nvs: do eager cleanup of HashListBlocks

Previously when HashList was removing items, HashListBlocks were
removed lazily. This resulted in empty HashListBlocks dangling around
in full pages, even when all items have been erased. These blocks
would only be deleted when NVS was re-initialized
(nvs_flash_deinit/nvs_flash_init).

This change does eager cleanup instead, based on the code from
@negativekelvin offered in
https://github.com/espressif/esp-idf/issues/1642#issuecomment-367227994.

Closes https://github.com/espressif/esp-idf/issues/1642.
This commit is contained in:
Ivan Grokhotkov
2019-02-22 17:28:43 +08:00
committed by bot
parent 3240f7ff11
commit 02a76abb8b
2 changed files with 53 additions and 1 deletions
@@ -284,6 +284,47 @@ TEST_CASE("Page handles invalid CRC of variable length items", "[nvs][cur]")
}
}
class HashListTestHelper : public HashList
{
public:
size_t getBlockCount()
{
return mBlockList.size();
}
};
TEST_CASE("HashList is cleaned up as soon as items are erased", "[nvs]")
{
HashListTestHelper hashlist;
// Add items
const size_t count = 128;
for (size_t i = 0; i < count; ++i) {
char key[16];
snprintf(key, sizeof(key), "i%ld", (long int)i);
Item item(1, ItemType::U32, 1, key);
hashlist.insert(item, i);
}
INFO("Added " << count << " items, " << hashlist.getBlockCount() << " blocks");
// Remove them in reverse order
for (size_t i = count; i > 0; --i) {
hashlist.erase(i - 1, true);
}
CHECK(hashlist.getBlockCount() == 0);
// Add again
for (size_t i = 0; i < count; ++i) {
char key[16];
snprintf(key, sizeof(key), "i%ld", (long int)i);
Item item(1, ItemType::U32, 1, key);
hashlist.insert(item, i);
}
INFO("Added " << count << " items, " << hashlist.getBlockCount() << " blocks");
// Remove them in the same order
for (size_t i = 0; i < count; ++i) {
hashlist.erase(i, true);
}
CHECK(hashlist.getBlockCount() == 0);
}
TEST_CASE("can init PageManager in empty flash", "[nvs]")
{
SpiFlashEmulator emu(4);