// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once #include "multistringpostattribute.h" #include "multi_string_enum_search_context.h" #include "string_direct_posting_store_adapter.hpp" #include #include namespace search { template MultiValueStringPostingAttributeT::MultiValueStringPostingAttributeT(const vespalib::string & name, const AttributeVector::Config & c) : MultiValueStringAttributeT(name, c), PostingParent(*this, this->getEnumStore()), _posting_store_adapter(this->get_posting_store(), this->_enumStore, this->getIsFilter()) { } template MultiValueStringPostingAttributeT::MultiValueStringPostingAttributeT(const vespalib::string & name) : MultiValueStringPostingAttributeT(name, AttributeVector::Config(AttributeVector::BasicType::STRING, attribute::CollectionType::ARRAY)) { } template MultiValueStringPostingAttributeT::~MultiValueStringPostingAttributeT() { this->disableFreeLists(); this->disable_entry_hold_list(); clearAllPostings(); } class StringEnumIndexMapper : public EnumIndexMapper { public: StringEnumIndexMapper(IEnumStoreDictionary & dictionary) : _dictionary(dictionary) { } IEnumStore::Index map(IEnumStore::Index original) const override; bool hasFold() const override { return true; } private: IEnumStoreDictionary& _dictionary; }; template void MultiValueStringPostingAttributeT:: applyValueChanges(const DocIndices& docIndices, EnumStoreBatchUpdater &updater) { using PostingChangeComputer = PostingChangeComputerT; EnumStore &enumStore(this->getEnumStore()); IEnumStoreDictionary& dictionary(enumStore.get_dictionary()); StringEnumIndexMapper mapper(dictionary); PostingMap changePost(PostingChangeComputer::compute(this->getMultiValueMapping(), docIndices, enumStore.get_folded_comparator(), mapper)); this->updatePostings(changePost); MultiValueStringAttributeT::applyValueChanges(docIndices, updater); } template void MultiValueStringPostingAttributeT::freezeEnumDictionary() { this->getEnumStore().freeze_dictionary(); } template void MultiValueStringPostingAttributeT::mergeMemoryStats(vespalib::MemoryUsage &total) { auto& compaction_strategy = this->getConfig().getCompactionStrategy(); total.merge(this->_posting_store.update_stat(compaction_strategy)); } template void MultiValueStringPostingAttributeT::reclaim_memory(generation_t oldest_used_gen) { MultiValueStringAttributeT::reclaim_memory(oldest_used_gen); _posting_store.reclaim_memory(oldest_used_gen); } template void MultiValueStringPostingAttributeT::before_inc_generation(generation_t current_gen) { _posting_store.freeze(); MultiValueStringAttributeT::before_inc_generation(current_gen); _posting_store.assign_generation(current_gen); } template std::unique_ptr MultiValueStringPostingAttributeT::getSearch(QueryTermSimpleUP qTerm, const attribute::SearchContextParams & params) const { using BaseSC = attribute::MultiStringEnumSearchContext; using SC = attribute::StringPostingSearchContext; bool cased = this->get_match_is_cased(); auto doc_id_limit = this->getCommittedDocIdLimit(); BaseSC base_sc(std::move(qTerm), cased, params.fuzzy_matching_algorithm(), *this, this->_mvMapping.make_read_view(doc_id_limit), this->_enumStore); return std::make_unique(std::move(base_sc), params.useBitVector(), *this); } template const IDocidWithWeightPostingStore* MultiValueStringPostingAttributeT::as_docid_with_weight_posting_store() const { if (this->isStringType()) { return &_posting_store_adapter; } return nullptr; } }