{
for (auto it = mBlockList.begin(); it != mBlockList.end();) {
bool haveEntries = false;
+ bool foundIndex = false;
for (size_t i = 0; i < it->mCount; ++i) {
if (it->mNodes[i].mIndex == index) {
it->mNodes[i].mIndex = 0xff;
- return;
+ foundIndex = true;
+ /* found the item and removed it */
}
if (it->mNodes[i].mIndex != 0xff) {
haveEntries = true;
}
+ if (haveEntries && foundIndex) {
+ /* item was found, and HashListBlock still has some items */
+ return;
+ }
}
+ /* no items left in HashListBlock, can remove */
if (!haveEntries) {
auto tmp = it;
++it;
} else {
++it;
}
+ if (foundIndex) {
+ /* item was found and empty HashListBlock was removed */
+ return;
+ }
}
if (itemShouldExist) {
assert(false && "item should have been present in cache");
}
}
+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);