summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2023-04-14 22:07:48 +0200
committerTor Egge <Tor.Egge@online.no>2023-04-14 22:07:48 +0200
commite8d305235e54c2f58998401b3f6245b3e6fd3031 (patch)
treeea7e7675a2face3add29b51493ca3f3b94d701f2 /searchlib
parenta214f60664de35f527e54fc253b2f6ba6cd5b8c3 (diff)
Ensure that default value is present in enum store.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/attribute/attribute_test.cpp28
-rw-r--r--searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp21
-rw-r--r--searchlib/src/tests/attribute/enumstore/enumstore_test.cpp20
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributevector.cpp2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enum_store_loaders.cpp8
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enum_store_loaders.h1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumattribute.hpp1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.h4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/enumstore.hpp42
-rw-r--r--searchlib/src/vespa/searchlib/attribute/i_enum_store.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp3
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/stringbase.cpp4
17 files changed, 111 insertions, 36 deletions
diff --git a/searchlib/src/tests/attribute/attribute_test.cpp b/searchlib/src/tests/attribute/attribute_test.cpp
index d2d3ccaad23..3a1a5b457ef 100644
--- a/searchlib/src/tests/attribute/attribute_test.cpp
+++ b/searchlib/src/tests/attribute/attribute_test.cpp
@@ -913,7 +913,7 @@ AttributeTest::testSingle()
AttributePtr ptr = createAttribute("sv-post-int32", cfg);
ptr->updateStat(true);
EXPECT_EQ(338972u, ptr->getStatus().getAllocated());
- EXPECT_EQ(101492u, ptr->getStatus().getUsed());
+ EXPECT_EQ(101632u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<IntegerAttribute, AttributeVector::largeint_t, int32_t>(ptr, values);
}
@@ -935,7 +935,7 @@ AttributeTest::testSingle()
AttributePtr ptr = createAttribute("sv-post-float", cfg);
ptr->updateStat(true);
EXPECT_EQ(338972u, ptr->getStatus().getAllocated());
- EXPECT_EQ(101492u, ptr->getStatus().getUsed());
+ EXPECT_EQ(101632u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<FloatingPointAttribute, double, float>(ptr, values);
}
@@ -948,7 +948,7 @@ AttributeTest::testSingle()
AttributePtr ptr = createAttribute("sv-string", Config(BasicType::STRING, CollectionType::SINGLE));
ptr->updateStat(true);
EXPECT_EQ(116528u + sizeof_large_string_entry, ptr->getStatus().getAllocated());
- EXPECT_EQ(52760u + sizeof_large_string_entry, ptr->getStatus().getUsed());
+ EXPECT_EQ(52844u + sizeof_large_string_entry, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<StringAttribute, string, string>(ptr, values);
}
@@ -958,7 +958,7 @@ AttributeTest::testSingle()
AttributePtr ptr = createAttribute("sv-fs-string", cfg);
ptr->updateStat(true);
EXPECT_EQ(344848u + sizeof_large_string_entry, ptr->getStatus().getAllocated());
- EXPECT_EQ(104408u + sizeof_large_string_entry, ptr->getStatus().getUsed());
+ EXPECT_EQ(104556u + sizeof_large_string_entry, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testSingle<StringAttribute, string, string>(ptr, values);
}
@@ -1110,7 +1110,7 @@ AttributeTest::testArray()
AttributePtr ptr = createAttribute("a-fs-int32", cfg);
ptr->updateStat(true);
EXPECT_EQ(844116u, ptr->getStatus().getAllocated());
- EXPECT_EQ(581232u, ptr->getStatus().getUsed());
+ EXPECT_EQ(581372u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<IntegerAttribute, AttributeVector::largeint_t>(ptr, values);
}
@@ -1129,7 +1129,7 @@ AttributeTest::testArray()
AttributePtr ptr = createAttribute("a-fs-float", cfg);
ptr->updateStat(true);
EXPECT_EQ(844116u, ptr->getStatus().getAllocated());
- EXPECT_EQ(581232u, ptr->getStatus().getUsed());
+ EXPECT_EQ(581372u, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<FloatingPointAttribute, double>(ptr, values);
}
@@ -1141,7 +1141,7 @@ AttributeTest::testArray()
AttributePtr ptr = createAttribute("a-string", Config(BasicType::STRING, CollectionType::ARRAY));
ptr->updateStat(true);
EXPECT_EQ(599784u + sizeof_large_string_entry, ptr->getStatus().getAllocated());
- EXPECT_EQ(532480u + sizeof_large_string_entry, ptr->getStatus().getUsed());
+ EXPECT_EQ(532564u + sizeof_large_string_entry, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<StringAttribute, string>(ptr, values);
}
@@ -1151,7 +1151,7 @@ AttributeTest::testArray()
AttributePtr ptr = createAttribute("afs-string", cfg);
ptr->updateStat(true);
EXPECT_EQ(849992u + sizeof_large_string_entry, ptr->getStatus().getAllocated());
- EXPECT_EQ(584148u + sizeof_large_string_entry, ptr->getStatus().getUsed());
+ EXPECT_EQ(584296u + sizeof_large_string_entry, ptr->getStatus().getUsed());
addDocs(ptr, numDocs);
testArray<StringAttribute, string>(ptr, values);
}
@@ -1718,7 +1718,7 @@ AttributeTest::testStatus()
ptr->commit(true);
EXPECT_EQ(ptr->getStatus().getNumDocs(), 100u);
EXPECT_EQ(ptr->getStatus().getNumValues(), 100u);
- EXPECT_EQ(ptr->getStatus().getNumUniqueValues(), 1u);
+ EXPECT_EQ(ptr->getStatus().getNumUniqueValues(), 2u);
size_t expUsed = 0;
expUsed += 1 * InternalNodeSize + 1 * LeafNodeSize; // enum store tree
expUsed += 1 * 32; // enum store (uniquevalues * bytes per entry)
@@ -1741,7 +1741,7 @@ AttributeTest::testStatus()
ptr->commit(true);
EXPECT_EQ(ptr->getStatus().getNumDocs(), numDocs);
EXPECT_EQ(ptr->getStatus().getNumValues(), numDocs*numValuesPerDoc);
- EXPECT_EQ(ptr->getStatus().getNumUniqueValues(), numUniq);
+ EXPECT_EQ(ptr->getStatus().getNumUniqueValues(), numUniq + 1);
size_t expUsed = 0;
expUsed += 1 * InternalNodeSize + 1 * LeafNodeSize; // Approximate enum store tree
expUsed += 272; // TODO Approximate... enum store (16 unique values, 17 bytes per entry)
@@ -2145,12 +2145,12 @@ AttributeTest::test_default_value_ref_count_is_updated_after_shrink_lid_space()
const auto & iattr = dynamic_cast<const search::IntegerAttributeTemplate<int32_t> &>(*attr);
attr->addReservedDoc();
attr->addDocs(10);
- EXPECT_EQ(11u, get_default_value_ref_count(*attr, iattr.defaultValue()));
+ EXPECT_EQ(12u, get_default_value_ref_count(*attr, iattr.defaultValue()));
attr->compactLidSpace(6);
- EXPECT_EQ(11u, get_default_value_ref_count(*attr, iattr.defaultValue()));
+ EXPECT_EQ(12u, get_default_value_ref_count(*attr, iattr.defaultValue()));
attr->shrinkLidSpace();
EXPECT_EQ(6u, attr->getNumDocs());
- EXPECT_EQ(6u, get_default_value_ref_count(*attr, iattr.defaultValue()));
+ EXPECT_EQ(7u, get_default_value_ref_count(*attr, iattr.defaultValue()));
}
template <typename AttributeType>
@@ -2170,7 +2170,7 @@ AttributeTest::requireThatAddressSpaceUsageIsReported(const Config &config, bool
AddressSpaceUsage after = attrPtr->getAddressSpaceUsage();
if (attrPtr->hasEnum()) {
LOG(info, "requireThatAddressSpaceUsageIsReported(%s): Has enum", attrName.c_str());
- EXPECT_EQ(before.enum_store_usage().used(), 1u);
+ EXPECT_EQ(before.enum_store_usage().used(), 2u);
EXPECT_EQ(before.enum_store_usage().dead(), 1u);
EXPECT_GT(after.enum_store_usage().used(), before.enum_store_usage().used());
EXPECT_GE(after.enum_store_usage().limit(), before.enum_store_usage().limit());
diff --git a/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp b/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp
index 820f39089d1..5501c99652b 100644
--- a/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp
+++ b/searchlib/src/tests/attribute/enumeratedsave/enumeratedsave_test.cpp
@@ -183,7 +183,7 @@ MemAttr::bufEqual(const Buffer &lhs, const Buffer &rhs) const
return false;
if (lhs.get() == NULL)
return true;
- if (!EXPECT_TRUE(lhs->getDataLen() == rhs->getDataLen()))
+ if (!EXPECT_EQUAL(lhs->getDataLen(), rhs->getDataLen()))
return false;
if (!EXPECT_TRUE(vespalib::memcmp_safe(lhs->getData(), rhs->getData(),
lhs->getDataLen()) == 0))
@@ -243,8 +243,9 @@ EnumeratedSaveTest::populate(IntegerAttribute &v, unsigned seed,
int weight = 1;
for(size_t i(0), m(v.getNumDocs()); i < m; i++) {
v.clearDoc(i);
- if (i == 9)
+ if (i == 9) {
continue;
+ }
if (i == 7) {
if (v.hasMultiValue()) {
v.append(i, -42, 27);
@@ -270,7 +271,7 @@ EnumeratedSaveTest::populate(IntegerAttribute &v, unsigned seed,
i + 1);
}
} else {
- EXPECT_TRUE( v.update(i, lrand48() & mask) );
+ EXPECT_TRUE( v.update(i, rnd.lrand48() & mask) );
}
}
v.commit();
@@ -288,8 +289,9 @@ EnumeratedSaveTest::populate(FloatingPointAttribute &v, unsigned seed,
int weight = 1;
for(size_t i(0), m(v.getNumDocs()); i < m; i++) {
v.clearDoc(i);
- if (i == 9)
+ if (i == 9) {
continue;
+ }
if (i == 7) {
if (v.hasMultiValue()) {
v.append(i, -42.0, 27);
@@ -315,7 +317,7 @@ EnumeratedSaveTest::populate(FloatingPointAttribute &v, unsigned seed,
i + 1);
}
} else {
- EXPECT_TRUE( v.update(i, lrand48()) );
+ EXPECT_TRUE( v.update(i, rnd.lrand48()) );
}
}
v.commit();
@@ -332,8 +334,9 @@ EnumeratedSaveTest::populate(StringAttribute &v, unsigned seed,
int weight = 1;
for(size_t i(0), m(v.getNumDocs()); i < m; i++) {
v.clearDoc(i);
- if (i == 9)
+ if (i == 9) {
continue;
+ }
if (i == 7) {
if (v.hasMultiValue()) {
v.append(i, "foo", 27);
@@ -712,9 +715,9 @@ EnumeratedSaveTest::test(BasicType bt, CollectionType ct,
Config check_cfg(cfg);
check_cfg.setFastSearch(true);
- checkLoad<VectorType, BufferType>(check_cfg, pref + "0_ee", v0);
- checkLoad<VectorType, BufferType>(check_cfg, pref + "1_ee", v1);
- checkLoad<VectorType, BufferType>(check_cfg, pref + "2_ee", v2);
+ TEST_DO((checkLoad<VectorType, BufferType>(check_cfg, pref + "0_ee", v0)));
+ TEST_DO((checkLoad<VectorType, BufferType>(check_cfg, pref + "1_ee", v1)));
+ TEST_DO((checkLoad<VectorType, BufferType>(check_cfg, pref + "2_ee", v2)));
TEST_DO((testReload<VectorType, BufferType>(v0, v1, v2,
mv0, mv1, mv2,
diff --git a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
index b3c7516777c..7341595ba40 100644
--- a/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
+++ b/searchlib/src/tests/attribute/enumstore/enumstore_test.cpp
@@ -188,7 +188,7 @@ TEST(EnumStoreTest, test_find_folded_on_string_enum_store)
for (std::string &str : unique) {
EnumIndex idx = ses.insert(str.c_str());
indices.push_back(idx);
- EXPECT_EQ(1u, ses.get_ref_count(idx));
+ EXPECT_EQ((str == "") ? 2u : 1u, ses.get_ref_count(idx));
}
ses.freeze_dictionary();
for (uint32_t i = 0; i < indices.size(); ++i) {
@@ -239,7 +239,7 @@ StringEnumStoreTest::testInsert(bool hasPostings)
for (const auto & i : unique) {
EnumIndex idx = ses.insert(i.c_str());
- EXPECT_EQ(1u, ses.get_ref_count(idx));
+ EXPECT_EQ((i == "") ? 2u : 1u, ses.get_ref_count(idx));
indices.push_back(idx);
EXPECT_TRUE(ses.find_index(i.c_str(), idx));
}
@@ -253,7 +253,7 @@ StringEnumStoreTest::testInsert(bool hasPostings)
EnumIndex idx;
EXPECT_TRUE(ses.find_index(unique[i].c_str(), idx));
EXPECT_TRUE(idx == indices[i]);
- EXPECT_EQ(1u, ses.get_ref_count(indices[i]));
+ EXPECT_EQ((i == 0) ? 2u : 1u, ses.get_ref_count(indices[i]));
const char* value = nullptr;
EXPECT_TRUE(ses.get_value(indices[i], value));
EXPECT_TRUE(strcmp(unique[i].c_str(), value) == 0);
@@ -354,16 +354,16 @@ TEST(EnumStoreTest, address_space_usage_is_reported)
NumericEnumStore store(false, DictionaryConfig::Type::BTREE);
using vespalib::AddressSpace;
- EXPECT_EQ(AddressSpace(1, 1, ADDRESS_LIMIT), store.get_values_address_space_usage());
- EnumIndex idx1 = store.insert(10);
EXPECT_EQ(AddressSpace(2, 1, ADDRESS_LIMIT), store.get_values_address_space_usage());
- EnumIndex idx2 = store.insert(20);
+ EnumIndex idx1 = store.insert(10);
// Address limit increases because buffer is re-sized.
EXPECT_EQ(AddressSpace(3, 1, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
+ EnumIndex idx2 = store.insert(20);
+ EXPECT_EQ(AddressSpace(4, 1, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
dec_ref_count(store, idx1);
- EXPECT_EQ(AddressSpace(3, 2, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
+ EXPECT_EQ(AddressSpace(4, 2, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
dec_ref_count(store, idx2);
- EXPECT_EQ(AddressSpace(3, 3, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
+ EXPECT_EQ(AddressSpace(4, 3, ADDRESS_LIMIT + 2), store.get_values_address_space_usage());
}
TEST(EnumStoreTest, provided_memory_allocator_is_used)
@@ -539,6 +539,7 @@ TYPED_TEST_SUITE(LoaderTest, LoaderTestTypes);
TYPED_TEST(LoaderTest, store_is_instantiated_with_enumerated_loader)
{
+ this->store.clear_default_value_ref();
auto loader = this->store.make_enumerated_loader();
this->load_values(loader);
loader.allocate_enums_histogram();
@@ -554,6 +555,7 @@ TYPED_TEST(LoaderTest, store_is_instantiated_with_enumerated_loader)
TYPED_TEST(LoaderTest, store_is_instantiated_with_enumerated_postings_loader)
{
+ this->store.clear_default_value_ref();
auto loader = this->store.make_enumerated_postings_loader();
this->load_values(loader);
this->set_ref_count(0, 1, loader);
@@ -568,6 +570,7 @@ TYPED_TEST(LoaderTest, store_is_instantiated_with_enumerated_postings_loader)
TYPED_TEST(LoaderTest, store_is_instantiated_with_non_enumerated_loader)
{
+ this->store.clear_default_value_ref();
auto loader = this->store.make_non_enumerated_loader();
using MyValues = LoaderTestValues<typename TypeParam::EnumStoreType>;
loader.insert(MyValues::values[0], 100);
@@ -904,6 +907,7 @@ TYPED_TEST(EnumStoreDictionaryTest, compact_worst_works)
}
std::vector<int32_t> exp_values;
std::vector<int32_t> values;
+ exp_values.push_back(std::numeric_limits<int32_t>::min());
for (int32_t i = 0; i < 20; ++i) {
exp_values.push_back(i);
}
diff --git a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp
index 1a2c8c43b94..9110c08099a 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributevector.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attributevector.cpp
@@ -353,6 +353,8 @@ AttributeVector::load(vespalib::Executor * executor) {
bool loaded = onLoad(executor);
if (loaded) {
commit();
+ incGeneration();
+ updateStat(true);
}
_loaded = loaded;
return _loaded;
diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.cpp b/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.cpp
index eeaa3e9539f..c1345b4f770 100644
--- a/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.cpp
@@ -93,6 +93,7 @@ EnumeratedLoader::build_dictionary()
{
_store.get_dictionary().build(_indexes);
release_enum_indexes();
+ _store.setup_default_value_ref();
}
EnumeratedPostingsLoader::EnumeratedPostingsLoader(IEnumStore& store)
@@ -131,6 +132,13 @@ EnumeratedPostingsLoader::build_dictionary()
_store.get_dictionary().build_with_payload(_indexes, _posting_indexes);
release_enum_indexes();
EntryRefVector().swap(_posting_indexes);
+ _store.setup_default_value_ref();
+}
+
+void
+EnumeratedPostingsLoader::build_empty_dictionary()
+{
+ _store.setup_default_value_ref();
}
}
diff --git a/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.h b/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.h
index 2a72fcac628..937ceb91628 100644
--- a/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.h
+++ b/searchlib/src/vespa/searchlib/attribute/enum_store_loaders.h
@@ -85,6 +85,7 @@ public:
void set_ref_count(Index idx, uint32_t ref_count);
vespalib::ArrayRef<EntryRef> initialize_empty_posting_indexes();
void build_dictionary();
+ void build_empty_dictionary();
};
}
diff --git a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp
index c5188b89129..a28a100cde5 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/enumattribute.hpp
@@ -50,6 +50,7 @@ void EnumAttribute<B>::load_enum_store(LoadedVector& loaded)
loader.set_ref_count_for_last_value(prevRefCount);
}
loader.build_dictionary();
+ _enumStore.setup_default_value_ref();
}
}
diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.h b/searchlib/src/vespa/searchlib/attribute/enumstore.h
index 266437fafa1..e8b18cf3974 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumstore.h
+++ b/searchlib/src/vespa/searchlib/attribute/enumstore.h
@@ -55,6 +55,8 @@ private:
ComparatorType _comparator;
ComparatorType _foldedComparator;
enumstore::EnumStoreCompactionSpec _compaction_spec;
+ EntryType _default_value;
+ Index _default_value_ref;
EnumStoreT(const EnumStoreT & rhs) = delete;
EnumStoreT & operator=(const EnumStoreT & rhs) = delete;
@@ -201,6 +203,8 @@ public:
bool find_index(EntryType value, Index& idx) const;
void free_unused_values() override;
void free_unused_values(IndexList to_remove);
+ void clear_default_value_ref() override;
+ void setup_default_value_ref() override;
vespalib::MemoryUsage update_stat(const CompactionStrategy& compaction_strategy) override;
std::unique_ptr<EnumIndexRemapper> consider_compact_values(const CompactionStrategy& compaction_strategy) override;
std::unique_ptr<EnumIndexRemapper> compact_worst_values(CompactionSpec compaction_spec, const CompactionStrategy& compaction_strategy) override;
diff --git a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
index bc767a296eb..a78d545c15f 100644
--- a/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/enumstore.hpp
@@ -17,6 +17,7 @@
#include <vespa/vespalib/datastore/unique_store.hpp>
#include <vespa/vespalib/datastore/unique_store_string_allocator.hpp>
#include <vespa/vespalib/util/array.hpp>
+#include <vespa/searchcommon/common/undefinedvalues.h>
#include <vespa/searchlib/util/bufferwriter.h>
#include <vespa/vespalib/datastore/compaction_strategy.h>
@@ -78,12 +79,18 @@ EnumStoreT<EntryT>::EnumStoreT(bool has_postings, const DictionaryConfig& dict_c
_is_folded(dict_cfg.getMatch() == DictionaryConfig::Match::UNCASED),
_comparator(_store.get_data_store()),
_foldedComparator(make_optionally_folded_comparator(is_folded())),
- _compaction_spec()
+ _compaction_spec(),
+ _default_value(attribute::getUndefined<EntryT>()),
+ _default_value_ref()
{
+ if constexpr (std::is_same_v<const char *, EntryT>) {
+ _default_value = "";
+ }
_store.set_dictionary(make_enum_store_dictionary(*this, has_postings, dict_cfg,
allocate_comparator(),
allocate_optionally_folded_comparator(is_folded())));
_dict = static_cast<IEnumStoreDictionary*>(&_store.get_dictionary());
+ setup_default_value_ref();
}
template <typename EntryT>
@@ -215,6 +222,31 @@ EnumStoreT<EntryT>::insert(EntryType value)
return _store.add(value).ref();
}
+
+template <typename EntryT>
+void
+EnumStoreT<EntryT>::clear_default_value_ref()
+{
+ if (_default_value_ref.valid()) {
+ auto updater = make_batch_updater();
+ updater.dec_ref_count(_default_value_ref);
+ _default_value_ref = Index();
+ updater.commit();
+ }
+}
+
+template <typename EntryT>
+void
+EnumStoreT<EntryT>::setup_default_value_ref()
+{
+ if (!_default_value_ref.valid()) {
+ auto updater = make_batch_updater();
+ _default_value_ref = updater.insert(_default_value);
+ updater.inc_ref_count(_default_value_ref);
+ updater.commit();
+ }
+}
+
template <typename EntryT>
vespalib::MemoryUsage
EnumStoreT<EntryT>::update_stat(const CompactionStrategy& compaction_strategy)
@@ -236,7 +268,13 @@ template <typename EntryT>
std::unique_ptr<IEnumStore::EnumIndexRemapper>
EnumStoreT<EntryT>::compact_worst_values(CompactionSpec compaction_spec, const CompactionStrategy& compaction_strategy)
{
- return _store.compact_worst(compaction_spec, compaction_strategy);
+ auto remapper = _store.compact_worst(compaction_spec, compaction_strategy);
+ if (_default_value_ref.valid()) {
+ if (remapper->get_entry_ref_filter().has(_default_value_ref)) {
+ _default_value_ref = remapper->remap(_default_value_ref);
+ }
+ }
+ return remapper;
}
template <typename EntryT>
diff --git a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h
index 2157db3e5ed..aa9fd549b60 100644
--- a/searchlib/src/vespa/searchlib/attribute/i_enum_store.h
+++ b/searchlib/src/vespa/searchlib/attribute/i_enum_store.h
@@ -74,6 +74,8 @@ public:
virtual std::unique_ptr<Enumerator> make_enumerator() = 0;
virtual std::unique_ptr<vespalib::datastore::EntryComparator> allocate_comparator() const = 0;
+ virtual void clear_default_value_ref() = 0;
+ virtual void setup_default_value_ref() = 0;
};
}
diff --git a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
index edfea23f48d..59c1216829d 100644
--- a/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multinumericenumattribute.hpp
@@ -97,6 +97,10 @@ MultiValueNumericEnumAttribute<B, M>::onLoad(vespalib::Executor *)
return false;
}
+ this->_enumStore.clear_default_value_ref();
+ this->commit();
+ this->incGeneration();
+
this->setCreateSerialNum(attrReader.getCreateSerialNum());
if (attrReader.getEnumerated()) {
diff --git a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
index a63862126fa..7b11fcd59f4 100644
--- a/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/multistringattribute.hpp
@@ -42,7 +42,6 @@ MultiValueStringAttributeT<B, M>::freezeEnumDictionary()
this->getEnumStore().freeze_dictionary();
}
-
template <typename B, typename M>
std::unique_ptr<attribute::SearchContext>
MultiValueStringAttributeT<B, M>::getSearch(QueryTermSimpleUP qTerm,
diff --git a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp
index 6ef3b575c3e..01e68949f92 100644
--- a/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/postinglistattribute.cpp
@@ -49,6 +49,7 @@ PostingListAttributeBase<P>::handle_load_posting_lists_and_update_enum_store(enu
PostingChange<P> postings;
const auto& loaded_enums = loader.get_loaded_enums();
if (loaded_enums.empty()) {
+ loader.build_empty_dictionary();
return;
}
uint32_t preve = 0;
diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp
index a105d980986..c75ee0aacb5 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/singlenumericattribute.hpp
@@ -134,8 +134,9 @@ SingleValueNumericAttribute<B>::onLoad(vespalib::Executor *)
PrimitiveReader<T> attrReader(*this);
bool ok(attrReader.getHasLoadData());
- if (!ok)
+ if (!ok) {
return false;
+ }
this->setCreateSerialNum(attrReader.getCreateSerialNum());
diff --git a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp
index 52ea0a53533..14bf9cdc9f0 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/singlenumericenumattribute.hpp
@@ -117,6 +117,10 @@ SingleValueNumericEnumAttribute<B>::onLoad(vespalib::Executor *)
return false;
}
+ this->_enumStore.clear_default_value_ref();
+ this->commit();
+ this->incGeneration();
+
this->setCreateSerialNum(attrReader.getCreateSerialNum());
if (attrReader.getEnumerated()) {
diff --git a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp
index 82a4393fc91..69fe6435a03 100644
--- a/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp
+++ b/searchlib/src/vespa/searchlib/attribute/singlestringattribute.hpp
@@ -40,7 +40,6 @@ SingleValueStringAttributeT<B>::freezeEnumDictionary()
this->getEnumStore().freeze_dictionary();
}
-
template <typename B>
std::unique_ptr<attribute::SearchContext>
SingleValueStringAttributeT<B>::getSearch(QueryTermSimpleUP qTerm,
diff --git a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
index 80967affaa7..b37318d470e 100644
--- a/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/stringbase.cpp
@@ -223,6 +223,10 @@ StringAttribute::onLoad(vespalib::Executor *)
return false;
}
+ getEnumStoreBase()->clear_default_value_ref();
+ commit();
+ incGeneration();
+
setCreateSerialNum(attrReader.getCreateSerialNum());
assert(attrReader.getEnumerated());