diff options
11 files changed, 83 insertions, 72 deletions
diff --git a/configdefinitions/src/vespa/attributes.def b/configdefinitions/src/vespa/attributes.def index be336c22cb6..4d15bfa92c2 100644 --- a/configdefinitions/src/vespa/attributes.def +++ b/configdefinitions/src/vespa/attributes.def @@ -4,7 +4,9 @@ namespace=vespa.config.search attribute[].name string attribute[].datatype enum { STRING, BOOL, UINT2, UINT4, INT8, INT16, INT32, INT64, FLOAT16, FLOAT, DOUBLE, PREDICATE, TENSOR, REFERENCE, NONE } default=NONE attribute[].collectiontype enum { SINGLE, ARRAY, WEIGHTEDSET } default=SINGLE +# Deprecated/ do-not-use, will sonn be GCed. attribute[].dictionary.ordering enum { ORDERED, UNORDERED } default = ORDERED +attribute[].dictionary.type enum { BTREE, HASH, BTREE_AND_HASH } default = BTREE attribute[].removeifzero bool default=false attribute[].createifnonexistent bool default=false attribute[].fastsearch bool default=false diff --git a/searchcommon/src/tests/attribute/config/attribute_config_test.cpp b/searchcommon/src/tests/attribute/config/attribute_config_test.cpp index 3dc1cf6d27e..98b2bfe5c90 100644 --- a/searchcommon/src/tests/attribute/config/attribute_config_test.cpp +++ b/searchcommon/src/tests/attribute/config/attribute_config_test.cpp @@ -110,22 +110,24 @@ TEST("Test GrowStrategy consistency") { } TEST("DictionaryConfig") { - using Ordering = DictionaryConfig::Ordering; - EXPECT_EQUAL(Ordering::ORDERED, DictionaryConfig().getOrdering()); - EXPECT_EQUAL(Ordering::ORDERED, DictionaryConfig(Ordering::ORDERED).getOrdering()); - EXPECT_EQUAL(Ordering::UNORDERED, DictionaryConfig(Ordering::UNORDERED).getOrdering()); - EXPECT_EQUAL(DictionaryConfig(Ordering::ORDERED), DictionaryConfig(Ordering::ORDERED)); - EXPECT_EQUAL(DictionaryConfig(Ordering::UNORDERED), DictionaryConfig(Ordering::UNORDERED)); - EXPECT_NOT_EQUAL(DictionaryConfig(Ordering::UNORDERED), DictionaryConfig(Ordering::ORDERED)); - EXPECT_NOT_EQUAL(DictionaryConfig(Ordering::ORDERED), DictionaryConfig(Ordering::UNORDERED)); - EXPECT_TRUE(Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED)) == - Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED))); - EXPECT_FALSE(Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED)) == - Config().set_dictionary_config(DictionaryConfig(Ordering::ORDERED))); - EXPECT_FALSE(Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED)) != - Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED))); - EXPECT_TRUE(Config().set_dictionary_config(DictionaryConfig(Ordering::UNORDERED)) != - Config().set_dictionary_config(DictionaryConfig(Ordering::ORDERED))); + using Type = DictionaryConfig::Type; + EXPECT_EQUAL(Type::BTREE, DictionaryConfig().getType()); + EXPECT_EQUAL(Type::BTREE, DictionaryConfig(Type::BTREE).getType()); + EXPECT_EQUAL(Type::HASH, DictionaryConfig(Type::HASH).getType()); + EXPECT_EQUAL(Type::BTREE_AND_HASH, DictionaryConfig(Type::BTREE_AND_HASH).getType()); + EXPECT_EQUAL(DictionaryConfig(Type::BTREE), DictionaryConfig(Type::BTREE)); + EXPECT_EQUAL(DictionaryConfig(Type::HASH), DictionaryConfig(Type::HASH)); + EXPECT_EQUAL(DictionaryConfig(Type::BTREE_AND_HASH), DictionaryConfig(Type::BTREE_AND_HASH)); + EXPECT_NOT_EQUAL(DictionaryConfig(Type::HASH), DictionaryConfig(Type::BTREE)); + EXPECT_NOT_EQUAL(DictionaryConfig(Type::BTREE), DictionaryConfig(Type::HASH)); + EXPECT_TRUE(Config().set_dictionary_config(DictionaryConfig(Type::HASH)) == + Config().set_dictionary_config(DictionaryConfig(Type::HASH))); + EXPECT_FALSE(Config().set_dictionary_config(DictionaryConfig(Type::HASH)) == + Config().set_dictionary_config(DictionaryConfig(Type::BTREE))); + EXPECT_FALSE(Config().set_dictionary_config(DictionaryConfig(Type::HASH)) != + Config().set_dictionary_config(DictionaryConfig(Type::HASH))); + EXPECT_TRUE(Config().set_dictionary_config(DictionaryConfig(Type::HASH)) != + Config().set_dictionary_config(DictionaryConfig(Type::BTREE))); } diff --git a/searchcommon/src/vespa/searchcommon/common/dictionary_config.cpp b/searchcommon/src/vespa/searchcommon/common/dictionary_config.cpp index 00b6ae2710f..a6a0255f96d 100644 --- a/searchcommon/src/vespa/searchcommon/common/dictionary_config.cpp +++ b/searchcommon/src/vespa/searchcommon/common/dictionary_config.cpp @@ -8,11 +8,13 @@ namespace search { std::ostream& operator<<(std::ostream& os, const DictionaryConfig & cfg) { - switch(cfg.getOrdering()) { - case DictionaryConfig::Ordering::ORDERED: - return os << "ORDERED"; - case DictionaryConfig::Ordering::UNORDERED: - return os << "UNORDERED"; + switch(cfg.getType()) { + case DictionaryConfig::Type::BTREE: + return os << "BTREE"; + case DictionaryConfig::Type::HASH: + return os << "HASH"; + case DictionaryConfig::Type::BTREE_AND_HASH: + return os << "BTREE_AND_HASH"; } assert(false); } diff --git a/searchcommon/src/vespa/searchcommon/common/dictionary_config.h b/searchcommon/src/vespa/searchcommon/common/dictionary_config.h index 06c88d88670..c35f7eaafef 100644 --- a/searchcommon/src/vespa/searchcommon/common/dictionary_config.h +++ b/searchcommon/src/vespa/searchcommon/common/dictionary_config.h @@ -11,13 +11,13 @@ namespace search { */ class DictionaryConfig { public: - enum class Ordering { ORDERED, UNORDERED }; - DictionaryConfig() noexcept : _ordering(Ordering::ORDERED) {} - DictionaryConfig(Ordering ordering) noexcept : _ordering(ordering) {} - Ordering getOrdering() const { return _ordering; } - bool operator == (const DictionaryConfig & b) const { return _ordering == b._ordering; } + enum class Type { BTREE, HASH, BTREE_AND_HASH }; + DictionaryConfig() noexcept : _type(Type::BTREE) {} + DictionaryConfig(Type ordering) noexcept : _type(ordering) {} + Type getType() const { return _type; } + bool operator == (const DictionaryConfig & b) const { return _type == b._type; } private: - Ordering _ordering; + Type _type; }; std::ostream& operator<<(std::ostream& os, const DictionaryConfig & cfg); diff --git a/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp b/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp index 3690533eef9..d999a6f37a2 100644 --- a/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp +++ b/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp @@ -27,7 +27,7 @@ using NodeAllocator = TreeType::NodeAllocatorType; TEST("requireThatNumericLessIsWorking") { - NumericEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + NumericEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert(10); EnumIndex e2 = es.insert(30); auto cmp1 = es.make_comparator(); @@ -41,7 +41,7 @@ TEST("requireThatNumericLessIsWorking") TEST("requireThatNumericEqualIsWorking") { - NumericEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + NumericEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert(10); EnumIndex e2 = es.insert(30); auto cmp1 = es.make_comparator(); @@ -56,7 +56,7 @@ TEST("requireThatNumericEqualIsWorking") TEST("requireThatFloatLessIsWorking") { - FloatEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + FloatEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert(10.5); EnumIndex e2 = es.insert(30.5); EnumIndex e3 = es.insert(std::numeric_limits<float>::quiet_NaN()); @@ -74,7 +74,7 @@ TEST("requireThatFloatLessIsWorking") TEST("requireThatFloatEqualIsWorking") { - FloatEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + FloatEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert(10.5); EnumIndex e2 = es.insert(30.5); EnumIndex e3 = es.insert(std::numeric_limits<float>::quiet_NaN()); @@ -93,7 +93,7 @@ TEST("requireThatFloatEqualIsWorking") TEST("requireThatStringLessIsWorking") { - StringEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert("Aa"); EnumIndex e2 = es.insert("aa"); EnumIndex e3 = es.insert("aB"); @@ -110,7 +110,7 @@ TEST("requireThatStringLessIsWorking") TEST("requireThatStringEqualIsWorking") { - StringEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert("Aa"); EnumIndex e2 = es.insert("aa"); EnumIndex e3 = es.insert("aB"); @@ -127,7 +127,7 @@ TEST("requireThatStringEqualIsWorking") TEST("requireThatComparatorWithTreeIsWorking") { - NumericEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + NumericEnumStore es(false, DictionaryConfig::Type::BTREE); vespalib::GenerationHandler g; TreeType t; NodeAllocator m; @@ -152,7 +152,7 @@ TEST("requireThatComparatorWithTreeIsWorking") TEST("requireThatFoldedLessIsWorking") { - StringEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert("Aa"); EnumIndex e2 = es.insert("aa"); EnumIndex e3 = es.insert("aB"); @@ -172,7 +172,7 @@ TEST("requireThatFoldedLessIsWorking") TEST("requireThatFoldedEqualIsWorking") { - StringEnumStore es(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore es(false, DictionaryConfig::Type::BTREE); EnumIndex e1 = es.insert("Aa"); EnumIndex e2 = es.insert("aa"); EnumIndex e3 = es.insert("aB"); diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp index 46f60ee00ee..b41fa389ab0 100644 --- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp +++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp @@ -6,7 +6,7 @@ #include <vespa/log/log.h> LOG_SETUP("enumstore_test"); -using Ordering = search::DictionaryConfig::Ordering; +using Type = search::DictionaryConfig::Type; using vespalib::datastore::EntryRef; namespace search { @@ -19,42 +19,42 @@ using StringEnumStore = EnumStoreT<const char*>; struct OrderedDoubleEnumStore { using EnumStoreType = DoubleEnumStore; - static constexpr Ordering ordering = Ordering::ORDERED; + static constexpr Type type = Type::BTREE; }; struct UnorderedDoubleEnumStore { using EnumStoreType = DoubleEnumStore; - static constexpr Ordering ordering = Ordering::UNORDERED; + static constexpr Type type = Type::BTREE_AND_HASH; }; struct OrderedFloatEnumStore { using EnumStoreType = FloatEnumStore; - static constexpr Ordering ordering = Ordering::ORDERED; + static constexpr Type type = Type::BTREE; }; struct UnorderedFloatEnumStore { using EnumStoreType = FloatEnumStore; - static constexpr Ordering ordering = Ordering::UNORDERED; + static constexpr Type type = Type::BTREE_AND_HASH; }; struct OrderedNumericEnumStore { using EnumStoreType = NumericEnumStore; - static constexpr Ordering ordering = Ordering::ORDERED; + static constexpr Type type = Type::BTREE; }; struct UnorderedNumericEnumStore { using EnumStoreType = NumericEnumStore; - static constexpr Ordering ordering = Ordering::UNORDERED; + static constexpr Type type = Type::BTREE_AND_HASH; }; struct OrderedStringEnumStore { using EnumStoreType = StringEnumStore; - static constexpr Ordering ordering = Ordering::ORDERED; + static constexpr Type type = Type::BTREE; }; struct UnorderedStringEnumStore { using EnumStoreType = StringEnumStore; - static constexpr Ordering ordering = Ordering::UNORDERED; + static constexpr Type type = Type::BTREE_AND_HASH; }; using StringVector = std::vector<std::string>; @@ -106,7 +106,7 @@ public: using EnumStoreType = typename EnumStoreTypeAndOrdering::EnumStoreType; EnumStoreType es; FloatEnumStoreTest() - : es(false, EnumStoreTypeAndOrdering::ordering) + : es(false, EnumStoreTypeAndOrdering::type) {} }; @@ -150,7 +150,7 @@ TYPED_TEST(FloatEnumStoreTest, numbers_can_be_inserted_and_retrieved) TEST(EnumStoreTest, test_find_folded_on_string_enum_store) { - StringEnumStore ses(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore ses(false, DictionaryConfig::Type::BTREE); std::vector<EnumIndex> indices; std::vector<std::string> unique({"", "one", "two", "TWO", "Two", "three"}); for (std::string &str : unique) { @@ -201,7 +201,7 @@ public: void StringEnumStoreTest::testInsert(bool hasPostings) { - StringEnumStore ses(hasPostings, DictionaryConfig::Ordering::ORDERED); + StringEnumStore ses(hasPostings, DictionaryConfig::Type::BTREE); std::vector<EnumIndex> indices; std::vector<std::string> unique; @@ -251,7 +251,7 @@ TEST_F(StringEnumStoreTest, test_insert_on_store_with_posting_lists) TEST(EnumStoreTest, test_hold_lists_and_generation) { - StringEnumStore ses(false, DictionaryConfig::Ordering::ORDERED); + StringEnumStore ses(false, DictionaryConfig::Type::BTREE); StringVector uniques; generation_t sesGen = 0u; uniques.reserve(100); @@ -328,7 +328,7 @@ dec_ref_count(NumericEnumStore& store, NumericEnumStore::Index idx) TEST(EnumStoreTest, address_space_usage_is_reported) { const size_t ADDRESS_LIMIT = 4290772994; // Max allocated elements in un-allocated buffers + allocated elements in allocated buffers. - NumericEnumStore store(false, DictionaryConfig::Ordering::ORDERED); + NumericEnumStore store(false, DictionaryConfig::Type::BTREE); using vespalib::AddressSpace; EXPECT_EQ(AddressSpace(1, 1, ADDRESS_LIMIT), store.get_address_space_usage()); @@ -350,7 +350,7 @@ public: EnumIndex i5; BatchUpdaterTest() - : store(false, DictionaryConfig::Ordering::ORDERED), + : store(false, DictionaryConfig::Type::BTREE), i3(), i5() { @@ -458,7 +458,7 @@ public: using Values = LoaderTestValues<EnumStoreType>; LoaderTest() - : store(true, EnumStoreTypeAndOrdering::ordering) + : store(true, EnumStoreTypeAndOrdering::type) {} void load_values(enumstore::EnumeratedLoaderBase& loader) const { @@ -570,7 +570,7 @@ public: EnumStoreType store; EnumStoreDictionaryTest() - : store(true, EnumStoreTypeAndOrdering::ordering) + : store(true, EnumStoreTypeAndOrdering::type) {} // Reuse test values from LoaderTest @@ -618,7 +618,7 @@ TYPED_TEST(EnumStoreDictionaryTest, find_frozen_index_works) this->update_posting_idx(value_0_idx, EntryRef(), this->fake_pidx()); auto& dict = this->store.get_dictionary(); EnumIndex idx; - if (TypeParam::ordering == Ordering::ORDERED) { + if (TypeParam::type == Type::BTREE) { 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)); @@ -640,7 +640,7 @@ TYPED_TEST(EnumStoreDictionaryTest, find_posting_list_works) 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) { + if (TypeParam::type == Type::BTREE) { EXPECT_FALSE(find_result.first.valid()); EXPECT_FALSE(find_result.second.valid()); } else { diff --git a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp index 145a021801d..2e946c7d34b 100644 --- a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp +++ b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp @@ -50,20 +50,22 @@ getCollectionTypeMap() static DataTypeMap _dataTypeMap = getDataTypeMap(); static CollectionTypeMap _collectionTypeMap = getCollectionTypeMap(); -DictionaryConfig::Ordering -convert(AttributesConfig::Attribute::Dictionary::Ordering ordering_cfg) { - switch (ordering_cfg) { - case AttributesConfig::Attribute::Dictionary::Ordering::ORDERED: - return DictionaryConfig::Ordering::ORDERED; - case AttributesConfig::Attribute::Dictionary::Ordering::UNORDERED: - return DictionaryConfig::Ordering::UNORDERED; +DictionaryConfig::Type +convert(AttributesConfig::Attribute::Dictionary::Type type_cfg) { + switch (type_cfg) { + case AttributesConfig::Attribute::Dictionary::Type::BTREE: + return DictionaryConfig::Type::BTREE; + case AttributesConfig::Attribute::Dictionary::Type::HASH: + return DictionaryConfig::Type::HASH; + case AttributesConfig::Attribute::Dictionary::Type::BTREE_AND_HASH: + return DictionaryConfig::Type::BTREE_AND_HASH; } assert(false); } DictionaryConfig convert_dictionary(const AttributesConfig::Attribute::Dictionary & dictionary) { - return DictionaryConfig(convert(dictionary.ordering)); + return DictionaryConfig(convert(dictionary.type)); } } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp index dc501dc9d89..fd523e227b0 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp +++ b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp @@ -13,7 +13,7 @@ EnumAttribute<B>:: EnumAttribute(const vespalib::string &baseFileName, const AttributeVector::Config &cfg) : B(baseFileName, cfg), - _enumStore(cfg.fastSearch(), cfg.get_dictionary_config().getOrdering()) + _enumStore(cfg.fastSearch(), cfg.get_dictionary_config().getType()) { this->setEnum(true); } diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp index 0961f7c87f1..5beafea0046 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp @@ -42,14 +42,15 @@ EnumStoreT<const char*>::load_unique_value(const void* src, } std::unique_ptr<vespalib::datastore::IUniqueStoreDictionary> -make_enum_store_dictionary(IEnumStore &store, bool has_postings, search::DictionaryConfig::Ordering ordering, std::unique_ptr<vespalib::datastore::EntryComparator> compare, std::unique_ptr<vespalib::datastore::EntryComparator> folded_compare) +make_enum_store_dictionary(IEnumStore &store, bool has_postings, search::DictionaryConfig::Type type, std::unique_ptr<vespalib::datastore::EntryComparator> compare, std::unique_ptr<vespalib::datastore::EntryComparator> folded_compare) { if (has_postings) { if (folded_compare) { return std::make_unique<EnumStoreFoldedDictionary>(store, std::move(compare), std::move(folded_compare)); } else { - switch (ordering) { - case search::DictionaryConfig::Ordering::UNORDERED: + switch (type) { + case search::DictionaryConfig::Type::HASH: + case search::DictionaryConfig::Type::BTREE_AND_HASH: return std::make_unique<EnumStoreDictionary<EnumPostingTree, vespalib::datastore::SimpleHashMap>>(store, std::move(compare)); default: return std::make_unique<EnumStoreDictionary<EnumPostingTree>>(store, std::move(compare)); diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.h b/searchlib/src/vespa/searchlib/attribute/enumstore.h index dc75ac1f38b..02b2ec019f6 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.h +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.h @@ -74,8 +74,8 @@ private: ssize_t load_unique_value(const void* src, size_t available, Index& idx); public: - EnumStoreT(bool has_postings, search::DictionaryConfig::Ordering ordering); - virtual ~EnumStoreT(); + EnumStoreT(bool has_postings, search::DictionaryConfig::Type type); + ~EnumStoreT() override; uint32_t get_ref_count(Index idx) const { return get_entry_base(idx).get_ref_count(); } void inc_ref_count(Index idx) { return get_entry_base(idx).inc_ref_count(); } @@ -213,7 +213,9 @@ public: }; std::unique_ptr<vespalib::datastore::IUniqueStoreDictionary> -make_enum_store_dictionary(IEnumStore &store, bool has_postings, search::DictionaryConfig::Ordering ordering, std::unique_ptr<vespalib::datastore::EntryComparator> compare, std::unique_ptr<vespalib::datastore::EntryComparator> folded_compare); +make_enum_store_dictionary(IEnumStore &store, bool has_postings, search::DictionaryConfig::Type type, + std::unique_ptr<vespalib::datastore::EntryComparator> compare, + std::unique_ptr<vespalib::datastore::EntryComparator> folded_compare); template <> diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp index 22f0d3e50dc..357026ab944 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp @@ -72,13 +72,13 @@ EnumStoreT<EntryT>::load_unique_value(const void* src, size_t available, Index& } template <typename EntryT> -EnumStoreT<EntryT>::EnumStoreT(bool has_postings, search::DictionaryConfig::Ordering ordering) +EnumStoreT<EntryT>::EnumStoreT(bool has_postings, search::DictionaryConfig::Type type) : _store(), _dict(), _cached_values_memory_usage(), _cached_values_address_space_usage(0, 0, (1ull << 32)) { - _store.set_dictionary(make_enum_store_dictionary(*this, has_postings, ordering, + _store.set_dictionary(make_enum_store_dictionary(*this, has_postings, type, std::make_unique<ComparatorType>(_store.get_data_store()), (has_string_type() ? std::make_unique<FoldedComparatorType>(_store.get_data_store()) : |