summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--searchcore/src/tests/proton/attribute/attributeflush_test.cpp2
-rw-r--r--searchlib/src/tests/attribute/enum_comparator/enum_comparator_test.cpp33
-rw-r--r--searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp2
-rw-r--r--searchlib/src/tests/attribute/enumstore/enumstore_test.cpp65
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.cpp22
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enum_store_dictionary.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumattributesaver.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumattributesaver.h8
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.h27
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.hpp32
-rw-r--r--searchlib/src/vespa/searchlib/attribute/i_enum_store.h10
-rw-r--r--searchlib/src/vespa/searchlib/attribute/i_enum_store_dictionary.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multienumattributesaver.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multienumattributesaver.h6
-rw-r--r--vespalib/src/vespa/vespalib/datastore/i_unique_store_dictionary.h4
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.h2
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_dictionary.hpp7
-rw-r--r--vespalib/src/vespa/vespalib/datastore/unique_store_enumerator.h3
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();