aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp')
-rw-r--r--vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp71
1 files changed, 60 insertions, 11 deletions
diff --git a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
index ce1ebe395ce..7b46196780f 100644
--- a/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
+++ b/vespalib/src/tests/datastore/unique_store_dictionary/unique_store_dictionary_test.cpp
@@ -34,25 +34,37 @@ public:
return resolve(lhs).ref() == resolve(rhs).ref();
}
size_t hash(const EntryRef rhs) const override {
- return rhs.ref();
+ return rhs.valid() ? rhs.ref() : _to_find.ref();
}
};
template <typename UniqueStoreDictionaryType>
-struct DictionaryReadTest : public ::testing::Test {
+struct UniqueStoreDictionaryTest : public ::testing::Test {
UniqueStoreDictionaryType dict;
std::unique_ptr<IUniqueStoreDictionaryReadSnapshot> snapshot;
+ vespalib::GenerationHandler gen_handler;
- DictionaryReadTest()
+ UniqueStoreDictionaryTest()
: dict(std::make_unique<Comparator>(0)),
- snapshot()
+ snapshot(),
+ gen_handler()
{
}
- DictionaryReadTest& add(uint32_t value) {
+ UniqueStoreDictionaryTest& add(uint32_t value) {
auto result = dict.add(Comparator(value), [=]() noexcept { return EntryRef(value); });
assert(result.inserted());
return *this;
}
+ UniqueStoreDictionaryTest& remove(uint32_t value) {
+ dict.remove(Comparator(value), EntryRef(value));
+ return *this;
+ }
+ void inc_generation() {
+ dict.freeze();
+ dict.transfer_hold_lists(gen_handler.getCurrentGeneration());
+ gen_handler.incGeneration();
+ dict.trim_hold_lists(gen_handler.getFirstUsedGeneration());
+ }
void take_snapshot() {
dict.freeze();
snapshot = dict.get_read_snapshot();
@@ -61,8 +73,8 @@ struct DictionaryReadTest : public ::testing::Test {
}
};
-using DictionaryReadTestTypes = ::testing::Types<DefaultUniqueStoreDictionary, UniqueStoreDictionary<DefaultDictionary, IUniqueStoreDictionary, ShardedHashMap>, UniqueStoreDictionary<NoBTreeDictionary, IUniqueStoreDictionary, ShardedHashMap>>;
-VESPA_GTEST_TYPED_TEST_SUITE(DictionaryReadTest, DictionaryReadTestTypes);
+using UniqueStoreDictionaryTestTypes = ::testing::Types<DefaultUniqueStoreDictionary, UniqueStoreDictionary<DefaultDictionary, IUniqueStoreDictionary, ShardedHashMap>, UniqueStoreDictionary<NoBTreeDictionary, IUniqueStoreDictionary, ShardedHashMap>>;
+VESPA_GTEST_TYPED_TEST_SUITE(UniqueStoreDictionaryTest, UniqueStoreDictionaryTestTypes);
// Disable warnings emitted by gtest generated files when using typed tests
#pragma GCC diagnostic push
@@ -70,7 +82,7 @@ VESPA_GTEST_TYPED_TEST_SUITE(DictionaryReadTest, DictionaryReadTestTypes);
#pragma GCC diagnostic ignored "-Wsuggest-override"
#endif
-TYPED_TEST(DictionaryReadTest, can_count_occurrences_of_a_key)
+TYPED_TEST(UniqueStoreDictionaryTest, can_count_occurrences_of_a_key)
{
this->add(3).add(5).take_snapshot();
EXPECT_EQ(0, this->snapshot->count(Comparator(2)));
@@ -79,7 +91,7 @@ TYPED_TEST(DictionaryReadTest, can_count_occurrences_of_a_key)
EXPECT_EQ(1, this->snapshot->count(Comparator(5)));
}
-TYPED_TEST(DictionaryReadTest, can_count_occurrences_of_keys_in_a_range)
+TYPED_TEST(UniqueStoreDictionaryTest, can_count_occurrences_of_keys_in_a_range)
{
if (!this->dict.get_has_btree_dictionary()) {
return;
@@ -95,7 +107,7 @@ TYPED_TEST(DictionaryReadTest, can_count_occurrences_of_keys_in_a_range)
EXPECT_EQ(0, this->snapshot->count_in_range(Comparator(5), Comparator(3)));
}
-TYPED_TEST(DictionaryReadTest, can_iterate_all_keys)
+TYPED_TEST(UniqueStoreDictionaryTest, can_iterate_all_keys)
{
using EntryRefVector = std::vector<EntryRef>;
this->add(3).add(5).add(7).take_snapshot();
@@ -104,7 +116,7 @@ TYPED_TEST(DictionaryReadTest, can_iterate_all_keys)
EXPECT_EQ(EntryRefVector({EntryRef(3), EntryRef(5), EntryRef(7)}), refs);
}
-TYPED_TEST(DictionaryReadTest, memory_usage_is_reported)
+TYPED_TEST(UniqueStoreDictionaryTest, memory_usage_is_reported)
{
auto initial_usage = this->dict.get_memory_usage();
this->add(10);
@@ -114,6 +126,43 @@ TYPED_TEST(DictionaryReadTest, memory_usage_is_reported)
EXPECT_EQ(0, usage.allocatedBytesOnHold());
}
+TYPED_TEST(UniqueStoreDictionaryTest, compaction_works)
+{
+ for (uint32_t i = 1; i < 100; ++i) {
+ this->add(i);
+ }
+ for (uint32_t i = 10; i < 100; ++i) {
+ this->remove(i);
+ }
+ this->inc_generation();
+ auto btree_memory_usage_before = this->dict.get_btree_memory_usage();
+ auto hash_memory_usage_before = this->dict.get_hash_memory_usage();
+ for (uint32_t i = 0; i < 15; ++i) {
+ this->dict.compact_worst(true, true);
+ }
+ this->inc_generation();
+ auto btree_memory_usage_after = this->dict.get_btree_memory_usage();
+ auto hash_memory_usage_after = this->dict.get_hash_memory_usage();
+ if (this->dict.get_has_btree_dictionary()) {
+ EXPECT_LT(btree_memory_usage_after.deadBytes(), btree_memory_usage_before.deadBytes());
+ } else {
+ EXPECT_EQ(btree_memory_usage_after.deadBytes(), btree_memory_usage_before.deadBytes());
+ }
+ if (this->dict.get_has_hash_dictionary()) {
+ EXPECT_LT(hash_memory_usage_after.deadBytes(), hash_memory_usage_before.deadBytes());
+ } else {
+ EXPECT_EQ(hash_memory_usage_after.deadBytes(), hash_memory_usage_before.deadBytes());
+ }
+ std::vector<EntryRef> exp_refs;
+ for (uint32_t i = 1; i < 10; ++i) {
+ exp_refs.emplace_back(EntryRef(i));
+ }
+ this->take_snapshot();
+ std::vector<EntryRef> refs;
+ this->snapshot->foreach_key([&](EntryRef ref){ refs.emplace_back(ref); });
+ EXPECT_EQ(exp_refs, refs);
+}
+
#pragma GCC diagnostic pop
GTEST_MAIN_RUN_ALL_TESTS()