return keys;
}
+ unsigned count_live_omap_extents() {
+ auto t = create_read_transaction();
+ unsigned count = 0;
+ with_trans_intr(*t, [this, &count](auto &t) {
+ return tm->get_lba_manager()->scan_mapped_space(
+ t,
+ [&count](paddr_t paddr, extent_len_t len, extent_types_t type, laddr_t laddr) {
+ if (type == extent_types_t::OMAP_INNER ||
+ type == extent_types_t::OMAP_LEAF) {
+ count++;
+ }
+ });
+ }).unsafe_get();
+ return count;
+ }
+
void list(
const omap_root_t &omap_root,
Transaction &t,
submit_transaction(std::move(t));
check_mappings(omap_root);
}
+ auto final_count = count_live_omap_extents();
+ logger().debug("leafnode_split_merge_balancing final live omap extents: {}",
+ final_count);
+ // After contracting back to depth 1, the tree consists of exactly the root leaf node.
+ EXPECT_EQ(final_count, 1U);
+
+ logger().debug("== clearing entire tree and verifying no leaks");
+ auto t_clear = create_mutate_transaction();
+ clear(omap_root, *t_clear);
+ submit_transaction(std::move(t_clear));
+ EXPECT_EQ(count_live_omap_extents(), 0U);
});
}
submit_transaction(std::move(t));
}
check_mappings(omap_root);
+ auto final_count = count_live_omap_extents();
+ logger().debug("innernode_split_merge_balancing final live omap extents: {}",
+ final_count);
+ // Bound derivation: 64 KiB OMAP_LEAF_BLOCK_SIZE / ~580 B entry size (50 B key + 512 B value
+ // + overhead) => healthy post-merge leaves hold >=55 entries, so count is <= size / 55 + C.
+ EXPECT_LE(final_count, test_omap_mappings.size() / 40 + 20U);
+
+ logger().debug("== clearing entire tree and verifying no leaks");
+ auto t_clear = create_mutate_transaction();
+ clear(omap_root, *t_clear);
+ submit_transaction(std::move(t_clear));
+ EXPECT_EQ(count_live_omap_extents(), 0U);
});
}
auto t = create_mutate_transaction();
clear(omap_root, *t);
submit_transaction(std::move(t));
+ EXPECT_EQ(count_live_omap_extents(), 0U);
});
}