aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/tests/btree/btree_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vespalib/src/tests/btree/btree_test.cpp')
-rw-r--r--vespalib/src/tests/btree/btree_test.cpp61
1 files changed, 60 insertions, 1 deletions
diff --git a/vespalib/src/tests/btree/btree_test.cpp b/vespalib/src/tests/btree/btree_test.cpp
index e1a9fa98a21..82fa4b6b50a 100644
--- a/vespalib/src/tests/btree/btree_test.cpp
+++ b/vespalib/src/tests/btree/btree_test.cpp
@@ -1549,6 +1549,38 @@ inc_generation(GenerationHandler &g, Tree &t)
s.trimHoldLists(g.getFirstUsedGeneration());
}
+template <typename Tree>
+void
+make_iterators(Tree& t, std::vector<int>& list, std::vector<typename Tree::ConstIterator>& iterators)
+{
+ for (auto key : list) {
+ iterators.emplace_back(t.lowerBound(key));
+ }
+ iterators.emplace_back(t.lowerBound(300));
+}
+
+class KeyRangeValidator
+{
+ std::vector<int> &_list;
+ size_t _start_pos;
+ size_t _end_pos;
+ size_t _curr_pos;
+public:
+ KeyRangeValidator(std::vector<int> &list, size_t start_pos, size_t end_pos)
+ : _list(list),
+ _start_pos(start_pos),
+ _end_pos(end_pos),
+ _curr_pos(start_pos)
+ {
+ }
+ void operator()(int key) {
+ assert(_curr_pos < _list.size());
+ EXPECT_EQ(key, _list[_curr_pos]);
+ ++_curr_pos;
+ }
+ size_t curr_pos() const noexcept { return _curr_pos; }
+};
+
}
TEST_F(BTreeTest, require_that_compaction_works)
@@ -1557,7 +1589,9 @@ TEST_F(BTreeTest, require_that_compaction_works)
GenerationHandler g;
Tree t;
std::vector<int> before_list;
+ std::vector<typename Tree::ConstIterator> before_iterators;
std::vector<int> after_list;
+ std::vector<typename Tree::ConstIterator> after_iterators;
for (uint32_t i = 1; i < 256; ++i) {
t.insert(i, 101);
}
@@ -1565,14 +1599,39 @@ TEST_F(BTreeTest, require_that_compaction_works)
t.remove(i);
}
inc_generation(g, t);
+ auto guard = g.takeGuard();
auto memory_usage_before = t.getAllocator().getMemoryUsage();
t.foreach_key([&before_list](int key) { before_list.emplace_back(key); });
- t.compact_worst();
+ make_iterators(t, before_list, before_iterators);
+ for (int i = 0; i < 15; ++i) {
+ t.compact_worst();
+ }
inc_generation(g, t);
auto memory_usage_after = t.getAllocator().getMemoryUsage();
t.foreach_key([&after_list](int key) { after_list.emplace_back(key); });
+ make_iterators(t, after_list, after_iterators);
EXPECT_LT(memory_usage_after.deadBytes(), memory_usage_before.deadBytes());
EXPECT_EQ(before_list, after_list);
+ EXPECT_EQ(before_iterators.size(), after_iterators.size());
+ for (size_t i = 0; i < before_iterators.size(); ++i) {
+ for (size_t j = 0; j < after_iterators.size(); ++j) {
+ EXPECT_EQ(before_iterators[i] == after_iterators[j], i == j);
+ EXPECT_EQ(before_iterators[i] - after_iterators[j], static_cast<ssize_t>(i - j));
+ EXPECT_EQ(after_iterators[j] - before_iterators[i], static_cast<ssize_t>(j - i));
+ if (i <= j) {
+ KeyRangeValidator validate_keys(before_list, i, j);
+ EXPECT_EQ(i, validate_keys.curr_pos());
+ before_iterators[i].foreach_key_range(after_iterators[j], [&validate_keys](int key) { validate_keys(key); });
+ EXPECT_EQ(j, validate_keys.curr_pos());
+ }
+ if (j <= i) {
+ KeyRangeValidator validate_keys(before_list, j, i);
+ EXPECT_EQ(j, validate_keys.curr_pos());
+ after_iterators[j].foreach_key_range(before_iterators[i], [&validate_keys](int key) { validate_keys(key); });
+ EXPECT_EQ(i, validate_keys.curr_pos());
+ }
+ }
+ }
}
}