Each block of HeapBlockDevice is only allocated from the heap when
that block is programmed. And erasing a block frees the associated
buffer.
To decide if there is enough heap to run the TDBStore Whitebox tests,
we need to perform a trial program() instead of erase().
From the documentations of `BlockDevice::get_erase_value()`:
-1 if you can't rely on the value of the erased storage
and `BlockDevice::program()`:
The blocks must have been erased prior to being programmed
So, `BlockDevice::erase()` should always be called regardless of
erase value.
Currently `TDBStore::offset_in_erase_unit()` and
`TDBStore::check_erase_before_write()` loop through erase units
one-by-one, until the entire range is covered. This is very inefficient
when the erase size is tiny, e.g. one-byte on a non-flash device for
which we use program as erase.
This commit reworks the algorithms, based on the fact that a block
device can erase or program as many units as needed in one go.