diff options
19 files changed, 106 insertions, 148 deletions
diff --git a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp index edb97e12cdc..31bf982ad70 100644 --- a/searchcore/src/tests/proton/attribute/attributeflush_test.cpp +++ b/searchcore/src/tests/proton/attribute/attributeflush_test.cpp @@ -636,7 +636,7 @@ Test::requireThatFlushFailurePreventsSyncTokenUpdate() EXPECT_EQUAL(0u, flush_target->getFlushedSerialNum()); auto flush_task = flush_target->initFlush(200); // Trigger flush failure - av->getEnumStoreBase()->get_data_store_base().inc_compaction_count(); + av->getEnumStoreBase()->inc_compaction_count(); flush_task->run(); EXPECT_EQUAL(0u, flush_target->getFlushedSerialNum()); } 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 34f8833f9be..97b08c5683f 100644 --- a/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp +++ b/searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp @@ -43,9 +43,8 @@ void Test::requireThatNumericComparatorIsWorking() { NumericEnumStore es(false); - EnumIndex e1, e2; - es.addEnum(10, e1); - es.addEnum(30, e2); + EnumIndex e1 = es.insert(10); + EnumIndex e2 = es.insert(30); auto cmp1 = es.make_comparator(); EXPECT_TRUE(cmp1(e1, e2)); EXPECT_TRUE(!cmp1(e2, e1)); @@ -59,10 +58,9 @@ void Test::requireThatFloatComparatorIsWorking() { FloatEnumStore es(false); - EnumIndex e1, e2, e3; - es.addEnum(10.5, e1); - es.addEnum(30.5, e2); - es.addEnum(std::numeric_limits<float>::quiet_NaN(), e3); + EnumIndex e1 = es.insert(10.5); + EnumIndex e2 = es.insert(30.5); + EnumIndex e3 = es.insert(std::numeric_limits<float>::quiet_NaN()); auto cmp1 = es.make_comparator(); EXPECT_TRUE(cmp1(e1, e2)); EXPECT_TRUE(!cmp1(e2, e1)); @@ -79,10 +77,9 @@ void Test::requireThatStringComparatorIsWorking() { StringEnumStore es(false); - EnumIndex e1, e2, e3; - es.addEnum("Aa", e1); - es.addEnum("aa", e2); - es.addEnum("aB", e3); + EnumIndex e1 = es.insert("Aa"); + EnumIndex e2 = es.insert("aa"); + EnumIndex e3 = es.insert("aB"); auto cmp1 = es.make_comparator(); EXPECT_TRUE(cmp1(e1, e2)); // similar folded, fallback to regular EXPECT_TRUE(!cmp1(e2, e1)); @@ -101,12 +98,11 @@ Test::requireThatComparatorWithTreeIsWorking() vespalib::GenerationHandler g; TreeType t; NodeAllocator m; - EnumIndex ei; for (int32_t v = 100; v > 0; --v) { auto cmp = es.make_comparator(v); EXPECT_TRUE(!t.find(EnumIndex(), m, cmp).valid()); - es.addEnum(v, ei); - t.insert(ei, BTreeNoLeafData(), m, cmp); + EnumIndex idx = es.insert(v); + t.insert(idx, BTreeNoLeafData(), m, cmp); } EXPECT_EQUAL(100u, t.size(m)); int32_t exp = 1; @@ -125,11 +121,10 @@ void Test::requireThatFoldedComparatorIsWorking() { StringEnumStore es(false); - EnumIndex e1, e2, e3, e4; - es.addEnum("Aa", e1); - es.addEnum("aa", e2); - es.addEnum("aB", e3); - es.addEnum("Folded", e4); + EnumIndex e1 = es.insert("Aa"); + EnumIndex e2 = es.insert("aa"); + EnumIndex e3 = es.insert("aB"); + EnumIndex e4 = es.insert("Folded"); auto cmp1 = es.make_folded_comparator(); EXPECT_TRUE(!cmp1(e1, e2)); // similar folded EXPECT_TRUE(!cmp1(e2, e1)); // similar folded diff --git a/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp b/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp index e8e55acf117..09cd186811d 100644 --- a/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp +++ b/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp @@ -513,7 +513,7 @@ EnumeratedSaveTest::saveMemDuringCompaction(AttributeVector &v) if (enum_store_base != nullptr) { auto saver = v.onInitSave(v.getBaseFileName()); // Simulate compaction - enum_store_base->get_data_store_base().inc_compaction_count(); + enum_store_base->inc_compaction_count(); auto save_result = saver->save(*res); EXPECT_EQUAL(!v.hasMultiValue(), save_result); } diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp index ca40b5cc259..c6acf465f83 100644 --- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp +++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp @@ -32,9 +32,9 @@ private: void testFloatEnumStore(); void testFindFolded(); - void testAddEnum(); + void testInsert(); template <typename EnumStoreType> - void testAddEnum(bool hasPostings); + void testInsert(bool hasPostings); template <typename EnumStoreType, typename Dictionary> void @@ -91,7 +91,7 @@ EnumStoreTest::testFloatEnumStore(EnumStoreType & es) T b[5] = {-25.5f, -15.5f, -5.5f, 4.5f, 14.5f}; for (uint32_t i = 0; i < 5; ++i) { - es.addEnum(a[i], idx); + es.insert(a[i]); } for (uint32_t i = 0; i < 5; ++i) { @@ -99,7 +99,7 @@ EnumStoreTest::testFloatEnumStore(EnumStoreType & es) EXPECT_TRUE(!es.findIndex(b[i], idx)); } - es.addEnum(std::numeric_limits<T>::quiet_NaN(), idx); + es.insert(std::numeric_limits<T>::quiet_NaN()); EXPECT_TRUE(es.findIndex(std::numeric_limits<T>::quiet_NaN(), idx)); EXPECT_TRUE(es.findIndex(std::numeric_limits<T>::quiet_NaN(), idx)); @@ -129,10 +129,8 @@ EnumStoreTest::testFindFolded() std::vector<EnumIndex> indices; std::vector<std::string> unique({"", "one", "two", "TWO", "Two", "three"}); for (std::string &str : unique) { - EnumIndex idx; - ses.addEnum(str.c_str(), idx); + EnumIndex idx = ses.insert(str.c_str()); indices.push_back(idx); - ses.incRefCount(idx); EXPECT_EQUAL(1u, ses.getRefCount(idx)); } ses.freezeTree(); @@ -154,21 +152,19 @@ EnumStoreTest::testFindFolded() } void -EnumStoreTest::testAddEnum() +EnumStoreTest::testInsert() { - testAddEnum<StringEnumStore>(false); + testInsert<StringEnumStore>(false); - testAddEnum<StringEnumStore>(true); + testInsert<StringEnumStore>(true); } template <typename EnumStoreType> void -EnumStoreTest::testAddEnum(bool hasPostings) +EnumStoreTest::testInsert(bool hasPostings) { - // TODO: Rewrite test to use BatchUpdater EnumStoreType ses(hasPostings); - EnumIndex idx; std::vector<EnumIndex> indices; std::vector<std::string> unique; unique.push_back(""); @@ -177,8 +173,7 @@ EnumStoreTest::testAddEnum(bool hasPostings) unique.push_back("unique"); for (uint32_t i = 0; i < unique.size(); ++i) { - ses.addEnum(unique[i].c_str(), idx); - ses.incRefCount(idx); + EnumIndex idx = ses.insert(unique[i].c_str()); EXPECT_EQUAL(1u, ses.getRefCount(idx)); indices.push_back(idx); EXPECT_TRUE(ses.findIndex(unique[i].c_str(), idx)); @@ -190,6 +185,7 @@ EnumStoreTest::testAddEnum(bool hasPostings) EXPECT_TRUE(ses.findEnum(unique[i].c_str(), e)); EXPECT_EQUAL(1u, ses.findFoldedEnums(unique[i].c_str()).size()); EXPECT_EQUAL(e, ses.findFoldedEnums(unique[i].c_str())[0]); + EnumIndex idx; EXPECT_TRUE(ses.findIndex(unique[i].c_str(), idx)); EXPECT_TRUE(idx == indices[i]); EXPECT_EQUAL(1u, ses.getRefCount(indices[i])); @@ -226,9 +222,7 @@ EnumStoreTest::testUniques void EnumStoreTest::testHoldListAndGeneration() { - // TODO: Rewrite test to use BatchUpdater StringEnumStore ses(false); - StringEnumStore::Index idx; StringVector uniques; generation_t sesGen = 0u; uniques.reserve(100); @@ -249,8 +243,7 @@ EnumStoreTest::testHoldListAndGeneration() // insert first batch of unique strings for (uint32_t i = 0; i < 100; ++i) { - ses.addEnum(uniques[i].c_str(), idx); - ses.incRefCount(idx); + EnumIndex idx = ses.insert(uniques[i].c_str()); EXPECT_TRUE(ses.getRefCount(idx)); // associate readers @@ -275,12 +268,14 @@ EnumStoreTest::testHoldListAndGeneration() } // remove all uniques + auto updater = ses.make_batch_updater(); for (uint32_t i = 0; i < 100; ++i) { + EnumIndex idx; EXPECT_TRUE(ses.findIndex(uniques[i].c_str(), idx)); - ses.decRefCount(idx); + updater.dec_ref_count(idx); EXPECT_EQUAL(0u, ses.getRefCount(idx)); } - ses.freeUnusedEnums(); + updater.commit(); // check readers again checkReaders(ses, sesGen, readers); @@ -291,20 +286,13 @@ EnumStoreTest::testHoldListAndGeneration() namespace { -NumericEnumStore::Index -addEnum(NumericEnumStore &store, uint32_t value) -{ - NumericEnumStore::Index result; - store.addEnum(value, result); - store.incRefCount(result); - return result; -} - void -decRefCount(NumericEnumStore& store, NumericEnumStore::Index idx) +dec_ref_count(NumericEnumStore& store, NumericEnumStore::Index idx) { - store.decRefCount(idx); - store.freeUnusedEnums(); + auto updater = store.make_batch_updater(); + updater.dec_ref_count(idx); + updater.commit(); + generation_t gen = 5; store.transferHoldLists(gen); store.trimHoldLists(gen + 1); @@ -315,20 +303,19 @@ decRefCount(NumericEnumStore& store, NumericEnumStore::Index idx) void EnumStoreTest::requireThatAddressSpaceUsageIsReported() { - // TODO: Rewrite test to use BatchUpdater const size_t ADDRESS_LIMIT = 4290772994; // Max allocated elements in un-allocated buffers + allocated elements in allocated buffers. NumericEnumStore store(false); using vespalib::AddressSpace; EXPECT_EQUAL(AddressSpace(1, 1, ADDRESS_LIMIT), store.getAddressSpaceUsage()); - NumericEnumStore::Index idx1 = addEnum(store, 10); + EnumIndex idx1 = store.insert(10); EXPECT_EQUAL(AddressSpace(2, 1, ADDRESS_LIMIT), store.getAddressSpaceUsage()); - NumericEnumStore::Index idx2 = addEnum(store, 20); + EnumIndex idx2 = store.insert(20); // Address limit increases because buffer is re-sized. EXPECT_EQUAL(AddressSpace(3, 1, ADDRESS_LIMIT + 2), store.getAddressSpaceUsage()); - decRefCount(store, idx1); + dec_ref_count(store, idx1); EXPECT_EQUAL(AddressSpace(3, 2, ADDRESS_LIMIT + 2), store.getAddressSpaceUsage()); - decRefCount(store, idx2); + dec_ref_count(store, idx2); EXPECT_EQUAL(AddressSpace(3, 3, ADDRESS_LIMIT + 2), store.getAddressSpaceUsage()); } @@ -357,7 +344,7 @@ EnumStoreTest::Main() testFloatEnumStore(); testFindFolded(); - testAddEnum(); + testInsert(); testHoldListAndGeneration(); TEST_DO(requireThatAddressSpaceUsageIsReported()); diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp index d45d6fa8c7c..dd58909ac7b 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp @@ -41,28 +41,6 @@ EnumStoreDictionary<DictionaryT>::getNumUniques() const template <typename DictionaryT> void -EnumStoreDictionary<DictionaryT>::writeAllValues(BufferWriter& writer, - BTreeNode::Ref rootRef) const -{ - constexpr size_t BATCHSIZE = 1000; - std::vector<Index> idxs; - idxs.reserve(BATCHSIZE); - typename DictionaryT::Iterator it(rootRef, this->_dict.getAllocator()); - while (it.valid()) { - if (idxs.size() >= idxs.capacity()) { - _enumStore.writeValues(writer, vespalib::ConstArrayRef(&idxs[0], idxs.size())); - idxs.clear(); - } - idxs.push_back(it.getKey()); - ++it; - } - if (!idxs.empty()) { - _enumStore.writeValues(writer, vespalib::ConstArrayRef(&idxs[0], idxs.size())); - } -} - -template <typename DictionaryT> -void EnumStoreDictionary<DictionaryT>::fixupRefCounts(const EnumVector& hist) { _enumStore.fixupRefCounts(hist, this->_dict); diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h index 6367a06e339..291b92fd0f7 100644 --- a/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h @@ -33,7 +33,6 @@ public: DictionaryT &getDictionary() { return this->_dict; } uint32_t getNumUniques() const override; - void writeAllValues(BufferWriter& writer, btree::BTreeNode::Ref rootRef) const override; void fixupRefCounts(const EnumVector& hist) override; void removeUnusedEnums(const IndexSet& unused, @@ -50,7 +49,6 @@ public: findMatchingEnums(const datastore::EntryComparator& cmp) const override; void onReset() override; - btree::BTreeNode::Ref getFrozenRootRef() const override { return this->get_frozen_root(); } EnumPostingTree & getPostingDictionary() override; const EnumPostingTree & getPostingDictionary() const override; diff --git a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp index 449f89f0386..cf394623abd 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp @@ -11,7 +11,7 @@ namespace search { EnumAttributeSaver:: EnumAttributeSaver(const IEnumStore &enumStore) : _enumStore(enumStore), - _enumerator(_enumStore.getEnumStoreDict(), _enumStore.get_data_store_base()) + _enumerator(enumStore.make_enumerator()) { } @@ -23,10 +23,10 @@ void EnumAttributeSaver::writeUdat(IAttributeSaveTarget &saveTarget) { if (saveTarget.getEnumerated()) { - std::unique_ptr<BufferWriter> - udatWriter(saveTarget.udatWriter().allocBufferWriter()); - const auto& enumDict = _enumStore.getEnumStoreDict(); - enumDict.writeAllValues(*udatWriter, _enumerator.get_frozen_root()); + auto udatWriter = saveTarget.udatWriter().allocBufferWriter(); + _enumerator->foreach_key([&](datastore::EntryRef idx){ + _enumStore.write_value(*udatWriter, idx); + }); udatWriter->flush(); } } diff --git a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h index 6c52a7a4e2d..f7bb263d4cb 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h +++ b/searchlib/src/vespa/searchlib/attribute/enumattributesaver.h @@ -17,11 +17,11 @@ class IAttributeSaveTarget; class EnumAttributeSaver { public: - using Enumerator = datastore::UniqueStoreEnumerator<IEnumStore::InternalIndex>; + using Enumerator = IEnumStore::Enumerator; private: const IEnumStore &_enumStore; - Enumerator _enumerator; + std::unique_ptr<Enumerator> _enumerator; public: EnumAttributeSaver(const IEnumStore &enumStore); @@ -29,8 +29,8 @@ public: void writeUdat(IAttributeSaveTarget &saveTarget); const IEnumStore &getEnumStore() const { return _enumStore; } - Enumerator &get_enumerator() { return _enumerator; } - void clear() { _enumerator.clear(); } + Enumerator &get_enumerator() { return *_enumerator; } + void clear() { _enumerator->clear(); } }; } // namespace search diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp index 188a381682f..f47d81a15a4 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.cpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.cpp @@ -11,14 +11,11 @@ namespace search { template <> void -EnumStoreT<const char*>::writeValues(BufferWriter& writer, - vespalib::ConstArrayRef<Index> idxs) const +EnumStoreT<const char*>::write_value(BufferWriter& writer, Index idx) const { - for (const auto& idx : idxs) { - const char* src = _store.get(idx); - size_t sz = strlen(src) + 1; - writer.write(src, sz); - } + const char* src = _store.get(idx); + size_t sz = strlen(src) + 1; + writer.write(src, sz); } template <> diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.h b/searchlib/src/vespa/searchlib/attribute/enumstore.h index c9784678340..399956db2fc 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.h +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.h @@ -77,9 +77,7 @@ public: virtual ~EnumStoreT(); uint32_t getRefCount(Index idx) const { return get_entry_base(idx).get_ref_count(); } - // TODO: Remove from public API void incRefCount(Index idx) { return get_entry_base(idx).inc_ref_count(); } - void decRefCount(Index idx) { return get_entry_base(idx).dec_ref_count(); } // Only use when reading from enumerated attribute save files // TODO: Instead create an API that is used for loading/initializing. @@ -110,10 +108,6 @@ public: return _dict->getPostingDictionary(); } - // TODO: Add API for getting compaction count instead. - const datastore::DataStoreBase &get_data_store_base() const override { return _store.get_allocator().get_data_store(); } - - bool getValue(Index idx, EntryType& value) const; EntryType getValue(uint32_t idx) const { return getValue(Index(EntryRef(idx))); } EntryType getValue(Index idx) const { return _store.get(idx); } @@ -166,11 +160,7 @@ public: : _store(store), _possibly_unused() {} - void insert(EntryType value) { - Index idx; - _store.addEnum(value, idx); - _possibly_unused.insert(idx); - } + void insert(EntryType value); void inc_ref_count(Index idx) { _store.get_entry_base(idx).inc_ref_count(); } @@ -206,18 +196,24 @@ public: return FoldedComparatorType(_store.get_data_store(), fallback_value, prefix); } - // TODO: Change to sending enum indexes as const array ref. - void writeValues(BufferWriter& writer, vespalib::ConstArrayRef<Index> idxs) const override; + void write_value(BufferWriter& writer, Index idx) const override; bool foldedChange(const Index &idx1, const Index &idx2) const override; bool findEnum(EntryType value, IEnumStore::EnumHandle &e) const; std::vector<IEnumStore::EnumHandle> findFoldedEnums(EntryType value) const; - void addEnum(EntryType value, Index &newIdx); + Index insert(EntryType value); bool findIndex(EntryType value, Index &idx) const; void freeUnusedEnums() override; void freeUnusedEnums(const IndexSet& toRemove); vespalib::MemoryUsage update_stat() override; std::unique_ptr<EnumIndexRemapper> consider_compact(const CompactionStrategy& compaction_strategy) override; std::unique_ptr<EnumIndexRemapper> compact_worst(bool compact_memory, bool compact_address_space) override; + uint64_t get_compaction_count() const override { + return _store.get_data_store().get_compaction_count(); + } + void inc_compaction_count() override { + _store.get_allocator().get_data_store().inc_compaction_count(); + } + std::unique_ptr<Enumerator> make_enumerator() const override; }; std::unique_ptr<datastore::IUniqueStoreDictionary> @@ -230,8 +226,7 @@ class datastore::DataStoreT<IEnumStore::Index>; template <> void -EnumStoreT<const char*>::writeValues(BufferWriter& writer, - vespalib::ConstArrayRef<IEnumStore::Index> idxs) const; +EnumStoreT<const char*>::write_value(BufferWriter& writer, Index idx) const; template <> ssize_t diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp index 8c230457c0e..e2d07e6424d 100644 --- a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp +++ b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp @@ -135,16 +135,25 @@ EnumStoreT<EntryType>::getValue(Index idx, EntryType& value) const template <typename EntryType> EnumStoreT<EntryType>::NonEnumeratedLoader::~NonEnumeratedLoader() = default; -template <class EntryType> +template <typename EntryType> void -EnumStoreT<EntryType>::writeValues(BufferWriter& writer, vespalib::ConstArrayRef<Index> idxs) const +EnumStoreT<EntryType>::BatchUpdater::insert(EntryType value) { - for (const auto& idx : idxs) { - writer.write(&_store.get(idx), sizeof(EntryType)); + auto cmp = _store.make_comparator(value); + auto result = _store._dict->add(cmp, [this, &value]() -> EntryRef { return _store._store.get_allocator().allocate(value); }); + if (result.inserted()) { + _possibly_unused.insert(result.ref()); } } template <class EntryType> +void +EnumStoreT<EntryType>::write_value(BufferWriter& writer, Index idx) const +{ + writer.write(&_store.get(idx), sizeof(EntryType)); +} + +template <class EntryType> bool EnumStoreT<EntryType>::foldedChange(const Index &idx1, const Index &idx2) const { @@ -199,12 +208,10 @@ EnumStoreT<EntryType>::freeUnusedEnums(const IndexSet& toRemove) } template <typename EntryType> -void -EnumStoreT<EntryType>::addEnum(EntryType value, Index& newIdx) +IEnumStore::Index +EnumStoreT<EntryType>::insert(EntryType value) { - auto cmp = make_comparator(value); - auto add_result = _dict->add(cmp, [this, &value]() -> EntryRef { return _store.get_allocator().allocate(value); }); - newIdx = add_result.ref(); + return _store.add(value).ref(); } template <typename EntryType> @@ -251,4 +258,11 @@ EnumStoreT<EntryType>::compact_worst(bool compact_memory, bool compact_address_s return _store.compact_worst(compact_memory, compact_address_space); } +template <typename EntryType> +std::unique_ptr<IEnumStore::Enumerator> +EnumStoreT<EntryType>::make_enumerator() const +{ + return std::make_unique<Enumerator>(*_dict, _store.get_data_store()); +} + } diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h index acaa5556cd9..a5a888f10e7 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h @@ -6,6 +6,7 @@ #include "enum_store_types.h" #include <vespa/searchcommon/attribute/iattributevector.h> #include <vespa/vespalib/datastore/entryref.h> +#include <vespa/vespalib/datastore/unique_store_enumerator.h> #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/util/array.h> #include <vespa/vespalib/util/memoryusage.h> @@ -37,6 +38,7 @@ public: using EnumHandle = enumstore::EnumHandle; using EnumVector = enumstore::EnumVector; using EnumIndexRemapper = datastore::UniqueStoreRemapper<InternalIndex>; + using Enumerator = datastore::UniqueStoreEnumerator<IEnumStore::InternalIndex>; struct CompareEnumIndex { using Index = IEnumStore::Index; @@ -50,7 +52,7 @@ public: virtual ~IEnumStore() = default; - virtual void writeValues(BufferWriter& writer, vespalib::ConstArrayRef<Index> idxs) const = 0; + virtual void write_value(BufferWriter& writer, Index idx) const = 0; virtual ssize_t load_unique_values(const void* src, size_t available, IndexVector& idx) = 0; virtual void fixupRefCount(Index idx, uint32_t refCount) = 0; virtual void fixupRefCounts(const EnumVector& histogram) = 0; @@ -59,13 +61,15 @@ public: virtual bool foldedChange(const Index& idx1, const Index& idx2) const = 0; virtual IEnumStoreDictionary& getEnumStoreDict() = 0; virtual const IEnumStoreDictionary& getEnumStoreDict() const = 0; - virtual const datastore::DataStoreBase& get_data_store_base() const = 0; virtual uint32_t getNumUniques() const = 0; virtual vespalib::MemoryUsage getValuesMemoryUsage() const = 0; virtual vespalib::MemoryUsage getDictionaryMemoryUsage() const = 0; virtual vespalib::MemoryUsage update_stat() = 0; virtual std::unique_ptr<EnumIndexRemapper> consider_compact(const CompactionStrategy& compaction_strategy) = 0; virtual std::unique_ptr<EnumIndexRemapper> compact_worst(bool compact_memory, bool compact_address_space) = 0; + virtual uint64_t get_compaction_count() const = 0; + // Should only be used by unit tests. + virtual void inc_compaction_count() = 0; enumstore::EnumeratedLoader make_enumerated_loader() { return enumstore::EnumeratedLoader(*this); @@ -75,6 +79,8 @@ public: return enumstore::EnumeratedPostingsLoader(*this); } + virtual std::unique_ptr<Enumerator> make_enumerator() const = 0; + template <typename TreeT> void fixupRefCounts(const EnumVector& hist, TreeT& tree) { if (hist.empty()) { diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h index c167fabfdcd..72e90da28fa 100644 --- a/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h +++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h @@ -38,7 +38,6 @@ public: virtual ~IEnumStoreDictionary() = default; virtual uint32_t getNumUniques() const = 0; - virtual void writeAllValues(BufferWriter& writer, btree::BTreeNode::Ref rootRef) const = 0; virtual void fixupRefCounts(const EnumVector& hist) = 0; virtual void freeUnusedEnums(const datastore::EntryComparator& cmp) = 0; @@ -50,7 +49,6 @@ public: findMatchingEnums(const datastore::EntryComparator& cmp) const = 0; virtual void onReset() = 0; - virtual btree::BTreeNode::Ref getFrozenRootRef() const = 0; virtual EnumPostingTree& getPostingDictionary() = 0; virtual const EnumPostingTree& getPostingDictionary() const = 0; diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp index 13079b6591c..016ed8bf710 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp +++ b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp @@ -84,8 +84,8 @@ MultiValueEnumAttributeSaver(GenerationHandler::Guard &&guard, : Parent(std::move(guard), header, mvMapping), _mvMapping(mvMapping), _enumSaver(enumStore), - _enum_store_data_store_base(enumStore.get_data_store_base()), - _compaction_count(_enum_store_data_store_base.get_compaction_count()) + _enum_store(enumStore), + _compaction_count(enumStore.get_compaction_count()) { } @@ -94,7 +94,7 @@ template <typename MultiValueT> bool MultiValueEnumAttributeSaver<MultiValueT>::compaction_interferred() const { - return _compaction_count != _enum_store_data_store_base.get_compaction_count(); + return _compaction_count != _enum_store.get_compaction_count(); } template <typename MultiValueT> diff --git a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h index 3f770c2a0bb..766a828c147 100644 --- a/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h +++ b/searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h @@ -24,9 +24,9 @@ class MultiValueEnumAttributeSaver : public MultiValueAttributeSaver using MultiValueMapping = attribute::MultiValueMapping<MultiValueType>; const MultiValueMapping &_mvMapping; - EnumAttributeSaver _enumSaver; - const datastore::DataStoreBase &_enum_store_data_store_base; - uint64_t _compaction_count; + EnumAttributeSaver _enumSaver; + const IEnumStore &_enum_store; + uint64_t _compaction_count; bool compaction_interferred() const; public: bool onSave(IAttributeSaveTarget &saveTarget) override; diff --git a/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary.h b/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary.h index 3299529032a..9604d1d5339 100644 --- a/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary.h +++ b/vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary.h @@ -5,6 +5,7 @@ #include "entryref.h" #include <vespa/vespalib/util/arrayref.h> #include <vespa/vespalib/util/generationhandler.h> +#include <vespa/vespalib/util/memoryusage.h> #include <functional> namespace search::datastore { @@ -27,8 +28,6 @@ public: public: using UP = std::unique_ptr<ReadSnapshot>; virtual ~ReadSnapshot() = default; - // TODO: Remove when all relevant functions have been migrated to this API. - virtual EntryRef get_frozen_root() const = 0; virtual size_t count(const EntryComparator& comp) const = 0; virtual size_t count_in_range(const EntryComparator& low, const EntryComparator& high) const = 0; virtual void foreach_key(std::function<void(EntryRef)> callback) const = 0; @@ -49,7 +48,6 @@ public: virtual void build(vespalib::ConstArrayRef<EntryRef> refs) = 0; virtual void build_with_payload(const std::vector<EntryRef>& refs, const std::vector<uint32_t>& payloads) = 0; virtual std::unique_ptr<ReadSnapshot> get_read_snapshot() const = 0; - virtual EntryRef get_frozen_root() const = 0; }; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.h b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.h index 21bc796b52b..69fbc332485 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.h @@ -27,7 +27,6 @@ protected: public: ReadSnapshotImpl(FrozenView frozen_view); - EntryRef get_frozen_root() const override { return _frozen_view.getRoot(); } size_t count(const EntryComparator& comp) const override; size_t count_in_range(const EntryComparator& low, const EntryComparator& high) const override; void foreach_key(std::function<void(EntryRef)> callback) const override; @@ -51,7 +50,6 @@ public: void build(vespalib::ConstArrayRef<EntryRef> refs) override; void build_with_payload(const std::vector<EntryRef>& refs, const std::vector<uint32_t>& payloads) override; std::unique_ptr<ReadSnapshot> get_read_snapshot() const override; - EntryRef get_frozen_root() const override; }; } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp index 02bf8ac14e6..14ed0c380c5 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp @@ -210,11 +210,4 @@ UniqueStoreDictionary<DictionaryT, ParentT>::get_read_snapshot() const return std::make_unique<ReadSnapshotImpl>(_dict.getFrozenView()); } -template <typename DictionaryT, typename ParentT> -EntryRef -UniqueStoreDictionary<DictionaryT, ParentT>::get_frozen_root() const -{ - return _dict.getFrozenView().getRoot(); -} - } diff --git a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.h b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.h index 0ffc695a285..5341647815e 100644 --- a/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.h +++ b/vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.h @@ -6,6 +6,8 @@ namespace search::datastore { +class DataStoreBase; + /** * Enumerator for related UniqueStore class. * @@ -28,7 +30,6 @@ private: public: UniqueStoreEnumerator(const IUniqueStoreDictionary &dict, const DataStoreBase &store); ~UniqueStoreEnumerator(); - EntryRef get_frozen_root() const { return _dict_snapshot->get_frozen_root(); } void enumerateValue(EntryRef ref); void enumerateValues(); void clear(); |