aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2021-03-19 18:41:08 +0100
committerTor Egge <Tor.Egge@broadpark.no>2021-03-19 19:06:04 +0100
commit6ecf7b70b5ac13e83a2e1231145faeaa696da18c (patch)
treec04d049c4d5103897d8c1c07993542e18ddd3af1
parent1ff6fa617f45cef77e97ba76750c476de48271c1 (diff)
Extend EnumStore unit test to test find_frozen_index and find_posting_list
member functions in EnumStoreDirectory.
-rw-r--r--searchlib/src/tests/attribute/enumstore/enumstore_test.cpp100
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp6
2 files changed, 106 insertions, 0 deletions
diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
index 85c12acb57d..b972c8690ee 100644
--- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
+++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
@@ -7,6 +7,7 @@
LOG_SETUP("enumstore_test");
using Ordering = search::DictionaryConfig::Ordering;
+using vespalib::datastore::EntryRef;
namespace search {
@@ -556,6 +557,105 @@ TYPED_TEST(LoaderTest, store_is_instantiated_with_non_enumerated_loader)
#pragma GCC diagnostic pop
+template <typename EnumStoreTypeAndOrdering>
+class EnumStoreDictionaryTest : public ::testing::Test {
+public:
+ using EnumStoreType = typename EnumStoreTypeAndOrdering::EnumStoreType;
+ using EntryType = typename EnumStoreType::EntryType;
+ EnumStoreType store;
+
+ EnumStoreDictionaryTest()
+ : store(true, EnumStoreTypeAndOrdering::ordering)
+ {}
+
+ // Reuse test values from LoaderTest
+ const std::vector<EntryType>& values() const noexcept { return LoaderTestValues<EnumStoreType>::values; }
+
+ typename EnumStoreType::ComparatorType make_bound_comparator(int value_idx) { return store.make_comparator(values()[value_idx]); }
+
+ void update_posting_idx(EnumIndex enum_idx, EntryRef old_posting_idx, EntryRef new_posting_idx);
+ EnumIndex insert_value(size_t value_idx);
+ static EntryRef fake_pidx() { return EntryRef(42); }
+};
+
+template <typename EnumStoreTypeAndOrdering>
+void
+EnumStoreDictionaryTest<EnumStoreTypeAndOrdering>::update_posting_idx(EnumIndex enum_idx, EntryRef old_posting_idx, EntryRef new_posting_idx)
+{
+ auto& dict = store.get_dictionary();
+ EntryRef old_posting_idx_check;
+ dict.update_posting_list(enum_idx, store.make_comparator(), [&old_posting_idx_check, new_posting_idx](EntryRef posting_idx) noexcept -> EntryRef { old_posting_idx_check = posting_idx; return new_posting_idx; });
+ EXPECT_EQ(old_posting_idx, old_posting_idx_check);
+}
+
+template <typename EnumStoreTypeAndOrdering>
+EnumIndex
+EnumStoreDictionaryTest<EnumStoreTypeAndOrdering>::insert_value(size_t value_idx)
+{
+ assert(value_idx < values().size());
+ auto enum_idx = store.insert(values()[value_idx]);
+ EXPECT_TRUE(enum_idx.valid());
+ return enum_idx;
+}
+
+// Disable warnings emitted by gtest generated files when using typed tests
+#pragma GCC diagnostic push
+#ifndef __clang__
+#pragma GCC diagnostic ignored "-Wsuggest-override"
+#endif
+
+using EnumStoreDictionaryTestTypes = ::testing::Types<OrderedNumericEnumStore, UnorderedNumericEnumStore>;
+VESPA_GTEST_TYPED_TEST_SUITE(EnumStoreDictionaryTest, EnumStoreDictionaryTestTypes);
+
+TYPED_TEST(EnumStoreDictionaryTest, find_frozen_index_works)
+{
+ auto value_0_idx = this->insert_value(0);
+ this->update_posting_idx(value_0_idx, EntryRef(), this->fake_pidx());
+ auto& dict = this->store.get_dictionary();
+ EnumIndex idx;
+ if (TypeParam::ordering == Ordering::ORDERED) {
+ EXPECT_FALSE(dict.find_frozen_index(this->make_bound_comparator(0), idx));
+ } else {
+ EXPECT_TRUE(dict.find_frozen_index(this->make_bound_comparator(0), idx));
+ EXPECT_EQ(value_0_idx, idx);
+ }
+ EXPECT_FALSE(dict.find_frozen_index(this->make_bound_comparator(1), idx));
+ this->store.freeze_dictionary();
+ idx = EnumIndex();
+ EXPECT_TRUE(dict.find_frozen_index(this->make_bound_comparator(0), idx));
+ EXPECT_EQ(value_0_idx, idx);
+ EXPECT_FALSE(dict.find_frozen_index(this->make_bound_comparator(1), idx));
+ this->update_posting_idx(value_0_idx, this->fake_pidx(), EntryRef());
+}
+
+TYPED_TEST(EnumStoreDictionaryTest, find_posting_list_works)
+{
+ auto value_0_idx = this->insert_value(0);
+ this->update_posting_idx(value_0_idx, EntryRef(), this->fake_pidx());
+ auto& dict = this->store.get_dictionary();
+ auto root = dict.get_frozen_root();
+ auto find_result = dict.find_posting_list(this->make_bound_comparator(0), root);
+ if (TypeParam::ordering == Ordering::ORDERED) {
+ EXPECT_FALSE(find_result.first.valid());
+ EXPECT_FALSE(find_result.second.valid());
+ } else {
+ EXPECT_EQ(value_0_idx, find_result.first);
+ EXPECT_EQ(this->fake_pidx(), find_result.second);
+ }
+ find_result = dict.find_posting_list(this->make_bound_comparator(1), root);
+ EXPECT_FALSE(find_result.first.valid());
+ this->store.freeze_dictionary();
+ root = dict.get_frozen_root();
+ find_result = dict.find_posting_list(this->make_bound_comparator(0), root);
+ EXPECT_EQ(value_0_idx, find_result.first);
+ EXPECT_EQ(this->fake_pidx(), find_result.second);
+ find_result = dict.find_posting_list(this->make_bound_comparator(1), root);
+ EXPECT_FALSE(find_result.first.valid());
+ this->update_posting_idx(value_0_idx, this->fake_pidx(), EntryRef());
+}
+
+#pragma GCC diagnostic pop
+
}
GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp
index 1676020b417..6cf4e4fc262 100644
--- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp
@@ -234,6 +234,12 @@ EnumStoreDictionary<DictionaryT, UnorderedDictionaryT>::update_posting_list(Inde
EntryRef new_posting_idx = updater(old_posting_idx);
dict.thaw(itr);
itr.writeData(new_posting_idx.ref());
+ if constexpr (has_unordered_dictionary) {
+ auto find_result = this->_unordered_dict.find(this->_unordered_dict.get_default_comparator(), idx);
+ assert(find_result != nullptr && find_result->first.load_relaxed() == idx);
+ assert(find_result->second.load_relaxed() == old_posting_idx);
+ find_result->second.store_release(new_posting_idx);
+ }
}
template <typename DictionaryT, typename UnorderedDictionaryT>