diff options
Diffstat (limited to 'searchlib')
16 files changed, 389 insertions, 271 deletions
diff --git a/searchlib/src/tests/memoryindex/field_index/field_index_iterator_test.cpp b/searchlib/src/tests/memoryindex/field_index/field_index_iterator_test.cpp index df7f80e8601..36e9bde5c9f 100644 --- a/searchlib/src/tests/memoryindex/field_index/field_index_iterator_test.cpp +++ b/searchlib/src/tests/memoryindex/field_index/field_index_iterator_test.cpp @@ -18,10 +18,13 @@ using namespace search::memoryindex; using search::index::schema::DataType; using search::test::SearchIteratorVerifier; +using FieldIndexType = FieldIndex<false>; +using PostingIteratorType = PostingIterator<false>; + class Verifier : public SearchIteratorVerifier { private: mutable TermFieldMatchData _tfmd; - FieldIndex _field_index; + FieldIndexType _field_index; public: Verifier(const Schema& schema) @@ -41,8 +44,8 @@ public: (void) strict; TermFieldMatchDataArray match_data; match_data.add(&_tfmd); - return std::make_unique<PostingIterator>(_field_index.find("a"), - _field_index.getFeatureStore(), 0, match_data); + return std::make_unique<PostingIteratorType>(_field_index.find("a"), + _field_index.getFeatureStore(), 0, match_data); } }; diff --git a/searchlib/src/tests/memoryindex/field_index/field_index_test.cpp b/searchlib/src/tests/memoryindex/field_index/field_index_test.cpp index 15d97d314a1..f2cc2580cd8 100644 --- a/searchlib/src/tests/memoryindex/field_index/field_index_test.cpp +++ b/searchlib/src/tests/memoryindex/field_index/field_index_test.cpp @@ -40,8 +40,10 @@ using vespalib::GenerationHandler; namespace memoryindex { using test::WrapInserter; -using PostingList = FieldIndex::PostingList; +using FieldIndexType = FieldIndex<false>; +using PostingList = FieldIndexType::PostingList; using PostingConstItr = PostingList::ConstIterator; +using PostingIteratorType = PostingIterator<false>; class MyBuilder : public IndexBuilder { private: @@ -197,22 +199,22 @@ assertPostingList(std::vector<uint32_t> &exp, PostingConstItr itr) return assertPostingList(ss.str(), itr); } -FieldIndex::PostingList::Iterator +FieldIndexType::PostingList::Iterator find_in_field_index(const vespalib::stringref word, uint32_t fieldId, const FieldIndexCollection& fic) { - auto* field_index = dynamic_cast<FieldIndex*>(fic.getFieldIndex(fieldId)); + auto* field_index = dynamic_cast<FieldIndexType*>(fic.getFieldIndex(fieldId)); assert(field_index != nullptr); return field_index->find(word); } -FieldIndex::PostingList::ConstIterator +FieldIndexType::PostingList::ConstIterator find_frozen_in_field_index(const vespalib::stringref word, uint32_t fieldId, const FieldIndexCollection& fic) { - auto* field_index = dynamic_cast<FieldIndex*>(fic.getFieldIndex(fieldId)); + auto* field_index = dynamic_cast<FieldIndexType*>(fic.getFieldIndex(fieldId)); assert(field_index != nullptr); return field_index->findFrozen(word); } @@ -409,7 +411,7 @@ public: { } - MyDrainRemoves(FieldIndex& field_index) + MyDrainRemoves(FieldIndexType& field_index) : _remover(field_index.getDocumentRemover()) { } @@ -487,7 +489,7 @@ make_single_field_schema() struct FieldIndexTest : public ::testing::Test { Schema schema; - FieldIndex idx; + FieldIndexType idx; FieldIndexTest() : schema(make_single_field_schema()), idx(schema, 0) @@ -518,8 +520,8 @@ struct FieldIndexCollectionTest : public ::testing::Test { } ~FieldIndexCollectionTest() {} - FieldIndex::PostingList::Iterator find(const vespalib::stringref word, - uint32_t fieldId) const { + FieldIndexType::PostingList::Iterator find(const vespalib::stringref word, + uint32_t fieldId) const { return find_in_field_index(word, fieldId, fic); } }; @@ -671,16 +673,16 @@ TEST_F(FieldIndexTest, require_that_posting_iterator_is_working) TermFieldMatchDataArray matchData; matchData.add(&tfmd); { - PostingIterator itr(idx.find("not"), - idx.getFeatureStore(), - 0, matchData); + PostingIteratorType itr(idx.find("not"), + idx.getFeatureStore(), + 0, matchData); itr.initFullRange(); EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(idx.find("a"), - idx.getFeatureStore(), - 0, matchData); + PostingIteratorType itr(idx.find("a"), + idx.getFeatureStore(), + 0, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -954,12 +956,12 @@ TEST_F(BasicInverterTest, require_that_inversion_is_working) TermFieldMatchDataArray matchData; matchData.add(&tfmd); { - PostingIterator itr(findFrozen("not", 0), featureStoreRef(_fic, 0), 0, matchData); + PostingIteratorType itr(findFrozen("not", 0), featureStoreRef(_fic, 0), 0, matchData); itr.initFullRange(); EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(findFrozen("a", 0), featureStoreRef(_fic, 0), 0, matchData); + PostingIteratorType itr(findFrozen("a", 0), featureStoreRef(_fic, 0), 0, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -976,19 +978,19 @@ TEST_F(BasicInverterTest, require_that_inversion_is_working) EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(findFrozen("x", 0), featureStoreRef(_fic, 0), 0, matchData); + PostingIteratorType itr(findFrozen("x", 0), featureStoreRef(_fic, 0), 0, matchData); itr.initFullRange(); EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(findFrozen("x", 1), featureStoreRef(_fic, 1), 1, matchData); + PostingIteratorType itr(findFrozen("x", 1), featureStoreRef(_fic, 1), 1, matchData); itr.initFullRange(); EXPECT_EQ(30u, itr.getDocId()); itr.unpack(30); EXPECT_EQ("{6:2[e=0,w=1,l=6]}", toString(tfmd.getIterator(), true, true)); } { - PostingIterator itr(findFrozen("x", 2), featureStoreRef(_fic, 2), 2, matchData); + PostingIteratorType itr(findFrozen("x", 2), featureStoreRef(_fic, 2), 2, matchData); itr.initFullRange(); EXPECT_EQ(30u, itr.getDocId()); itr.unpack(30); @@ -996,7 +998,7 @@ TEST_F(BasicInverterTest, require_that_inversion_is_working) EXPECT_EQ("{2:1[e=0,w=1,l=2]}", toString(tfmd.getIterator(), true, true)); } { - PostingIterator itr(findFrozen("x", 3), featureStoreRef(_fic, 3), 3, matchData); + PostingIteratorType itr(findFrozen("x", 3), featureStoreRef(_fic, 3), 3, matchData); itr.initFullRange(); EXPECT_EQ(30u, itr.getDocId()); itr.unpack(30); @@ -1193,17 +1195,17 @@ TEST_F(UriInverterTest, require_that_uri_indexing_is_working) matchData.add(&tfmd); { uint32_t fieldId = _schema.getIndexFieldId("iu"); - PostingIterator itr(findFrozen("not", fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("not", fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_TRUE(itr.isAtEnd()); } { uint32_t fieldId = _schema.getIndexFieldId("iu"); - PostingIterator itr(findFrozen("example", fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("example", fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -1213,9 +1215,9 @@ TEST_F(UriInverterTest, require_that_uri_indexing_is_working) } { uint32_t fieldId = _schema.getIndexFieldId("iau"); - PostingIterator itr(findFrozen("example", fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("example", fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -1226,9 +1228,9 @@ TEST_F(UriInverterTest, require_that_uri_indexing_is_working) } { uint32_t fieldId = _schema.getIndexFieldId("iwu"); - PostingIterator itr(findFrozen("example", fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("example", fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -1279,18 +1281,18 @@ TEST_F(CjkInverterTest, require_that_cjk_indexing_is_working) matchData.add(&tfmd); uint32_t fieldId = _schema.getIndexFieldId("f0"); { - PostingIterator itr(findFrozen("not", fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("not", fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(findFrozen("我就" - "是那个", - fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("我就" + "是那个", + fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); @@ -1299,11 +1301,11 @@ TEST_F(CjkInverterTest, require_that_cjk_indexing_is_working) EXPECT_TRUE(itr.isAtEnd()); } { - PostingIterator itr(findFrozen("大灰" - "狼", - fieldId), - featureStoreRef(_fic, fieldId), - fieldId, matchData); + PostingIteratorType itr(findFrozen("大灰" + "狼", + fieldId), + featureStoreRef(_fic, fieldId), + fieldId, matchData); itr.initFullRange(); EXPECT_EQ(10u, itr.getDocId()); itr.unpack(10); diff --git a/searchlib/src/vespa/searchlib/memoryindex/CMakeLists.txt b/searchlib/src/vespa/searchlib/memoryindex/CMakeLists.txt index 441fe12c383..c19596692cc 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/CMakeLists.txt +++ b/searchlib/src/vespa/searchlib/memoryindex/CMakeLists.txt @@ -5,6 +5,7 @@ vespa_add_library(searchlib_memoryindex OBJECT document_inverter.cpp feature_store.cpp field_index.cpp + field_index_base.cpp field_index_collection.cpp field_index_remover.cpp field_inverter.cpp diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index.cpp b/searchlib/src/vespa/searchlib/memoryindex/field_index.cpp index e492e3e7eee..a5dc921cfdf 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/field_index.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/field_index.cpp @@ -48,33 +48,24 @@ void set_interleaved_features(DocIdAndFeatures &features) using datastore::EntryRef; -vespalib::asciistream & -operator<<(vespalib::asciistream & os, const FieldIndex::WordKey & rhs) -{ - os << "wr(" << rhs._wordRef.ref() << ")"; - return os; -} - -FieldIndex::FieldIndex(const index::Schema& schema, uint32_t fieldId) +template <bool interleaved_features> +FieldIndex<interleaved_features>::FieldIndex(const index::Schema& schema, uint32_t fieldId) : FieldIndex(schema, fieldId, index::FieldLengthInfo()) { } -FieldIndex::FieldIndex(const index::Schema& schema, uint32_t fieldId, const index::FieldLengthInfo& info) - : _wordStore(), - _numUniqueWords(0), - _generationHandler(), - _dict(), - _postingListStore(), - _featureStore(schema), - _fieldId(fieldId), - _remover(_wordStore), - _inserter(std::make_unique<OrderedFieldIndexInserter>(*this)), - _calculator(info) +template <bool interleaved_features> +FieldIndex<interleaved_features>::FieldIndex(const index::Schema& schema, uint32_t fieldId, + const index::FieldLengthInfo& info) + : FieldIndexBase(schema, fieldId, info), + _postingListStore() { + using InserterType = OrderedFieldIndexInserter<interleaved_features>; + _inserter = std::make_unique<InserterType>(*this); } -FieldIndex::~FieldIndex() +template <bool interleaved_features> +FieldIndex<interleaved_features>::~FieldIndex() { _postingListStore.disableFreeLists(); _postingListStore.disableElemHoldList(); @@ -101,28 +92,31 @@ FieldIndex::~FieldIndex() trimHoldLists(); } -FieldIndex::PostingList::Iterator -FieldIndex::find(const vespalib::stringref word) const +template <bool interleaved_features> +typename FieldIndex<interleaved_features>::PostingList::Iterator +FieldIndex<interleaved_features>::find(const vespalib::stringref word) const { DictionaryTree::Iterator itr = _dict.find(WordKey(EntryRef()), KeyComp(_wordStore, word)); if (itr.valid()) { return _postingListStore.begin(EntryRef(itr.getData())); } - return PostingList::Iterator(); + return typename PostingList::Iterator(); } -FieldIndex::PostingList::ConstIterator -FieldIndex::findFrozen(const vespalib::stringref word) const +template <bool interleaved_features> +typename FieldIndex<interleaved_features>::PostingList::ConstIterator +FieldIndex<interleaved_features>::findFrozen(const vespalib::stringref word) const { auto itr = _dict.getFrozenView().find(WordKey(EntryRef()), KeyComp(_wordStore, word)); if (itr.valid()) { return _postingListStore.beginFrozen(EntryRef(itr.getData())); } - return PostingList::Iterator(); + return typename PostingList::Iterator(); } +template <bool interleaved_features> void -FieldIndex::compactFeatures() +FieldIndex<interleaved_features>::compactFeatures() { std::vector<uint32_t> toHold; @@ -130,7 +124,7 @@ FieldIndex::compactFeatures() auto itr = _dict.begin(); uint32_t packedIndex = _fieldId; for (; itr.valid(); ++itr) { - PostingListStore::RefType pidx(EntryRef(itr.getData())); + typename PostingListStore::RefType pidx(EntryRef(itr.getData())); if (!pidx.valid()) { continue; } @@ -177,8 +171,9 @@ FieldIndex::compactFeatures() _featureStore.transferHoldLists(generation); } +template <bool interleaved_features> void -FieldIndex::dump(search::index::IndexBuilder & indexBuilder) +FieldIndex<interleaved_features>::dump(search::index::IndexBuilder & indexBuilder) { vespalib::stringref word; FeatureStore::DecodeContextCooked decoder(nullptr); @@ -187,7 +182,7 @@ FieldIndex::dump(search::index::IndexBuilder & indexBuilder) _featureStore.setupForField(_fieldId, decoder); for (auto itr = _dict.begin(); itr.valid(); ++itr) { const WordKey & wk = itr.getKey(); - PostingListStore::RefType plist(EntryRef(itr.getData())); + typename PostingListStore::RefType plist(EntryRef(itr.getData())); word = _wordStore.getWord(wk._wordRef); if (!plist.valid()) { continue; @@ -225,8 +220,9 @@ FieldIndex::dump(search::index::IndexBuilder & indexBuilder) } } +template <bool interleaved_features> vespalib::MemoryUsage -FieldIndex::getMemoryUsage() const +FieldIndex<interleaved_features>::getMemoryUsage() const { vespalib::MemoryUsage usage; usage.merge(_wordStore.getMemoryUsage()); @@ -239,17 +235,20 @@ FieldIndex::getMemoryUsage() const namespace { +template <bool interleaved_features> class MemoryTermBlueprint : public SimpleLeafBlueprint { private: + using FieldIndexType = FieldIndex<interleaved_features>; + using PostingListIteratorType = typename FieldIndexType::PostingList::ConstIterator; GenerationHandler::Guard _guard; - FieldIndex::PostingList::ConstIterator _posting_itr; + PostingListIteratorType _posting_itr; const FeatureStore& _feature_store; const uint32_t _field_id; const bool _use_bit_vector; public: MemoryTermBlueprint(GenerationHandler::Guard&& guard, - FieldIndex::PostingList::ConstIterator posting_itr, + PostingListIteratorType posting_itr, const FeatureStore& feature_store, const FieldSpecBase& field, uint32_t field_id, @@ -267,7 +266,8 @@ public: } SearchIterator::UP createLeafSearch(const TermFieldMatchDataArray& tfmda, bool) const override { - auto result = std::make_unique<PostingIterator>(_posting_itr, _feature_store, _field_id, tfmda); + using PostingIteratorType = PostingIterator<interleaved_features>; + auto result = std::make_unique<PostingIteratorType>(_posting_itr, _feature_store, _field_id, tfmda); if (_use_bit_vector) { LOG(debug, "Return BooleanMatchIteratorWrapper: field_id(%u), doc_count(%zu)", _field_id, _posting_itr.size()); @@ -281,95 +281,99 @@ public: } +template <bool interleaved_features> std::unique_ptr<queryeval::SimpleLeafBlueprint> -FieldIndex::make_term_blueprint(const vespalib::string& term, - const queryeval::FieldSpecBase& field, - uint32_t field_id) +FieldIndex<interleaved_features>::make_term_blueprint(const vespalib::string& term, + const queryeval::FieldSpecBase& field, + uint32_t field_id) { auto guard = takeGenerationGuard(); auto posting_itr = findFrozen(term); bool use_bit_vector = field.isFilter(); - return std::make_unique<MemoryTermBlueprint>(std::move(guard), posting_itr, getFeatureStore(), - field, field_id, use_bit_vector); + return std::make_unique<MemoryTermBlueprint<interleaved_features>> + (std::move(guard), posting_itr, getFeatureStore(), field, field_id, use_bit_vector); } +template +class FieldIndex<false>; + } namespace search::btree { template -class BTreeNodeDataWrap<memoryindex::FieldIndex::WordKey, BTreeDefaultTraits::LEAF_SLOTS>; +class BTreeNodeDataWrap<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::LEAF_SLOTS>; template -class BTreeNodeT<memoryindex::FieldIndex::WordKey, BTreeDefaultTraits::INTERNAL_SLOTS>; +class BTreeNodeT<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::INTERNAL_SLOTS>; #if 0 template -class BTreeNodeT<memoryindex::FieldIndex::WordKey, +class BTreeNodeT<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::LEAF_SLOTS>; #endif template -class BTreeNodeTT<memoryindex::FieldIndex::WordKey, +class BTreeNodeTT<memoryindex::FieldIndexBase::WordKey, datastore::EntryRef, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS>; template -class BTreeNodeTT<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeTT<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::LEAF_SLOTS>; template -class BTreeInternalNode<memoryindex::FieldIndex::WordKey, +class BTreeInternalNode<memoryindex::FieldIndexBase::WordKey, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS>; template -class BTreeLeafNode<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeLeafNode<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::LEAF_SLOTS>; template -class BTreeNodeStore<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeStore<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS, BTreeDefaultTraits::LEAF_SLOTS>; template -class BTreeIterator<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeIterator<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, + const memoryindex::FieldIndexBase::KeyComp, BTreeDefaultTraits>; template -class BTree<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTree<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, + const memoryindex::FieldIndexBase::KeyComp, BTreeDefaultTraits>; template -class BTreeRoot<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeRoot<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, + const memoryindex::FieldIndexBase::KeyComp, BTreeDefaultTraits>; template -class BTreeRootBase<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeRootBase<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS, BTreeDefaultTraits::LEAF_SLOTS>; template -class BTreeNodeAllocator<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeAllocator<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS, BTreeDefaultTraits::LEAF_SLOTS>; diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index.h b/searchlib/src/vespa/searchlib/memoryindex/field_index.h index 9c97ebf3e85..05665945800 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/field_index.h +++ b/searchlib/src/vespa/searchlib/memoryindex/field_index.h @@ -2,20 +2,13 @@ #pragma once -#include "feature_store.h" -#include "field_index_remover.h" -#include "i_field_index.h" +#include "field_index_base.h" #include "posting_list_entry.h" -#include "word_store.h" -#include <vespa/searchlib/index/docidandfeatures.h> -#include <vespa/searchlib/index/field_length_calculator.h> #include <vespa/searchlib/index/indexbuilder.h> #include <vespa/vespalib/btree/btree.h> #include <vespa/vespalib/btree/btreenodeallocator.h> #include <vespa/vespalib/btree/btreeroot.h> #include <vespa/vespalib/btree/btreestore.h> -#include <vespa/vespalib/stllike/string.h> -#include <vespa/vespalib/util/memoryusage.h> namespace search::memoryindex { @@ -33,95 +26,24 @@ class IOrderedFieldIndexInserter; * This information is unpacked and used during ranking. * * Elements in the three stores are accessed using 32-bit references / handles. + * + * The template parameter specifies whether the underlying posting lists have interleaved features or not. */ -class FieldIndex : public IFieldIndex { +template <bool interleaved_features> +class FieldIndex : public FieldIndexBase { public: // Mapping from docid -> feature ref - using PostingListEntryType = PostingListEntry<false>; + using PostingListEntryType = PostingListEntry<interleaved_features>; using PostingList = btree::BTreeRoot<uint32_t, PostingListEntryType, search::btree::NoAggregated>; using PostingListStore = btree::BTreeStore<uint32_t, PostingListEntryType, search::btree::NoAggregated, std::less<uint32_t>, btree::BTreeDefaultTraits>; - using PostingListKeyDataType = PostingListStore::KeyDataType; - - struct WordKey { - datastore::EntryRef _wordRef; - - explicit WordKey(datastore::EntryRef wordRef) : _wordRef(wordRef) { } - WordKey() : _wordRef() { } - - friend vespalib::asciistream & - operator<<(vespalib::asciistream & os, const WordKey & rhs); - }; - - class KeyComp { - private: - const WordStore &_wordStore; - const vespalib::stringref _word; - - const char *getWord(datastore::EntryRef wordRef) const { - if (wordRef.valid()) { - return _wordStore.getWord(wordRef); - } - return _word.data(); - } - - public: - KeyComp(const WordStore &wordStore, const vespalib::stringref word) - : _wordStore(wordStore), - _word(word) - { } - - bool operator()(const WordKey & lhs, const WordKey & rhs) const { - int cmpres = strcmp(getWord(lhs._wordRef), getWord(rhs._wordRef)); - return cmpres < 0; - } - }; - - using PostingListPtr = uint32_t; - using DictionaryTree = btree::BTree<WordKey, PostingListPtr, - search::btree::NoAggregated, - const KeyComp>; -private: - using GenerationHandler = vespalib::GenerationHandler; - - WordStore _wordStore; - uint64_t _numUniqueWords; - GenerationHandler _generationHandler; - DictionaryTree _dict; - PostingListStore _postingListStore; - FeatureStore _featureStore; - uint32_t _fieldId; - FieldIndexRemover _remover; - std::unique_ptr<IOrderedFieldIndexInserter> _inserter; - index::FieldLengthCalculator _calculator; - -public: - datastore::EntryRef addWord(const vespalib::stringref word) { - _numUniqueWords++; - return _wordStore.addWord(word); - } - - datastore::EntryRef addFeatures(const index::DocIdAndFeatures &features) { - return _featureStore.addFeatures(_fieldId, features).first; - } - - FieldIndex(const index::Schema& schema, uint32_t fieldId); - FieldIndex(const index::Schema& schema, uint32_t fieldId, const index::FieldLengthInfo& info); - ~FieldIndex(); - PostingList::Iterator find(const vespalib::stringref word) const; - - PostingList::ConstIterator - findFrozen(const vespalib::stringref word) const; - - uint64_t getNumUniqueWords() const override { return _numUniqueWords; } - const FeatureStore & getFeatureStore() const override { return _featureStore; } - const WordStore &getWordStore() const override { return _wordStore; } - IOrderedFieldIndexInserter &getInserter() override { return *_inserter; } - index::FieldLengthCalculator &get_calculator() override { return _calculator; } + using PostingListKeyDataType = typename PostingListStore::KeyDataType; private: + PostingListStore _postingListStore; + void freeze() { _postingListStore.freeze(); _dict.getAllocator().freeze(); @@ -148,18 +70,19 @@ private: } public: - GenerationHandler::Guard takeGenerationGuard() override { - return _generationHandler.takeGuard(); - } + FieldIndex(const index::Schema& schema, uint32_t fieldId); + FieldIndex(const index::Schema& schema, uint32_t fieldId, const index::FieldLengthInfo& info); + ~FieldIndex(); + + typename PostingList::Iterator find(const vespalib::stringref word) const; + typename PostingList::ConstIterator findFrozen(const vespalib::stringref word) const; void compactFeatures() override; void dump(search::index::IndexBuilder & indexBuilder) override; vespalib::MemoryUsage getMemoryUsage() const override; - DictionaryTree &getDictionaryTree() { return _dict; } PostingListStore &getPostingListStore() { return _postingListStore; } - FieldIndexRemover &getDocumentRemover() override { return _remover; } void commit() override { _remover.flush(); @@ -179,82 +102,82 @@ public: namespace search::btree { extern template -class BTreeNodeDataWrap<memoryindex::FieldIndex::WordKey, +class BTreeNodeDataWrap<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::LEAF_SLOTS>; extern template -class BTreeNodeT<memoryindex::FieldIndex::WordKey, +class BTreeNodeT<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::INTERNAL_SLOTS>; #if 0 extern template -class BTreeNodeT<memoryindex::FieldIndex::WordKey, +class BTreeNodeT<memoryindex::FieldIndexBase::WordKey, BTreeDefaultTraits::LEAF_SLOTS>; #endif extern template -class BTreeNodeTT<memoryindex::FieldIndex::WordKey, +class BTreeNodeTT<memoryindex::FieldIndexBase::WordKey, datastore::EntryRef, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS>; extern template -class BTreeNodeTT<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeTT<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::LEAF_SLOTS>; extern template -class BTreeInternalNode<memoryindex::FieldIndex::WordKey, +class BTreeInternalNode<memoryindex::FieldIndexBase::WordKey, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS>; extern template -class BTreeLeafNode<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeLeafNode<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::LEAF_SLOTS>; extern template -class BTreeNodeStore<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeStore<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS, BTreeDefaultTraits::LEAF_SLOTS>; extern template -class BTreeIterator<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeIterator<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, + const memoryindex::FieldIndexBase::KeyComp, BTreeDefaultTraits>; extern template -class BTree<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTree<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, + const memoryindex::FieldIndexBase::KeyComp, BTreeDefaultTraits>; extern template -class BTreeRoot<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeRoot<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - const memoryindex::FieldIndex::KeyComp, - BTreeDefaultTraits>; + const memoryindex::FieldIndexBase::KeyComp, + BTreeDefaultTraits>; extern template -class BTreeRootBase<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeRootBase<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, BTreeDefaultTraits::INTERNAL_SLOTS, BTreeDefaultTraits::LEAF_SLOTS>; extern template -class BTreeNodeAllocator<memoryindex::FieldIndex::WordKey, - memoryindex::FieldIndex::PostingListPtr, +class BTreeNodeAllocator<memoryindex::FieldIndexBase::WordKey, + memoryindex::FieldIndexBase::PostingListPtr, search::btree::NoAggregated, - BTreeDefaultTraits::INTERNAL_SLOTS, - BTreeDefaultTraits::LEAF_SLOTS>; + BTreeDefaultTraits::INTERNAL_SLOTS, + BTreeDefaultTraits::LEAF_SLOTS>; } diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index_base.cpp b/searchlib/src/vespa/searchlib/memoryindex/field_index_base.cpp new file mode 100644 index 00000000000..ee1fee3d935 --- /dev/null +++ b/searchlib/src/vespa/searchlib/memoryindex/field_index_base.cpp @@ -0,0 +1,36 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include "field_index_base.h" +#include "i_ordered_field_index_inserter.h" +#include <vespa/vespalib/stllike/asciistream.h> + +namespace search::memoryindex { + +vespalib::asciistream & +operator<<(vespalib::asciistream& os, const FieldIndexBase::WordKey& rhs) +{ + os << "wr(" << rhs._wordRef.ref() << ")"; + return os; +} + +FieldIndexBase::FieldIndexBase(const index::Schema& schema, uint32_t fieldId) + : FieldIndexBase(schema, fieldId, index::FieldLengthInfo()) +{ +} + +FieldIndexBase::FieldIndexBase(const index::Schema& schema, uint32_t fieldId, + const index::FieldLengthInfo& info) + : _wordStore(), + _numUniqueWords(0), + _generationHandler(), + _dict(), + _featureStore(schema), + _fieldId(fieldId), + _remover(_wordStore), + _inserter(), + _calculator(info) +{ +} + +} + diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index_base.h b/searchlib/src/vespa/searchlib/memoryindex/field_index_base.h new file mode 100644 index 00000000000..7efec1f2ae8 --- /dev/null +++ b/searchlib/src/vespa/searchlib/memoryindex/field_index_base.h @@ -0,0 +1,119 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#pragma once + +#include "feature_store.h" +#include "field_index_remover.h" +#include "i_field_index.h" +#include "word_store.h" +#include <vespa/searchlib/index/docidandfeatures.h> +#include <vespa/searchlib/index/field_length_calculator.h> +#include <vespa/vespalib/btree/btree.h> +#include <vespa/vespalib/btree/btreenodeallocator.h> +#include <vespa/vespalib/btree/btreeroot.h> +#include <vespa/vespalib/stllike/string.h> +#include <vespa/vespalib/util/memoryusage.h> + +namespace search::memoryindex { + +class IOrderedFieldIndexInserter; + +/** + * Abstract base class for implementation of memory index for a single field. + * + * Contains all components that are not dependent of the posting list format. + */ +class FieldIndexBase : public IFieldIndex { +public: + /** + * Class representing a word used as key in the dictionary. + */ + struct WordKey { + datastore::EntryRef _wordRef; + + explicit WordKey(datastore::EntryRef wordRef) : _wordRef(wordRef) { } + WordKey() : _wordRef() { } + + friend vespalib::asciistream& + operator<<(vespalib::asciistream& os, const WordKey& rhs); + }; + + /** + * Comparator class for words used in the dictionary. + */ + class KeyComp { + private: + const WordStore& _wordStore; + const vespalib::stringref _word; + + const char* getWord(datastore::EntryRef wordRef) const { + if (wordRef.valid()) { + return _wordStore.getWord(wordRef); + } + return _word.data(); + } + + public: + KeyComp(const WordStore& wordStore, const vespalib::stringref word) + : _wordStore(wordStore), + _word(word) + { } + + bool operator()(const WordKey& lhs, const WordKey& rhs) const { + int cmpres = strcmp(getWord(lhs._wordRef), getWord(rhs._wordRef)); + return cmpres < 0; + } + }; + + using PostingListPtr = uint32_t; + using DictionaryTree = btree::BTree<WordKey, PostingListPtr, + search::btree::NoAggregated, + const KeyComp>; + +protected: + using GenerationHandler = vespalib::GenerationHandler; + + WordStore _wordStore; + uint64_t _numUniqueWords; + GenerationHandler _generationHandler; + DictionaryTree _dict; + FeatureStore _featureStore; + uint32_t _fieldId; + FieldIndexRemover _remover; + std::unique_ptr<IOrderedFieldIndexInserter> _inserter; + index::FieldLengthCalculator _calculator; + + void incGeneration() { + _generationHandler.incGeneration(); + } + +public: + datastore::EntryRef addWord(const vespalib::stringref word) { + _numUniqueWords++; + return _wordStore.addWord(word); + } + + datastore::EntryRef addFeatures(const index::DocIdAndFeatures& features) { + return _featureStore.addFeatures(_fieldId, features).first; + } + + FieldIndexBase(const index::Schema& schema, uint32_t fieldId); + FieldIndexBase(const index::Schema& schema, uint32_t fieldId, const index::FieldLengthInfo& info); + + uint64_t getNumUniqueWords() const override { return _numUniqueWords; } + const FeatureStore& getFeatureStore() const override { return _featureStore; } + const WordStore& getWordStore() const override { return _wordStore; } + IOrderedFieldIndexInserter& getInserter() override { return *_inserter; } + index::FieldLengthCalculator& get_calculator() override { return _calculator; } + + GenerationHandler::Guard takeGenerationGuard() override { + return _generationHandler.takeGuard(); + } + + DictionaryTree& getDictionaryTree() { return _dict; } + FieldIndexRemover& getDocumentRemover() override { return _remover; } + +}; + +} + diff --git a/searchlib/src/vespa/searchlib/memoryindex/field_index_collection.cpp b/searchlib/src/vespa/searchlib/memoryindex/field_index_collection.cpp index 40b1e8f360f..dc7d35a755d 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/field_index_collection.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/field_index_collection.cpp @@ -34,7 +34,7 @@ FieldIndexCollection::FieldIndexCollection(const Schema& schema, const IFieldLen { for (uint32_t fieldId = 0; fieldId < _numFields; ++fieldId) { const auto& field = schema.getIndexField(fieldId); - auto fieldIndex = std::make_unique<FieldIndex>(schema, fieldId, inspector.get_field_length_info(field.getName())); + auto fieldIndex = std::make_unique<FieldIndex<false>>(schema, fieldId, inspector.get_field_length_info(field.getName())); _fieldIndexes.push_back(std::move(fieldIndex)); } } diff --git a/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.cpp b/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.cpp index 624ae41b990..c6524a2fc64 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.cpp @@ -27,7 +27,8 @@ const vespalib::string emptyWord = ""; } -OrderedFieldIndexInserter::OrderedFieldIndexInserter(FieldIndex &fieldIndex) +template <bool interleaved_features> +OrderedFieldIndexInserter<interleaved_features>::OrderedFieldIndexInserter(FieldIndexType& fieldIndex) : _word(), _prevDocId(noDocId), _prevAdd(false), @@ -39,10 +40,12 @@ OrderedFieldIndexInserter::OrderedFieldIndexInserter(FieldIndex &fieldIndex) { } -OrderedFieldIndexInserter::~OrderedFieldIndexInserter() = default; +template <bool interleaved_features> +OrderedFieldIndexInserter<interleaved_features>::~OrderedFieldIndexInserter() = default; +template <bool interleaved_features> void -OrderedFieldIndexInserter::flushWord() +OrderedFieldIndexInserter<interleaved_features>::flushWord() { if (_removes.empty() && _adds.empty()) { return; @@ -64,21 +67,24 @@ OrderedFieldIndexInserter::flushWord() _adds.clear(); } +template <bool interleaved_features> void -OrderedFieldIndexInserter::flush() +OrderedFieldIndexInserter<interleaved_features>::flush() { flushWord(); _listener.flush(); } +template <bool interleaved_features> void -OrderedFieldIndexInserter::commit() +OrderedFieldIndexInserter<interleaved_features>::commit() { _fieldIndex.commit(); } +template <bool interleaved_features> void -OrderedFieldIndexInserter::setNextWord(const vespalib::stringref word) +OrderedFieldIndexInserter<interleaved_features>::setNextWord(const vespalib::stringref word) { // TODO: Adjust here if zero length words should be legal. assert(_word < word); @@ -103,9 +109,10 @@ OrderedFieldIndexInserter::setNextWord(const vespalib::stringref word) assert(_word == wordStore.getWord(_dItr.getKey()._wordRef)); } +template <bool interleaved_features> void -OrderedFieldIndexInserter::add(uint32_t docId, - const index::DocIdAndFeatures &features) +OrderedFieldIndexInserter<interleaved_features>::add(uint32_t docId, + const index::DocIdAndFeatures &features) { assert(docId != noDocId); assert(_prevDocId == noDocId || _prevDocId < docId || @@ -117,8 +124,9 @@ OrderedFieldIndexInserter::add(uint32_t docId, _prevAdd = true; } +template <bool interleaved_features> void -OrderedFieldIndexInserter::remove(uint32_t docId) +OrderedFieldIndexInserter<interleaved_features>::remove(uint32_t docId) { assert(docId != noDocId); assert(_prevDocId == noDocId || _prevDocId < docId); @@ -127,8 +135,9 @@ OrderedFieldIndexInserter::remove(uint32_t docId) _prevAdd = false; } +template <bool interleaved_features> void -OrderedFieldIndexInserter::rewind() +OrderedFieldIndexInserter<interleaved_features>::rewind() { assert(_removes.empty() && _adds.empty()); _word = ""; @@ -137,10 +146,14 @@ OrderedFieldIndexInserter::rewind() _dItr.begin(); } +template <bool interleaved_features> datastore::EntryRef -OrderedFieldIndexInserter::getWordRef() const +OrderedFieldIndexInserter<interleaved_features>::getWordRef() const { return _dItr.getKey()._wordRef; } +template +class OrderedFieldIndexInserter<false>; + } diff --git a/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.h b/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.h index 529b1d6d6a7..0e04b126f32 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.h +++ b/searchlib/src/vespa/searchlib/memoryindex/ordered_field_index_inserter.h @@ -18,27 +18,30 @@ class IFieldIndexInsertListener; * and for each word updating the posting list with docId adds / removes. * * Insert order must be properly sorted, first by word, then by docId. + * + * The template parameter specifies whether the posting lists of the field index have interleaved features or not. */ +template <bool interleaved_features> class OrderedFieldIndexInserter : public IOrderedFieldIndexInserter { private: vespalib::stringref _word; uint32_t _prevDocId; bool _prevAdd; - using DictionaryTree = FieldIndex::DictionaryTree; - using PostingListStore = FieldIndex::PostingListStore; - using KeyComp = FieldIndex::KeyComp; - using WordKey = FieldIndex::WordKey; - using PostingListEntryType = FieldIndex::PostingListEntryType; - using PostingListKeyDataType = FieldIndex::PostingListKeyDataType; - FieldIndex &_fieldIndex; - DictionaryTree::Iterator _dItr; + using FieldIndexType = FieldIndex<interleaved_features>; + using DictionaryTree = typename FieldIndexType::DictionaryTree; + using PostingListStore = typename FieldIndexType::PostingListStore; + using KeyComp = typename FieldIndexType::KeyComp; + using WordKey = typename FieldIndexType::WordKey; + using PostingListEntryType = typename FieldIndexType::PostingListEntryType; + using PostingListKeyDataType = typename FieldIndexType::PostingListKeyDataType; + FieldIndexType& _fieldIndex; + typename DictionaryTree::Iterator _dItr; IFieldIndexInsertListener &_listener; // Pending changes to posting list for (_word) std::vector<uint32_t> _removes; std::vector<PostingListKeyDataType> _adds; - static constexpr uint32_t noFieldId = std::numeric_limits<uint32_t>::max(); static constexpr uint32_t noDocId = std::numeric_limits<uint32_t>::max(); @@ -50,7 +53,7 @@ private: void flushWord(); public: - OrderedFieldIndexInserter(FieldIndex &fieldIndex); + OrderedFieldIndexInserter(FieldIndexType& fieldIndex); ~OrderedFieldIndexInserter() override; void setNextWord(const vespalib::stringref word) override; void add(uint32_t docId, const index::DocIdAndFeatures &features) override; diff --git a/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.cpp b/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.cpp index bad3d47b2b9..0e84c2b7968 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.cpp @@ -13,10 +13,11 @@ LOG_SETUP(".searchlib.memoryindex.posting_iterator"); namespace search::memoryindex { -PostingIterator::PostingIterator(FieldIndex::PostingList::ConstIterator itr, - const FeatureStore & featureStore, - uint32_t packedIndex, - const fef::TermFieldMatchDataArray & matchData) : +template <bool interleaved_features> +PostingIterator<interleaved_features>::PostingIterator(PostingListIteratorType itr, + const FeatureStore& featureStore, + uint32_t packedIndex, + const fef::TermFieldMatchDataArray& matchData) : queryeval::RankedSearchIteratorBase(matchData), _itr(itr), _featureStore(featureStore), @@ -25,10 +26,12 @@ PostingIterator::PostingIterator(FieldIndex::PostingList::ConstIterator itr, _featureStore.setupForField(packedIndex, _featureDecoder); } -PostingIterator::~PostingIterator() {} +template <bool interleaved_features> +PostingIterator<interleaved_features>::~PostingIterator() = default; +template <bool interleaved_features> void -PostingIterator::initRange(uint32_t begin, uint32_t end) +PostingIterator<interleaved_features>::initRange(uint32_t begin, uint32_t end) { SearchIterator::initRange(begin, end); _itr.lower_bound(begin); @@ -40,8 +43,9 @@ PostingIterator::initRange(uint32_t begin, uint32_t end) clearUnpacked(); } +template <bool interleaved_features> void -PostingIterator::doSeek(uint32_t docId) +PostingIterator<interleaved_features>::doSeek(uint32_t docId) { if (getUnpacked()) { clearUnpacked(); @@ -54,8 +58,9 @@ PostingIterator::doSeek(uint32_t docId) } } +template <bool interleaved_features> void -PostingIterator::doUnpack(uint32_t docId) +PostingIterator<interleaved_features>::doUnpack(uint32_t docId) { if (!_matchData.valid() || getUnpacked()) { return; @@ -69,6 +74,9 @@ PostingIterator::doUnpack(uint32_t docId) setUnpacked(); } +template +class PostingIterator<false>; + } namespace search::btree { diff --git a/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.h b/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.h index de337ef49f3..f029c837cf7 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.h +++ b/searchlib/src/vespa/searchlib/memoryindex/posting_iterator.h @@ -9,10 +9,15 @@ namespace search::memoryindex { /** * Search iterator for memory field index posting list. + * + * The template parameter specifies whether the wrapped posting list has interleaved features or not. */ +template <bool interleaved_features> class PostingIterator : public queryeval::RankedSearchIteratorBase { private: - FieldIndex::PostingList::ConstIterator _itr; + using FieldIndexType = FieldIndex<interleaved_features>; + using PostingListIteratorType = typename FieldIndexType::PostingList::ConstIterator; + PostingListIteratorType _itr; const FeatureStore &_featureStore; FeatureStore::DecodeContextCooked _featureDecoder; @@ -25,7 +30,7 @@ public: * @param packedIndex the field or field collection owning features. * @param matchData the match data to unpack features into. **/ - PostingIterator(FieldIndex::PostingList::ConstIterator itr, + PostingIterator(PostingListIteratorType itr, const FeatureStore &featureStore, uint32_t packedIndex, const fef::TermFieldMatchDataArray &matchData); diff --git a/searchlib/src/vespa/searchlib/memoryindex/posting_list_entry.h b/searchlib/src/vespa/searchlib/memoryindex/posting_list_entry.h index b3f488d4ed7..373de21e836 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/posting_list_entry.h +++ b/searchlib/src/vespa/searchlib/memoryindex/posting_list_entry.h @@ -9,7 +9,7 @@ namespace search::memoryindex { /** * Entry per document in memory index posting list. */ -template <bool has_interleaved_features> +template <bool interleaved_features> class PostingListEntry { mutable datastore::EntryRef _features; // reference to compressed features diff --git a/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.cpp b/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.cpp index d3d9e5e0bcb..a4996c931e2 100644 --- a/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.cpp +++ b/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.cpp @@ -129,10 +129,10 @@ search::queryeval::SearchIterator * FakeMemTreeOcc:: createIterator(const fef::TermFieldMatchDataArray &matchData) const { - return new search::memoryindex::PostingIterator(_tree.begin(_allocator), - _mgr._featureStore, - _packedIndex, - matchData); + return new search::memoryindex::PostingIterator<false>(_tree.begin(_allocator), + _mgr._featureStore, + _packedIndex, + matchData); } diff --git a/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.h b/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.h index 599d2b37ab2..69114611fe6 100644 --- a/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.h +++ b/searchlib/src/vespa/searchlib/test/fakedata/fakememtreeocc.h @@ -13,8 +13,9 @@ namespace search::fakedata { class FakeMemTreeOccMgr : public FakeWord::RandomizedWriter { public: - using Tree = memoryindex::FieldIndex::PostingList; - using PostingListEntryType = memoryindex::FieldIndex::PostingListEntryType; + // TODO: Create implementation for "interleaved features" posting list as well. + using Tree = memoryindex::FieldIndex<false>::PostingList; + using PostingListEntryType = memoryindex::FieldIndex<false>::PostingListEntryType; using NodeAllocator = Tree::NodeAllocatorType; using FeatureStore = memoryindex::FeatureStore; using EntryRef = datastore::EntryRef; diff --git a/searchlib/src/vespa/searchlib/test/memoryindex/wrap_inserter.h b/searchlib/src/vespa/searchlib/test/memoryindex/wrap_inserter.h index 647f624daea..268bf834d21 100644 --- a/searchlib/src/vespa/searchlib/test/memoryindex/wrap_inserter.h +++ b/searchlib/src/vespa/searchlib/test/memoryindex/wrap_inserter.h @@ -20,7 +20,7 @@ public: { } - WrapInserter(FieldIndex& field_index) + WrapInserter(IFieldIndex& field_index) : _inserter(field_index.getInserter()) { } |