diff --git a/core/formats/columnstore2.cpp b/core/formats/columnstore2.cpp index 828f4afc0..00bf5a116 100644 --- a/core/formats/columnstore2.cpp +++ b/core/formats/columnstore2.cpp @@ -381,21 +381,22 @@ class column_base : public column_reader, private util::noncopyable { column_header& mutable_header() { return hdr_; } void reset_stream(const index_input* stream) { stream_ = stream; } - bool allocate_buffered_memory(size_t size, size_t mappings) { - if (!resource_manager_cached_.Increase(size + mappings)) { - auto column_name = name(); - if (irs::IsNull(column_name)) { - column_name = ""; - } - IRS_LOG_WARN( - absl::StrCat("Failed to allocate memory for buffered column id ", - header().id, " name: ", column_name, " of size ", size)); - return false; - } + + bool allocate_buffered_memory(size_t size, size_t mappings) noexcept try { + resource_manager_cached_.Increase(size + mappings); // should be only one alllocation IRS_ASSERT(column_data_.empty()); column_data_.resize(size); return true; + } catch (...) { + auto column_name = name(); + if (irs::IsNull(column_name)) { + column_name = ""; + } + IRS_LOG_WARN( + absl::StrCat("Failed to allocate memory for buffered column id ", + header().id, " name: ", column_name, " of size ", size)); + return false; } size_t calculate_bitmap_size(size_t file_len, @@ -619,9 +620,9 @@ struct mask_column : public column_base { const index_input& data_in, compression::decompressor::ptr&& /*inflater*/, encryption::stream* cipher) { - return memory::make_tracked_managed( - rm_r, std::move(name), rm_c, std::move(payload), std::move(hdr), - std::move(index), data_in, cipher); + return memory::make_tracked(rm_r, std::move(name), rm_c, + std::move(payload), std::move(hdr), + std::move(index), data_in, cipher); } mask_column(std::optional&& name, IResourceManager& rm_c, @@ -753,7 +754,7 @@ column_ptr dense_fixed_length_column::read( compression::decompressor::ptr&& inflater, encryption::stream* cipher) { const uint64_t len = index_in.read_long(); const uint64_t data = index_in.read_long(); - return memory::make_tracked_managed( + return memory::make_tracked( rm_r, std::move(name), rm_c, std::move(payload), std::move(hdr), std::move(index), data_in, std::move(inflater), cipher, data, len); } @@ -787,7 +788,7 @@ doc_iterator::ptr dense_fixed_length_column::iterator(ColumnHint hint) const { class fixed_length_column : public column_base { public: - using Blocks = std::vector>; + using Blocks = ManagedVector; static column_ptr read(std::optional&& name, IResourceManager& rm_r, IResourceManager& rm_c, @@ -798,7 +799,7 @@ class fixed_length_column : public column_base { encryption::stream* cipher) { const uint64_t len = index_in.read_long(); auto blocks = read_blocks_dense(hdr, index_in, rm_r); - return memory::make_tracked_managed( + return memory::make_tracked( rm_r, std::move(name), rm_c, std::move(payload), std::move(hdr), std::move(index), data_in, std::move(inflater), cipher, std::move(blocks), len); @@ -997,18 +998,19 @@ class sparse_column : public column_base { compression::decompressor::ptr&& inflater, encryption::stream* cipher) { auto blocks = read_blocks_sparse(hdr, index_in, rm_r); - return memory::make_tracked_managed( + return memory::make_tracked( rm_r, std::move(name), rm_c, std::move(payload), std::move(hdr), std::move(index), data_in, std::move(inflater), cipher, std::move(blocks)); } - sparse_column( - std::optional&& name, IResourceManager& resource_manager, - bstring&& payload, column_header&& hdr, column_index&& index, - const index_input& data_in, compression::decompressor::ptr&& inflater, - encryption::stream* cipher, - std::vector>&& blocks) + sparse_column(std::optional&& name, + IResourceManager& resource_manager, bstring&& payload, + column_header&& hdr, column_index&& index, + const index_input& data_in, + compression::decompressor::ptr&& inflater, + encryption::stream* cipher, + ManagedVector&& blocks) : column_base{std::move(name), resource_manager, std::move(payload), std::move(hdr), std::move(index), data_in, cipher}, @@ -1053,9 +1055,9 @@ class sparse_column : public column_base { } private: - static std::vector> - read_blocks_sparse(const column_header& hdr, index_input& in, - IResourceManager& resource_manager); + static ManagedVector read_blocks_sparse( + const column_header& hdr, index_input& in, + IResourceManager& resource_manager); template class payload_reader : private ValueReader { @@ -1072,8 +1074,7 @@ class sparse_column : public column_base { template bool make_buffered_data( - column_header& hdr, index_input& in, - std::vector>& blocks, + column_header& hdr, index_input& in, ManagedVector& blocks, std::vector& column_data, std::span> next_sorted_columns, remapped_bytes_view_input::mapping* mapping) { @@ -1167,7 +1168,7 @@ class sparse_column : public column_base { return true; } - std::vector> blocks_; + ManagedVector blocks_; compression::decompressor::ptr inflater_; }; diff --git a/core/formats/columnstore2.hpp b/core/formats/columnstore2.hpp index 125de1f58..fc790e160 100644 --- a/core/formats/columnstore2.hpp +++ b/core/formats/columnstore2.hpp @@ -155,8 +155,7 @@ class column final : public irs::column_output { irs::type_info compression_; compression::compressor::ptr deflater_; columnstore_writer::column_finalizer_f finalizer_; - std::vector> - blocks_; // at most 65536 blocks + ManagedVector blocks_; // at most 65536 blocks memory_output data_; memory_output docs_; sparse_bitmap_writer docs_writer_{docs_.stream, ctx_.version}; diff --git a/core/formats/formats.hpp b/core/formats/formats.hpp index ee580e0d5..4a63fbb77 100644 --- a/core/formats/formats.hpp +++ b/core/formats/formats.hpp @@ -62,7 +62,7 @@ using DocumentMask = absl::container_internal::hash_default_hash, absl::container_internal::hash_default_eq, ManagedTypedAllocator>; -using DocMap = std::vector>; +using DocMap = ManagedVector; using DocMapView = std::span; using callback_f = std::function; @@ -76,7 +76,7 @@ struct WanderatorOptions { struct SegmentWriterOptions { const ColumnInfoProvider& column_info; const FeatureInfoProvider& feature_info; - const std::set& scorers_features; + const feature_set_t& scorers_features; ScorersView scorers; const Comparer* const comparator{}; IResourceManager& resource_manager{IResourceManager::kNoop}; @@ -124,9 +124,8 @@ struct postings_writer { virtual ~postings_writer() = default; // out - corresponding terms stream virtual void prepare(index_output& out, const flush_state& state) = 0; - virtual void begin_field( - IndexFeatures index_features, - const std::map& features) = 0; + virtual void begin_field(IndexFeatures index_features, + const feature_map_t& features) = 0; virtual state write(doc_iterator& docs) = 0; virtual void begin_block() = 0; virtual void encode(data_output& out, const term_meta& state) = 0; @@ -485,7 +484,7 @@ struct flush_state { const DocMap* docmap{}; const ColumnProvider* columns{}; // Accumulated segment features - const std::set* features{}; + const feature_set_t* features{}; // Segment name const std::string_view name; // segment name ScorersView scorers; diff --git a/core/formats/formats_burst_trie.cpp b/core/formats/formats_burst_trie.cpp index a8ee24bb5..3b1f3644a 100644 --- a/core/formats/formats_burst_trie.cpp +++ b/core/formats/formats_burst_trie.cpp @@ -870,7 +870,7 @@ const fst::FstReadOptions& fst_read_options() { // mininum size of string weight we store in FST [[maybe_unused]] constexpr const size_t MIN_WEIGHT_SIZE = 2; -using Blocks = std::vector>; +using Blocks = ManagedVector; void MergeBlocks(Blocks& blocks, OutputBuffer& buffer) { IRS_ASSERT(!blocks.empty()); @@ -1028,7 +1028,7 @@ class field_writer final : public irs::field_writer { encryption::stream::ptr index_out_cipher_; index_output::ptr index_out_; // output stream for indexes postings_writer::ptr pw_; // postings writer - std::vector> stack_; + ManagedVector stack_; fst_buffer* fst_buf_; // pimpl buffer used for building FST for fields volatile_byte_ref last_term_; // last pushed term std::vector prefixes_; diff --git a/core/formats/skip_list.hpp b/core/formats/skip_list.hpp index 00386d805..a19a67520 100644 --- a/core/formats/skip_list.hpp +++ b/core/formats/skip_list.hpp @@ -82,7 +82,7 @@ class SkipWriter : util::noncopyable { void Skip(doc_id_t count, Writer&& write); protected: - std::vector> levels_; + ManagedVector levels_; size_t max_levels_; doc_id_t skip_0_; // skip interval for 0 level doc_id_t skip_n_; // skip interval for 1..n levels diff --git a/core/index/buffered_column.hpp b/core/index/buffered_column.hpp index 7ef8538ba..f16695013 100644 --- a/core/index/buffered_column.hpp +++ b/core/index/buffered_column.hpp @@ -44,8 +44,7 @@ struct BufferedValue { class BufferedColumn final : public column_output, private util::noncopyable { public: - using BufferedValues = - std::vector>; + using BufferedValues = ManagedVector; using Buffer = irs::basic_string>; explicit BufferedColumn(const ColumnInfo& info, IResourceManager& rm) diff --git a/core/index/field_meta.hpp b/core/index/field_meta.hpp index 86fa87e32..3516f5742 100644 --- a/core/index/field_meta.hpp +++ b/core/index/field_meta.hpp @@ -42,10 +42,6 @@ struct field_stats { uint32_t num_unique{}; }; -using feature_map_t = std::map; -using feature_set_t = std::set; -using features_t = std::span; - // Represents field metadata struct field_meta { public: diff --git a/core/index/index_features.hpp b/core/index/index_features.hpp index 2791131f2..4af59810d 100644 --- a/core/index/index_features.hpp +++ b/core/index/index_features.hpp @@ -23,6 +23,8 @@ #pragma once #include +#include +#include #include #include "index/column_info.hpp" @@ -81,4 +83,8 @@ using FeatureInfoProvider = std::function( type_info::type_id)>; +using feature_map_t = std::map; +using feature_set_t = std::set; +using features_t = std::span; + } // namespace irs diff --git a/core/index/index_writer.cpp b/core/index/index_writer.cpp index 17438f1f4..13c6e6037 100644 --- a/core/index/index_writer.cpp +++ b/core/index/index_writer.cpp @@ -199,13 +199,13 @@ void RemoveFromExistingSegment(DocumentMask& deleted_docs, return; } - auto prepared = query.filter->prepare(reader); + auto prepared = query.filter->prepare({.index = reader}); if (IRS_UNLIKELY(!prepared)) { return; // skip invalid prepared filters } - auto itr = prepared->execute(reader); + auto itr = prepared->execute({.segment = reader}); if (IRS_UNLIKELY(!itr)) { return; // skip invalid iterators @@ -232,12 +232,12 @@ bool RemoveFromImportedSegment(DocumentMask& deleted_docs, return false; } - auto prepared = query.filter->prepare(reader); + auto prepared = query.filter->prepare({.index = reader}); if (IRS_UNLIKELY(!prepared)) { return false; // skip invalid prepared filters } - auto itr = prepared->execute(reader); + auto itr = prepared->execute({.segment = reader}); if (IRS_UNLIKELY(!itr)) { return false; // skip invalid iterators } @@ -270,13 +270,13 @@ void FlushedSegmentContext::Remove(IndexWriter::QueryContext& query) { auto& document_mask = flushed.document_mask; - auto prepared = query.filter->prepare(*reader); + auto prepared = query.filter->prepare({.index = *reader}); if (IRS_UNLIKELY(!prepared)) { return; // Skip invalid prepared filters } - auto itr = prepared->execute(*reader); + auto itr = prepared->execute({.segment = *reader}); if (IRS_UNLIKELY(!itr)) { return; // Skip invalid iterators diff --git a/core/index/index_writer.hpp b/core/index/index_writer.hpp index 9d0eaf9e9..c78681665 100644 --- a/core/index/index_writer.hpp +++ b/core/index/index_writer.hpp @@ -678,16 +678,14 @@ class IndexWriter : private util::noncopyable { RefTrackingDirectory dir_; // sequential list of pending modification - std::vector> queries_; + ManagedVector queries_; // all of the previously flushed versions of this segment - std::vector> flushed_; + ManagedVector flushed_; // update_contexts to use with 'flushed_' // sequentially increasing through all offsets // (sequential doc_id in 'flushed_' == offset + doc_limits::min(), size() // == sum of all 'flushed_'.'docs_count') - std::vector> - flushed_docs_; + ManagedVector flushed_docs_; // function to get new SegmentMeta from segment_meta_generator_t meta_generator_; diff --git a/core/index/merge_writer.cpp b/core/index/merge_writer.cpp index 79e0021d3..7d4e2a322 100644 --- a/core/index/merge_writer.cpp +++ b/core/index/merge_writer.cpp @@ -69,7 +69,7 @@ void AccumulateFeatures(feature_set_t& accum, const feature_map_t& features) { // mapping of old doc_id to new doc_id (reader doc_ids are sequential 0 based) // masked doc_ids have value of MASKED_DOC_ID -using doc_id_map_t = std::vector>; +using doc_id_map_t = ManagedVector; // document mapping function using doc_map_f = std::function; diff --git a/core/index/merge_writer.hpp b/core/index/merge_writer.hpp index 4b84c3d03..9e31077a9 100644 --- a/core/index/merge_writer.hpp +++ b/core/index/merge_writer.hpp @@ -46,9 +46,8 @@ class MergeWriter : public util::noncopyable { ReaderCtx(const SubReader& reader, IResourceManager& rm) noexcept : ReaderCtx{&reader, rm} {} - const SubReader* reader; // segment reader - std::vector> - doc_id_map; // FIXME use bitpacking vector + const SubReader* reader; // segment reader + ManagedVector doc_id_map; // FIXME use bitpacking vector std::function doc_map; // mapping function }; @@ -98,11 +97,11 @@ class MergeWriter : public util::noncopyable { const FlushProgress& progress); directory& dir_; - std::vector> readers_; + ManagedVector readers_; const ColumnInfoProvider* column_info_{}; const FeatureInfoProvider* feature_info_{}; ScorersView scorers_; - const std::set* scorers_features_{}; + const feature_set_t* scorers_features_{}; const Comparer* const comparator_{}; }; diff --git a/core/index/segment_writer.hpp b/core/index/segment_writer.hpp index 03acf23f4..6a89f0b2b 100644 --- a/core/index/segment_writer.hpp +++ b/core/index/segment_writer.hpp @@ -384,7 +384,7 @@ class segment_writer : public ColumnProvider, util::noncopyable { cached_columns_; // pointers remain valid absl::flat_hash_map column_ids_; sorted_column sort_; - std::vector> docs_context_; + ManagedVector docs_context_; // invalid/removed doc_ids (e.g. partially indexed due to indexing failure) DocsMask docs_mask_; fields_data fields_; diff --git a/core/resource_manager.hpp b/core/resource_manager.hpp index 840774b5a..9d0364669 100644 --- a/core/resource_manager.hpp +++ b/core/resource_manager.hpp @@ -22,10 +22,13 @@ #pragma once +#include + #include "shared.hpp" #include "utils/managed_allocator.hpp" namespace irs { + struct IResourceManager { static IResourceManager kNoop; #ifdef IRESEARCH_DEBUG @@ -38,10 +41,9 @@ struct IResourceManager { IResourceManager(const IResourceManager&) = delete; IResourceManager operator=(const IResourceManager&) = delete; - virtual bool Increase([[maybe_unused]] size_t v) noexcept { + virtual void Increase([[maybe_unused]] size_t v) { IRS_ASSERT(this != &kForbidden); IRS_ASSERT(v != 0); - return true; } virtual void Decrease([[maybe_unused]] size_t v) noexcept { @@ -82,4 +84,7 @@ struct ManagedTypedAllocator using Base::Base; }; +template +using ManagedVector = std::vector>; + } // namespace irs diff --git a/core/search/all_filter.cpp b/core/search/all_filter.cpp index 42f85e090..16c5287ca 100644 --- a/core/search/all_filter.cpp +++ b/core/search/all_filter.cpp @@ -47,19 +47,17 @@ class all_query : public filter::prepared { bstring stats_; }; -filter::prepared::ptr all::prepare(const IndexReader& reader, - const Scorers& order, score_t filter_boost, - const attribute_provider* /*ctx*/) const { +filter::prepared::ptr all::prepare(const PrepareContext& ctx) const { // skip field-level/term-level statistics because there are no explicit // fields/terms, but still collect index-level statistics // i.e. all fields and terms implicitly match - bstring stats(order.stats_size(), 0); + bstring stats(ctx.scorers.stats_size(), 0); auto* stats_buf = stats.data(); - PrepareCollectors(order.buckets(), stats_buf); + PrepareCollectors(ctx.scorers.buckets(), stats_buf); - return memory::make_managed(std::move(stats), - this->boost() * filter_boost); + return memory::make_tracked(ctx.memory, std::move(stats), + ctx.boost * boost()); } } // namespace irs diff --git a/core/search/all_filter.hpp b/core/search/all_filter.hpp index f5ed75baa..e39e15222 100644 --- a/core/search/all_filter.hpp +++ b/core/search/all_filter.hpp @@ -29,11 +29,7 @@ namespace irs { // Filter returning all documents class all : public filter { public: - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& reader, const Scorers& order, - score_t filter_boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; irs::type_info::type_id type() const noexcept final { return irs::type::id(); diff --git a/core/search/bm25.cpp b/core/search/bm25.cpp index f8e6125b7..4e0bc7f12 100644 --- a/core/search/bm25.cpp +++ b/core/search/bm25.cpp @@ -486,7 +486,7 @@ ScoreFunction BM25::prepare_scorer(const ColumnProvider& segment, MakeBM25NormAdapter([]() { return 1U; })); } -void BM25::get_features(std::set& features) const { +void BM25::get_features(feature_set_t& features) const { if (NeedsNorm()) { features.emplace(irs::type::id()); } diff --git a/core/search/bm25.hpp b/core/search/bm25.hpp index baece76be..c6a9b8c8a 100644 --- a/core/search/bm25.hpp +++ b/core/search/bm25.hpp @@ -78,15 +78,15 @@ class BM25 final : public irs::ScorerBase { return IndexFeatures::FREQ; } - void get_features(std::set& features) const final; + void get_features(feature_set_t& features) const final; FieldCollector::ptr prepare_field_collector() const final; - ScoreFunction prepare_scorer( - const ColumnProvider& segment, - const std::map& features, - const byte_type* query_stats, const attribute_provider& doc_attrs, - score_t boost) const final; + ScoreFunction prepare_scorer(const ColumnProvider& segment, + const feature_map_t& features, + const byte_type* query_stats, + const attribute_provider& doc_attrs, + score_t boost) const final; WandWriter::ptr prepare_wand_writer(size_t max_levels) const final; diff --git a/core/search/boolean_filter.cpp b/core/search/boolean_filter.cpp index 8760a9716..18956a2d2 100644 --- a/core/search/boolean_filter.cpp +++ b/core/search/boolean_filter.cpp @@ -145,7 +145,7 @@ namespace irs { // Base class for boolean queries class BooleanQuery : public filter::prepared { public: - using queries_t = std::vector; + using queries_t = ManagedVector; using iterator = queries_t::const_iterator; BooleanQuery() noexcept : excl_{0} {} @@ -193,27 +193,28 @@ class BooleanQuery : public filter::prepared { } } - virtual void prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, ScoreMergeType merge_type, - const attribute_provider* ctx, - std::span incl, - std::span excl) { - BooleanQuery::queries_t queries; + void prepare(const PrepareContext& ctx, ScoreMergeType merge_type, + std::span incl, + std::span excl) { + BooleanQuery::queries_t queries{{ctx.memory}}; queries.reserve(incl.size() + excl.size()); // apply boost to the current node - this->boost(boost); + this->boost(ctx.boost); // prepare included for (const auto* filter : incl) { - queries.emplace_back(filter->prepare(rdr, ord, boost, ctx)); + queries.emplace_back(filter->prepare(ctx)); } // prepare excluded for (const auto* filter : excl) { // exclusion part does not affect scoring at all - queries.emplace_back( - filter->prepare(rdr, Scorers::kUnordered, irs::kNoBoost, ctx)); + queries.emplace_back(filter->prepare({ + .index = ctx.index, + .memory = ctx.memory, + .ctx = ctx.ctx, + })); } // nothrow block @@ -334,9 +335,7 @@ bool boolean_filter::equals(const filter& rhs) const noexcept { }); } -filter::prepared::ptr boolean_filter::prepare( - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr boolean_filter::prepare(const PrepareContext& ctx) const { const auto size = filters_.size(); if (IRS_UNLIKELY(size == 0)) { @@ -349,7 +348,7 @@ filter::prepared::ptr boolean_filter::prepare( // FIXME(gnusi): let Not handle everything? if (filter->type() != irs::type::id()) { - return filter->prepare(rdr, ord, boost * this->boost(), ctx); + return filter->prepare(ctx.Boost(boost())); } } @@ -368,7 +367,7 @@ filter::prepared::ptr boolean_filter::prepare( incl.push_back(all_docs_no_boost.get()); } - return prepare(incl, excl, rdr, ord, boost, ctx); + return PrepareBoolean(incl, excl, ctx); } void boolean_filter::group_filters(filter::ptr& all_docs_zero_boost, @@ -419,11 +418,9 @@ void boolean_filter::group_filters(filter::ptr& all_docs_zero_boost, } } -filter::prepared::ptr And::prepare(std::vector& incl, - std::vector& excl, - const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr And::PrepareBoolean(std::vector& incl, + std::vector& excl, + const PrepareContext& ctx) const { // optimization step // if include group empty itself or has 'empty' -> this whole conjunction is // empty @@ -431,9 +428,12 @@ filter::prepared::ptr And::prepare(std::vector& incl, return prepared::empty(); } + PrepareContext sub_ctx = ctx; + // single node case if (1 == incl.size() && excl.empty()) { - return incl.front()->prepare(rdr, ord, this->boost() * boost, ctx); + sub_ctx.boost *= boost(); + return incl.front()->prepare(sub_ctx); } auto cumulative_all = MakeAllDocsFilter(kNoBoost); @@ -467,12 +467,12 @@ filter::prepared::ptr And::prepare(std::vector& incl, // substitute new_boost back we will get ( boost * OR_BOOST * ALL_BOOST + // boost * OR_BOOST * LEFT_BOOST) - original non-optimized boost value auto left_boost = (*incl.begin())->boost(); - if (this->boost() != 0 && left_boost != 0 && !ord.empty()) { - boost = (boost * this->boost() * all_boost + - boost * this->boost() * left_boost) / - (left_boost * this->boost()); + if (boost() != 0 && left_boost != 0 && !sub_ctx.scorers.empty()) { + sub_ctx.boost = (sub_ctx.boost * boost() * all_boost + + sub_ctx.boost * boost() * left_boost) / + (left_boost * boost()); } else { - boost = 0; + sub_ctx.boost = 0; } } else { // create new 'all' with boost from all removed @@ -480,38 +480,33 @@ filter::prepared::ptr And::prepare(std::vector& incl, incl.push_back(cumulative_all.get()); } } - boost *= this->boost(); + sub_ctx.boost *= this->boost(); if (1 == incl.size() && excl.empty()) { // single node case - return incl.front()->prepare(rdr, ord, boost, ctx); + return incl.front()->prepare(sub_ctx); } - auto q = memory::make_managed(); - q->prepare(rdr, ord, boost, merge_type(), ctx, incl, excl); + auto q = memory::make_tracked(sub_ctx.memory); + q->prepare(sub_ctx, merge_type(), incl, excl); return q; } -filter::prepared::ptr Or::prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr Or::prepare(const PrepareContext& ctx) const { if (0 == min_match_count_) { // only explicit 0 min match counts! // all conditions are satisfied - return MakeAllDocsFilter(kNoBoost)->prepare(rdr, ord, this->boost() * boost, - ctx); + return MakeAllDocsFilter(kNoBoost)->prepare(ctx.Boost(boost())); } - return boolean_filter::prepare(rdr, ord, boost, ctx); + return boolean_filter::prepare(ctx); } -filter::prepared::ptr Or::prepare(std::vector& incl, - std::vector& excl, - const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const { - boost *= this->boost(); +filter::prepared::ptr Or::PrepareBoolean(std::vector& incl, + std::vector& excl, + const PrepareContext& ctx) const { + const PrepareContext sub_ctx = ctx.Boost(boost()); if (0 == min_match_count_) { // only explicit 0 min match counts! // all conditions are satisfied - return MakeAllDocsFilter(kNoBoost)->prepare(rdr, ord, boost, ctx); + return MakeAllDocsFilter(kNoBoost)->prepare(sub_ctx); } if (!incl.empty() && incl.back()->type() == irs::type::id()) { @@ -524,7 +519,7 @@ filter::prepared::ptr Or::prepare(std::vector& incl, // single node case if (1 == incl.size() && excl.empty()) { - return incl.front()->prepare(rdr, ord, boost, ctx); + return incl.front()->prepare(sub_ctx); } auto cumulative_all = MakeAllDocsFilter(kNoBoost); @@ -542,7 +537,8 @@ filter::prepared::ptr Or::prepare(std::vector& incl, } } if (all_count != 0) { - if (ord.empty() && incl.size() > 1 && min_match_count_ <= all_count) { + if (sub_ctx.scorers.empty() && incl.size() > 1 && + min_match_count_ <= all_count) { // if we have at least one all in include group - all other filters are // not necessary in case there is no scoring and 'all' count satisfies // min_match @@ -566,12 +562,11 @@ filter::prepared::ptr Or::prepare(std::vector& incl, // check strictly less to not roll back to 0 min_match (we`ve handled this // case above!) single 'all' left -> it could contain boost we want to // preserve - const auto adjusted_min_match_count = - (optimized_match_count < min_match_count_) - ? min_match_count_ - optimized_match_count - : 1; + const auto adjusted_min_match = (optimized_match_count < min_match_count_) + ? min_match_count_ - optimized_match_count + : 1; - if (adjusted_min_match_count > incl.size()) { + if (adjusted_min_match > incl.size()) { // can't satisfy 'min_match_count' conditions // having only 'incl.size()' queries return prepared::empty(); @@ -579,48 +574,45 @@ filter::prepared::ptr Or::prepare(std::vector& incl, if (1 == incl.size() && excl.empty()) { // single node case - return incl.front()->prepare(rdr, ord, boost, ctx); + return incl.front()->prepare(sub_ctx); } - IRS_ASSERT(adjusted_min_match_count > 0 && - adjusted_min_match_count <= incl.size()); + IRS_ASSERT(adjusted_min_match > 0 && adjusted_min_match <= incl.size()); memory::managed_ptr q; - if (adjusted_min_match_count == incl.size()) { - q = memory::make_managed(); - } else if (1 == adjusted_min_match_count) { - q = memory::make_managed(); + if (adjusted_min_match == incl.size()) { + q = memory::make_tracked(sub_ctx.memory); + } else if (1 == adjusted_min_match) { + q = memory::make_tracked(sub_ctx.memory); } else { // min_match_count > 1 && min_match_count < incl.size() - q = memory::make_managed(adjusted_min_match_count); + q = memory::make_tracked(sub_ctx.memory, adjusted_min_match); } - q->prepare(rdr, ord, boost, merge_type(), ctx, incl, excl); + q->prepare(sub_ctx, merge_type(), incl, excl); return q; } -filter::prepared::ptr Not::prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr Not::prepare(const PrepareContext& ctx) const { const auto res = optimize_not(*this); if (!res.first) { return prepared::empty(); } - boost *= this->boost(); + const PrepareContext sub_ctx = ctx.Boost(boost()); if (res.second) { auto all_docs = MakeAllDocsFilter(kNoBoost); const std::array incl{all_docs.get()}; const std::array excl{res.first}; - auto q = memory::make_managed(); - q->prepare(rdr, ord, boost, ScoreMergeType::kSum, ctx, incl, excl); + auto q = memory::make_tracked(sub_ctx.memory); + q->prepare(sub_ctx, ScoreMergeType::kSum, incl, excl); return q; } // negation has been optimized out - return res.first->prepare(rdr, ord, boost, ctx); + return res.first->prepare(sub_ctx); } size_t Not::hash() const noexcept { diff --git a/core/search/boolean_filter.hpp b/core/search/boolean_filter.hpp index cdf15ed3f..349bfd14c 100644 --- a/core/search/boolean_filter.hpp +++ b/core/search/boolean_filter.hpp @@ -61,17 +61,14 @@ class boolean_filter : public filter, public AllDocsProvider { bool empty() const { return filters_.empty(); } size_t size() const { return filters_.size(); } - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const override; + filter::prepared::ptr prepare(const PrepareContext& ctx) const override; protected: bool equals(const filter& rhs) const noexcept final; - virtual filter::prepared::ptr prepare( + virtual filter::prepared::ptr PrepareBoolean( std::vector& incl, std::vector& excl, - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const = 0; + const PrepareContext& ctx) const = 0; private: void group_filters(filter::ptr& all_docs_no_boost, @@ -85,18 +82,14 @@ class boolean_filter : public filter, public AllDocsProvider { // Represents conjunction class And final : public boolean_filter { public: - using filter::prepare; - type_info::type_id type() const noexcept final { return irs::type::id(); } protected: - filter::prepared::ptr prepare(std::vector& incl, - std::vector& excl, - const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr PrepareBoolean(std::vector& incl, + std::vector& excl, + const PrepareContext& ctx) const final; }; // Represents disjunction @@ -111,19 +104,14 @@ class Or final : public boolean_filter { return *this; } - using filter::prepare; - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; type_info::type_id type() const noexcept final { return irs::type::id(); } protected: - filter::prepared::ptr prepare(std::vector& incl, - std::vector& excl, - const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr PrepareBoolean(std::vector& incl, + std::vector& excl, + const PrepareContext& ctx) const final; private: size_t min_match_count_{1}; @@ -154,11 +142,7 @@ class Not : public filter, public AllDocsProvider { void clear() { filter_.reset(); } bool empty() const { return nullptr == filter_; } - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; size_t hash() const noexcept final; diff --git a/core/search/boost_scorer.cpp b/core/search/boost_scorer.cpp index 1c763a796..7af24b539 100644 --- a/core/search/boost_scorer.cpp +++ b/core/search/boost_scorer.cpp @@ -41,11 +41,11 @@ struct volatile_boost_score_ctx final : score_ctx { }; } // namespace -ScoreFunction BoostScore::prepare_scorer( - const ColumnProvider& /*segment*/, - const std::map& /*features*/, - const byte_type* /*stats*/, const attribute_provider& attrs, - score_t boost) const { +ScoreFunction BoostScore::prepare_scorer(const ColumnProvider& /*segment*/, + const feature_map_t& /*features*/, + const byte_type* /*stats*/, + const attribute_provider& attrs, + score_t boost) const { const auto* volatile_boost = irs::get(attrs); if (volatile_boost == nullptr) { diff --git a/core/search/boost_scorer.hpp b/core/search/boost_scorer.hpp index 8a89f349a..6e86f454b 100644 --- a/core/search/boost_scorer.hpp +++ b/core/search/boost_scorer.hpp @@ -33,11 +33,11 @@ struct BoostScore final : ScorerBase { static void init(); - ScoreFunction prepare_scorer( - const ColumnProvider& /*segment*/, - const std::map& /*features*/, - const byte_type* /*stats*/, const attribute_provider& attrs, - score_t boost) const final; + ScoreFunction prepare_scorer(const ColumnProvider& /*segment*/, + const feature_map_t& /*features*/, + const byte_type* /*stats*/, + const attribute_provider& attrs, + score_t boost) const final; IndexFeatures index_features() const noexcept final { return IndexFeatures::NONE; diff --git a/core/search/column_existence_filter.cpp b/core/search/column_existence_filter.cpp index 1ee633abf..33b763f80 100644 --- a/core/search/column_existence_filter.cpp +++ b/core/search/column_existence_filter.cpp @@ -25,10 +25,9 @@ #include "formats/empty_term_reader.hpp" #include "search/disjunction.hpp" +namespace irs { namespace { -using namespace irs; - class column_existence_query : public irs::filter::prepared { public: column_existence_query(std::string_view field, bstring&& stats, score_t boost) @@ -128,27 +127,25 @@ class column_prefix_existence_query : public column_existence_query { } // namespace -namespace irs { - filter::prepared::ptr by_column_existence::prepare( - const IndexReader& reader, const Scorers& order, score_t filter_boost, - const attribute_provider* /*ctx*/) const { + const PrepareContext& ctx) const { // skip field-level/term-level statistics because there are no explicit // fields/terms, but still collect index-level statistics // i.e. all fields and terms implicitly match - bstring stats(order.stats_size(), 0); + bstring stats(ctx.scorers.stats_size(), 0); auto* stats_buf = stats.data(); - PrepareCollectors(order.buckets(), stats_buf); + PrepareCollectors(ctx.scorers.buckets(), stats_buf); - filter_boost *= boost(); + const auto filter_boost = ctx.boost * boost(); auto& acceptor = options().acceptor; - return acceptor ? memory::make_managed( - field(), std::move(stats), acceptor, filter_boost) - : memory::make_managed( - field(), std::move(stats), filter_boost); + return acceptor + ? memory::make_tracked( + ctx.memory, field(), std::move(stats), acceptor, filter_boost) + : memory::make_tracked( + ctx.memory, field(), std::move(stats), filter_boost); } } // namespace irs diff --git a/core/search/column_existence_filter.hpp b/core/search/column_existence_filter.hpp index 5f289d141..d2882ec36 100644 --- a/core/search/column_existence_filter.hpp +++ b/core/search/column_existence_filter.hpp @@ -49,11 +49,7 @@ struct by_column_existence_options { class by_column_existence final : public filter_base { public: - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; }; } // namespace irs diff --git a/core/search/filter.cpp b/core/search/filter.cpp index e7db6777e..5803458c2 100644 --- a/core/search/filter.cpp +++ b/core/search/filter.cpp @@ -47,8 +47,7 @@ filter::prepared::ptr filter::prepared::empty() { return memory::to_managed(kEmptyQuery); } -filter::prepared::ptr empty::prepare(const IndexReader&, const Scorers&, - score_t, const attribute_provider*) const { +filter::prepared::ptr empty::prepare(const PrepareContext& /*ctx*/) const { return memory::to_managed(kEmptyQuery); } diff --git a/core/search/filter.hpp b/core/search/filter.hpp index 66097c725..38b439902 100644 --- a/core/search/filter.hpp +++ b/core/search/filter.hpp @@ -35,10 +35,25 @@ namespace irs { struct IndexReader; struct PreparedStateVisitor; +struct PrepareContext { + const IndexReader& index; + IResourceManager& memory = IResourceManager::kNoop; + const Scorers& scorers = Scorers::kUnordered; + const attribute_provider* ctx = nullptr; + score_t boost = kNoBoost; + + PrepareContext Boost(score_t boost) const noexcept { + auto ctx = *this; + ctx.boost *= boost; + return ctx; + } +}; + struct ExecutionContext { const SubReader& segment; - const Scorers& scorers; - const attribute_provider* ctx{}; + IResourceManager& memory = IResourceManager::kNoop; + const Scorers& scorers = Scorers::kUnordered; + const attribute_provider* ctx = nullptr; // If enabled, wand would use first scorer from scorers WandContext wand; }; @@ -55,12 +70,6 @@ class filter { explicit prepared(score_t boost = kNoBoost) noexcept : boost_(boost) {} - doc_iterator::ptr execute( - const SubReader& segment, - const Scorers& scorers = Scorers::kUnordered) const { - return execute({.segment = segment, .scorers = scorers}); - } - virtual doc_iterator::ptr execute(const ExecutionContext& ctx) const = 0; virtual void visit(const SubReader& segment, PreparedStateVisitor& visitor, @@ -85,29 +94,7 @@ class filter { bool operator==(const filter& rhs) const noexcept { return equals(rhs); } - // boost - external boost - virtual filter::prepared::ptr prepare( - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const = 0; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - const attribute_provider* ctx) const { - return prepare(rdr, ord, irs::kNoBoost, ctx); - } - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost) const { - return prepare(rdr, ord, boost, nullptr); - } - - filter::prepared::ptr prepare(const IndexReader& rdr, - const Scorers& ord) const { - return prepare(rdr, ord, irs::kNoBoost); - } - - filter::prepared::ptr prepare(const IndexReader& rdr) const { - return prepare(rdr, Scorers::kUnordered); - } + virtual filter::prepared::ptr prepare(const PrepareContext& ctx) const = 0; score_t boost() const noexcept { return boost_; } @@ -186,9 +173,7 @@ class filter_base : public filter_with_options { // Filter which returns no documents class empty final : public filter { public: - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; type_info::type_id type() const noexcept final { return irs::type::id(); diff --git a/core/search/granular_range_filter.cpp b/core/search/granular_range_filter.cpp index f1581c5f6..7533acd8d 100644 --- a/core/search/granular_range_filter.cpp +++ b/core/search/granular_range_filter.cpp @@ -34,6 +34,7 @@ #include "search/range_filter.hpp" #include "search/term_filter.hpp" +namespace irs { namespace { // Example term structure, in order of term iteration/comparison, N = 4: @@ -49,27 +50,26 @@ namespace { // max_term (with e.g. N=3)-/ // Return the granularity portion of the term -irs::bytes_view mask_granularity(irs::bytes_view term, - size_t prefix_size) noexcept { - return term.size() > prefix_size ? irs::bytes_view{term.data(), prefix_size} +bytes_view mask_granularity(bytes_view term, size_t prefix_size) noexcept { + return term.size() > prefix_size ? bytes_view{term.data(), prefix_size} : term; } // Return the value portion of the term -irs::bytes_view mask_value(irs::bytes_view term, size_t prefix_size) noexcept { - if (irs::IsNull(term)) { +bytes_view mask_value(bytes_view term, size_t prefix_size) noexcept { + if (IsNull(term)) { return term; } - return term.size() > prefix_size ? irs::bytes_view{term.data() + prefix_size, - term.size() - prefix_size} - : irs::bytes_view{}; + return term.size() > prefix_size + ? bytes_view{term.data() + prefix_size, term.size() - prefix_size} + : bytes_view{}; } // Collect terms while they are accepted by Comparer template -void collect_terms(const irs::SubReader& segment, const irs::term_reader& field, - irs::seek_term_iterator& terms, Visitor& visitor, +void collect_terms(const SubReader& segment, const term_reader& field, + seek_term_iterator& terms, Visitor& visitor, const Comparer& cmp) { terms.read(); // read attributes (needed for cookie()) visitor.prepare(segment, field, terms); @@ -81,7 +81,7 @@ void collect_terms(const irs::SubReader& segment, const irs::term_reader& field, break; // terminate traversal } - visitor.visit(irs::kNoBoost); + visitor.visit(kNoBoost); } while (terms.next()); } @@ -90,32 +90,31 @@ void collect_terms(const irs::SubReader& segment, const irs::term_reader& field, // [null == current .. max), (min .. null == end of granularity range] template void collect_terms_between( - const irs::SubReader& segment, const irs::term_reader& field, - irs::seek_term_iterator& terms, size_t prefix_size, - irs::bytes_view begin_term, - irs::bytes_view end_term, // granularity level for end_term is ingored - // during comparison - bool include_begin_term, // should begin_term also be included - bool include_end_term, /* should end_term also be included*/ + const SubReader& segment, const term_reader& field, seek_term_iterator& terms, + size_t prefix_size, bytes_view begin_term, + bytes_view end_term, // granularity level for end_term is ingored + // during comparison + bool include_begin_term, // should begin_term also be included + bool include_end_term, /* should end_term also be included*/ Visitor& visitor) { - irs::bstring tmp; - irs::bytes_view masked_begin_level; + bstring tmp; + bytes_view masked_begin_level; // seek to start of term range for collection - if (!irs::IsNull(begin_term)) { + if (!IsNull(begin_term)) { const auto res = terms.seek_ge(begin_term); // seek to start - if (irs::SeekResult::END == res) { + if (SeekResult::END == res) { return; // have reached the end of terms in segment } - if (irs::SeekResult::FOUND == res) { + if (SeekResult::FOUND == res) { if (!include_begin_term) { if (!terms.next()) { return; // skipped current term and no more terms in segment } } else if (!include_end_term && - !irs::IsNull(end_term) // (begin .. end of granularity range] + !IsNull(end_term) // (begin .. end of granularity range] && !(mask_value(begin_term, prefix_size) < mask_value(end_term, prefix_size))) { // don't use '==' since it @@ -130,7 +129,7 @@ void collect_terms_between( return; // skipped current term and no more terms in segment } else { // need a copy as the original reference may be changed - tmp = static_cast(terms.value()); + tmp = static_cast(terms.value()); // the starting range granularity level masked_begin_level = mask_granularity(tmp, prefix_size); } @@ -141,7 +140,7 @@ void collect_terms_between( collect_terms( segment, field, terms, visitor, [&prefix_size, masked_begin_level, masked_end_term, - include_end_term](const irs::term_iterator& itr) -> bool { + include_end_term](const term_iterator& itr) -> bool { const auto& value = itr.value(); const auto masked_current_level = mask_granularity(value, prefix_size); const auto masked_current_term = mask_value(value, prefix_size); @@ -151,8 +150,7 @@ void collect_terms_between( // or granularity level boundary passed or term already covered by a // less-granular range return masked_current_level == masked_begin_level && - (irs::IsNull( - masked_end_term) // (begin .. end of granularity range] + (IsNull(masked_end_term) // (begin .. end of granularity range] || (include_end_term && masked_current_term <= masked_end_term) // (being .. end] || (!include_end_term && @@ -162,19 +160,18 @@ void collect_terms_between( // collect all terms starting from the min_term granularity range template -void collect_terms_from( - const irs::SubReader& segment, const irs::term_reader& field, - irs::seek_term_iterator& terms, size_t prefix_size, - const irs::by_granular_range::options_type::terms& min_term, - bool min_term_inclusive, Visitor& visitor) { +void collect_terms_from(const SubReader& segment, const term_reader& field, + seek_term_iterator& terms, size_t prefix_size, + const by_granular_range::options_type::terms& min_term, + bool min_term_inclusive, Visitor& visitor) { auto min_term_itr = min_term.rbegin(); // start with least granular // for the case where there is no min_term, include remaining range at the // current granularity level if (min_term_itr == min_term.rend()) { collect_terms_between(segment, field, terms, prefix_size, - irs::bytes_view{}, // collect full granularity range - irs::bytes_view{}, // collect full granularity range + bytes_view{}, // collect full granularity range + bytes_view{}, // collect full granularity range true, true, visitor); return; // done @@ -191,8 +188,8 @@ void collect_terms_from( // masked next term is < masked current term) collect_terms_between( segment, field, terms, prefix_size, - *min_term_itr, // the min term for the current granularity level - irs::bytes_view{}, // collect full granularity range + *min_term_itr, // the min term for the current granularity level + bytes_view{}, // collect full granularity range min_term_inclusive && exact_min_term == &(*min_term_itr), true, // add min_term if requested visitor); @@ -209,25 +206,25 @@ void collect_terms_from( // seek to the same term at a lower granularity level than current level auto res = terms.seek_ge(*min_term_itr); - if (irs::SeekResult::END == res) { + if (SeekResult::END == res) { continue; } auto end_term = - (irs::SeekResult::NOT_FOUND == res || - (irs::SeekResult::FOUND == res && terms.next())) // have next term + (SeekResult::NOT_FOUND == res || + (SeekResult::FOUND == res && terms.next())) // have next term && mask_granularity(terms.value(), prefix_size) == mask_granularity(*min_term_itr, prefix_size) // on same level ? terms.value() - : irs::bytes_view{}; - irs::bstring end_term_copy; + : bytes_view{}; + bstring end_term_copy; auto is_most_granular_term = exact_min_term == &(*current_min_term_itr); // need a copy of the term since bytes_view changes on terms.seek(...) - if (!irs::IsNull(end_term)) { + if (!IsNull(end_term)) { end_term_copy.assign(end_term.data(), end_term.size()); - end_term = irs::bytes_view(end_term_copy); + end_term = bytes_view(end_term_copy); } collect_terms_between( @@ -236,9 +233,8 @@ void collect_terms_from( // level end_term, // the min term for the previous lesser granularity level min_term_inclusive && is_most_granular_term, // add min_term if requested - irs::IsNull(end_term) && - is_most_granular_term, // add end term if required - // (for most granular) + IsNull(end_term) && is_most_granular_term, // add end term if required + // (for most granular) visitor); } } @@ -246,19 +242,18 @@ void collect_terms_from( // Collect terms only starting from the current granularity level and ending // with granularity range, include/exclude end term template -void collect_terms_until( - const irs::SubReader& segment, const irs::term_reader& field, - irs::seek_term_iterator& terms, size_t prefix_size, - const irs::by_granular_range::options_type::terms& max_term, - bool max_term_inclusive, Visitor& visitor) { +void collect_terms_until(const SubReader& segment, const term_reader& field, + seek_term_iterator& terms, size_t prefix_size, + const by_granular_range::options_type::terms& max_term, + bool max_term_inclusive, Visitor& visitor) { auto max_term_itr = max_term.rbegin(); // start with least granular // for the case where there is no max_term, remaining range at the current // granularity level if (max_term_itr == max_term.rend()) { collect_terms_between(segment, field, terms, prefix_size, - irs::bytes_view{}, // collect full granularity range - irs::bytes_view{}, // collect full granularity range + bytes_view{}, // collect full granularity range + bytes_view{}, // collect full granularity range true, true, visitor); return; // done @@ -288,8 +283,8 @@ void collect_terms_until( // advance by one and collect all terms excluding the current max_term collect_terms_between( segment, field, terms, prefix_size, - irs::bytes_view{}, // collect full granularity range - *max_term_itr, // the max term for the current granularity level + bytes_view{}, // collect full granularity range + *max_term_itr, // the max term for the current granularity level true, max_term_inclusive && exact_max_term == &(*max_term_itr), // add max_term if requested @@ -300,7 +295,7 @@ void collect_terms_until( // collect the remaining more-granular ranges of the min_term // ........................................................................... - irs::bstring tmp_term; + bstring tmp_term; // advance by one and collect all terms excluding the current max_term, repeat // for all remaining granularity levels @@ -331,10 +326,9 @@ void collect_terms_until( // granularity range template void collect_terms_within( - const irs::SubReader& segment, const irs::term_reader& field, - irs::seek_term_iterator& terms, size_t prefix_size, - const irs::by_granular_range::options_type::terms& min_term, - const irs::by_granular_range::options_type::terms& max_term, + const SubReader& segment, const term_reader& field, seek_term_iterator& terms, + size_t prefix_size, const by_granular_range::options_type::terms& min_term, + const by_granular_range::options_type::terms& max_term, bool min_term_inclusive, bool max_term_inclusive, Visitor& visitor) { auto min_term_itr = min_term.rbegin(); // start with least granular @@ -418,10 +412,9 @@ void collect_terms_within( collect_terms_between( segment, field, terms, prefix_size, *min_term_itr, // the min term for the current granularity level - max_term.empty() - ? irs::bytes_view{} - : irs::bytes_view(*max_term_itr), // collect up to max term at same - // granularity range + max_term.empty() ? bytes_view{} + : bytes_view(*max_term_itr), // collect up to max term at + // same granularity range min_term_inclusive && exact_min_term == &(*min_term_itr), false, // add min_term if requested, end_term already covered by a // less-granular range @@ -438,24 +431,24 @@ void collect_terms_within( ++current_min_term_itr != end; ++min_term_itr) { auto res = terms.seek_ge(*min_term_itr); - if (irs::SeekResult::END == res) { + if (SeekResult::END == res) { continue; } auto end_term = - (irs::SeekResult::NOT_FOUND == res || - (irs::SeekResult::FOUND == res && terms.next())) // have next term + (SeekResult::NOT_FOUND == res || + (SeekResult::FOUND == res && terms.next())) // have next term && mask_granularity(terms.value(), prefix_size) == mask_granularity(*min_term_itr, prefix_size) // on same level ? terms.value() - : irs::bytes_view{}; - irs::bstring end_term_copy; + : bytes_view{}; + bstring end_term_copy; // need a copy of the term since bytes_view changes on terms.seek(...) - if (!irs::IsNull(end_term)) { + if (!IsNull(end_term)) { end_term_copy.assign(end_term.data(), end_term.size()); - end_term = irs::bytes_view(end_term_copy); + end_term = bytes_view(end_term_copy); } collect_terms_between( @@ -484,25 +477,25 @@ void collect_terms_within( } template -void visit(const irs::SubReader& segment, const irs::term_reader& reader, - const irs::by_granular_range::options_type::range_type& rng, - Visitor& visitor) { - auto terms = reader.iterator(irs::SeekMode::NORMAL); +void VisitImpl(const SubReader& segment, const term_reader& reader, + const by_granular_range::options_type::range_type& rng, + Visitor& visitor) { + auto terms = reader.iterator(SeekMode::NORMAL); if (IRS_UNLIKELY(!terms) || !terms->next()) { return; // no terms to collect } const size_t prefix_size = - reader.meta().features.count(irs::type::id()); + reader.meta().features.count(type::id()); - IRS_ASSERT(!rng.min.empty() || irs::BoundType::UNBOUNDED == rng.min_type); - IRS_ASSERT(!rng.max.empty() || irs::BoundType::UNBOUNDED == rng.max_type); + IRS_ASSERT(!rng.min.empty() || BoundType::UNBOUNDED == rng.min_type); + IRS_ASSERT(!rng.max.empty() || BoundType::UNBOUNDED == rng.max_type); if (rng.min.empty()) { // open min range if (rng.max.empty()) { // open max range // collect all terms - static const irs::by_granular_range::options_type::terms empty; + static const by_granular_range::options_type::terms empty; collect_terms_from(segment, reader, *terms, prefix_size, empty, true, visitor); return; @@ -511,13 +504,13 @@ void visit(const irs::SubReader& segment, const irs::term_reader& reader, auto& max_term = *rng.max.rbegin(); // smallest least granular term - const irs::bytes_view smallest_term{max_term.c_str(), - std::min(max_term.size(), prefix_size)}; + const bytes_view smallest_term{max_term.c_str(), + std::min(max_term.size(), prefix_size)}; // collect terms ending with max granularity range, include/exclude max term - if (irs::SeekResult::END != terms->seek_ge(smallest_term)) { + if (SeekResult::END != terms->seek_ge(smallest_term)) { collect_terms_until(segment, reader, *terms, prefix_size, rng.max, - irs::BoundType::INCLUSIVE == rng.max_type, visitor); + BoundType::INCLUSIVE == rng.max_type, visitor); } return; @@ -527,22 +520,20 @@ void visit(const irs::SubReader& segment, const irs::term_reader& reader, // collect terms starting with min granularity range, include/exclude min // term collect_terms_from(segment, reader, *terms, prefix_size, rng.min, - irs::BoundType::INCLUSIVE == rng.min_type, visitor); + BoundType::INCLUSIVE == rng.min_type, visitor); return; } // collect terms starting with min granularity range and ending with max // granularity range, include/exclude min/max term collect_terms_within(segment, reader, *terms, prefix_size, rng.min, rng.max, - irs::BoundType::INCLUSIVE == rng.min_type, - irs::BoundType::INCLUSIVE == rng.max_type, visitor); + BoundType::INCLUSIVE == rng.min_type, + BoundType::INCLUSIVE == rng.max_type, visitor); } } // namespace -namespace irs { - -// Sequential 'granularity_level' value, cannot use 'irs::increment' since +// Sequential 'granularity_level' value, cannot use 'increment' since // it can be 0 void set_granular_term(by_granular_range_options::terms& boundary, numeric_token_stream& term) { @@ -555,9 +546,8 @@ void set_granular_term(by_granular_range_options::terms& boundary, } filter::prepared::ptr by_granular_range::prepare( - const IndexReader& index, const Scorers& ord, score_t boost, - std::string_view field, const options_type::range_type& rng, - size_t scored_terms_limit) { + const PrepareContext& ctx, std::string_view field, + const options_type::range_type& rng, size_t scored_terms_limit) { if (!rng.min.empty() && !rng.max.empty()) { const auto& min = rng.min.front(); const auto& max = rng.max.front(); @@ -566,7 +556,7 @@ filter::prepared::ptr by_granular_range::prepare( if (rng.min_type == rng.max_type && rng.min_type == BoundType::INCLUSIVE) { // degenerated case - return by_term::prepare(index, ord, boost, field, min); + return by_term::prepare(ctx, field, min); } // can't satisfy condition @@ -576,12 +566,12 @@ filter::prepared::ptr by_granular_range::prepare( // object for collecting order stats limited_sample_collector collector{ - ord.empty() ? 0 : scored_terms_limit}; - MultiTermQuery::States states{index.size()}; + ctx.scorers.empty() ? 0 : scored_terms_limit}; + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; multiterm_visitor mtv{collector, states}; // iterate over the segments - for (const auto& segment : index) { + for (const auto& segment : ctx.index) { // get term dictionary for field const term_reader* reader = segment.field(field); @@ -589,18 +579,18 @@ filter::prepared::ptr by_granular_range::prepare( continue; // no such field in this reader } - ::visit(segment, *reader, rng, mtv); + VisitImpl(segment, *reader, rng, mtv); } if (states.empty()) { return prepared::empty(); } - MultiTermQuery::Stats stats; - collector.score(index, ord, stats); + MultiTermQuery::Stats stats{{ctx.memory}}; + collector.score(ctx.index, ctx.scorers, stats); - return memory::make_managed(std::move(states), - std::move(stats), boost, + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost, ScoreMergeType::kSum, size_t{1}); } @@ -608,7 +598,7 @@ void by_granular_range::visit(const SubReader& segment, const term_reader& reader, const options_type::range_type& rng, filter_visitor& visitor) { - ::visit(segment, reader, rng, visitor); + VisitImpl(segment, reader, rng, visitor); } } // namespace irs diff --git a/core/search/granular_range_filter.hpp b/core/search/granular_range_filter.hpp index c6cfef17e..82aa863af 100644 --- a/core/search/granular_range_filter.hpp +++ b/core/search/granular_range_filter.hpp @@ -97,8 +97,7 @@ void set_granular_term(by_granular_range_options::terms& boundary, ////////////////////////////////////////////////////////////////////////////// class by_granular_range : public filter_base { public: - static filter::prepared::ptr prepare(const IndexReader& index, - const Scorers& ord, score_t boost, + static filter::prepared::ptr prepare(const PrepareContext& ctx, std::string_view field, const options_type::range_type& rng, size_t scored_terms_limit); @@ -107,12 +106,8 @@ class by_granular_range : public filter_base { const options_type::range_type& rng, filter_visitor& visitor); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(index, ord, this->boost() * boost, field(), options().range, + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { + return prepare(ctx.Boost(boost()), field(), options().range, options().scored_terms_limit); } }; diff --git a/core/search/levenshtein_filter.cpp b/core/search/levenshtein_filter.cpp index 4ed6848e1..24e2198d8 100644 --- a/core/search/levenshtein_filter.cpp +++ b/core/search/levenshtein_filter.cpp @@ -38,18 +38,16 @@ #include "utils/std.hpp" #include "utils/utf8_utils.hpp" +namespace irs { namespace { -using namespace irs; - //////////////////////////////////////////////////////////////////////////////// /// @returns levenshtein similarity //////////////////////////////////////////////////////////////////////////////// IRS_FORCE_INLINE score_t similarity(uint32_t distance, uint32_t size) noexcept { IRS_ASSERT(size); - static_assert(sizeof(score_t) == sizeof(uint32_t), - "sizeof(score_t) != sizeof(uint32_t)"); + static_assert(sizeof(score_t) == sizeof(uint32_t)); return 1.f - score_t(distance) / size; } @@ -134,9 +132,9 @@ class top_terms_collector /// @param visitor visitor ////////////////////////////////////////////////////////////////////////////// template -void visit(const SubReader& segment, const term_reader& reader, - const byte_type no_distance, const uint32_t utf8_target_size, - automaton_table_matcher& matcher, Visitor&& visitor) { +void VisitImpl(const SubReader& segment, const term_reader& reader, + const byte_type no_distance, const uint32_t utf8_target_size, + automaton_table_matcher& matcher, Visitor&& visitor) { IRS_ASSERT(fst::kError != matcher.Properties(0)); auto terms = reader.iterator(matcher); @@ -160,7 +158,7 @@ void visit(const SubReader& segment, const term_reader& reader, const auto utf8_value_size = static_cast(utf8_utils::utf8_length(terms->value())); const auto boost = - ::similarity(*distance, std::min(utf8_value_size, utf8_target_size)); + similarity(*distance, std::min(utf8_value_size, utf8_target_size)); visitor.visit(boost); } while (terms->next()); @@ -184,37 +182,33 @@ bool collect_terms(const IndexReader& index, std::string_view field, const byte_type max_distance = d.max_distance() + 1; for (auto& segment : index) { - auto* reader = segment.field(field); - - if (!reader) { - continue; + if (auto* reader = segment.field(field); reader) { + VisitImpl(segment, *reader, max_distance, utf8_term_size, matcher, + collector); } - - visit(segment, *reader, max_distance, utf8_term_size, matcher, collector); } return true; } filter::prepared::ptr prepare_levenshtein_filter( - const IndexReader& index, const Scorers& order, score_t boost, - std::string_view field, bytes_view prefix, bytes_view term, - size_t terms_limit, const parametric_description& d) { - field_collectors field_stats(order); - term_collectors term_stats(order, 1); - MultiTermQuery::States states{index.size()}; + const PrepareContext& ctx, std::string_view field, bytes_view prefix, + bytes_view term, size_t terms_limit, const parametric_description& d) { + field_collectors field_stats{ctx.scorers}; + term_collectors term_stats{ctx.scorers, 1}; + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; if (!terms_limit) { all_terms_collector term_collector{states, field_stats, term_stats}; term_collector.stat_index(0); // aggregate stats from different terms - if (!collect_terms(index, field, prefix, term, d, term_collector)) { + if (!collect_terms(ctx.index, field, prefix, term, d, term_collector)) { return filter::prepared::empty(); } } else { top_terms_collector term_collector(terms_limit, field_stats); - if (!collect_terms(index, field, prefix, term, d, term_collector)) { + if (!collect_terms(ctx.index, field, prefix, term, d, term_collector)) { return filter::prepared::empty(); } @@ -225,20 +219,19 @@ filter::prepared::ptr prepare_levenshtein_filter( }); } - std::vector stats(1); - stats.back().resize(order.stats_size(), 0); + MultiTermQuery::Stats stats( + 1, MultiTermQuery::Stats::allocator_type{ctx.memory}); + stats.back().resize(ctx.scorers.stats_size(), 0); auto* stats_buf = stats[0].data(); - term_stats.finish(stats_buf, 0, field_stats, index); + term_stats.finish(stats_buf, 0, field_stats, ctx.index); - return memory::make_managed(std::move(states), - std::move(stats), boost, + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost, ScoreMergeType::kMax, size_t{1}); } } // namespace -namespace irs { - field_visitor by_edit_distance::visitor( const options_type::filter_options& opts) { return executeLevenshtein( @@ -281,37 +274,35 @@ field_visitor by_edit_distance::visitor( return [ctx = std::move(ctx), utf8_term_size, max_distance]( const SubReader& segment, const term_reader& field, filter_visitor& visitor) mutable { - return ::visit(segment, field, max_distance, utf8_term_size, - ctx->matcher, visitor); + return VisitImpl(segment, field, max_distance, utf8_term_size, + ctx->matcher, visitor); }; }); } filter::prepared::ptr by_edit_distance::prepare( - const IndexReader& index, const Scorers& order, score_t boost, - std::string_view field, bytes_view term, size_t scored_terms_limit, - byte_type max_distance, options_type::pdp_f provider, - bool with_transpositions, bytes_view prefix) { + const PrepareContext& ctx, std::string_view field, bytes_view term, + size_t scored_terms_limit, byte_type max_distance, + options_type::pdp_f provider, bool with_transpositions, bytes_view prefix) { return executeLevenshtein( max_distance, provider, with_transpositions, prefix, term, []() -> filter::prepared::ptr { return prepared::empty(); }, - [&index, &order, boost, &field, &prefix, &term]() -> filter::prepared::ptr { + [&]() -> filter::prepared::ptr { if (!prefix.empty() && !term.empty()) { bstring target; target.reserve(prefix.size() + term.size()); target += prefix; target += term; - return by_term::prepare(index, order, boost, field, target); + return by_term::prepare(ctx, field, target); } - return by_term::prepare(index, order, boost, field, - prefix.empty() ? term : prefix); + return by_term::prepare(ctx, field, prefix.empty() ? term : prefix); }, - [&field, scored_terms_limit, &index, &order, boost]( - const parametric_description& d, const bytes_view prefix, - const bytes_view term) -> filter::prepared::ptr { - return prepare_levenshtein_filter(index, order, boost, field, prefix, - term, scored_terms_limit, d); + [&, scored_terms_limit](const parametric_description& d, + const bytes_view prefix, + const bytes_view term) -> filter::prepared::ptr { + return prepare_levenshtein_filter(ctx, field, prefix, term, + scored_terms_limit, d); }); } diff --git a/core/search/levenshtein_filter.hpp b/core/search/levenshtein_filter.hpp index 97da4bb49..85758ec35 100644 --- a/core/search/levenshtein_filter.hpp +++ b/core/search/levenshtein_filter.hpp @@ -110,24 +110,20 @@ class by_edit_distance final : public filter_base { public: static ptr make(); - static prepared::ptr prepare(const IndexReader& index, const Scorers& order, - score_t boost, std::string_view field, - bytes_view term, size_t terms_limit, - byte_type max_distance, + static prepared::ptr prepare(const PrepareContext& ctx, + std::string_view field, bytes_view term, + size_t terms_limit, byte_type max_distance, options_type::pdp_f provider, bool with_transpositions, bytes_view prefix); static field_visitor visitor(const options_type::filter_options& options); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& order, - score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(index, order, this->boost() * boost, field(), options().term, - options().max_terms, options().max_distance, - options().provider, options().with_transpositions, - options().prefix); + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { + auto sub_ctx = ctx; + sub_ctx.boost *= boost(); + return prepare(sub_ctx, field(), options().term, options().max_terms, + options().max_distance, options().provider, + options().with_transpositions, options().prefix); } }; diff --git a/core/search/limited_sample_collector.hpp b/core/search/limited_sample_collector.hpp index e2c174d42..76d2d026d 100644 --- a/core/search/limited_sample_collector.hpp +++ b/core/search/limited_sample_collector.hpp @@ -120,7 +120,7 @@ class limited_sample_collector : private util::noncopyable { // Finish collecting and evaluate stats void score(const IndexReader& index, const Scorers& order, - std::vector& stats) { + MultiTermQuery::Stats& stats) { if (!scored_terms_limit_) { return; // nothing to score (optimization) } diff --git a/core/search/multiterm_query.hpp b/core/search/multiterm_query.hpp index 40869c8ac..91eb30df4 100644 --- a/core/search/multiterm_query.hpp +++ b/core/search/multiterm_query.hpp @@ -32,7 +32,8 @@ namespace irs { class MultiTermQuery : public filter::prepared { public: using States = StatesCache; - using Stats = std::vector; + // TODO(MBkkt) block_pool + using Stats = ManagedVector; explicit MultiTermQuery(States&& states, Stats&& stats, score_t boost, ScoreMergeType merge_type, size_t min_match) diff --git a/core/search/nested_filter.cpp b/core/search/nested_filter.cpp index 9efb1b3f9..43a7ca971 100644 --- a/core/search/nested_filter.cpp +++ b/core/search/nested_filter.cpp @@ -597,7 +597,6 @@ class ByNestedQuery : public filter::prepared { IRS_ASSERT(IsValid(match_)); } - using filter::prepared::execute; doc_iterator::ptr execute(const ExecutionContext& ctx) const final; void visit(const SubReader& segment, PreparedStateVisitor& visitor, @@ -688,26 +687,30 @@ doc_iterator::ptr ByNestedQuery::execute(const ExecutionContext& ctx) const { }); } -filter::prepared::ptr ByNestedFilter::prepare( - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr ByNestedFilter::prepare(const PrepareContext& ctx) const { auto& [parent, child, match, merge_type] = options(); if (!parent || !child || !IsValid(match)) { return prepared::empty(); } - boost *= this->boost(); + const auto sub_boost = ctx.boost * boost(); - auto prepared_child = child->prepare(rdr, GetOrder(match, ord), boost, ctx); + auto prepared_child = child->prepare({ + .index = ctx.index, + .memory = ctx.memory, + .scorers = GetOrder(match, ctx.scorers), + .ctx = ctx.ctx, + .boost = sub_boost, + }); if (!prepared_child) { return prepared::empty(); } - return memory::make_managed(parent, std::move(prepared_child), - merge_type, match, - /*none_boost*/ boost); + return memory::make_tracked( + ctx.memory, parent, std::move(prepared_child), merge_type, match, + /*none_boost*/ sub_boost); } } // namespace irs diff --git a/core/search/nested_filter.hpp b/core/search/nested_filter.hpp index d4627b0c4..a793b5366 100644 --- a/core/search/nested_filter.hpp +++ b/core/search/nested_filter.hpp @@ -109,10 +109,7 @@ struct ByNestedOptions { // Filter is capable of finding parents by the corresponding child filter. class ByNestedFilter final : public filter_with_options { public: - using filter::prepare; - - prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* /*ctx*/) const final; + prepared::ptr prepare(const PrepareContext& ctx) const final; }; } // namespace irs diff --git a/core/search/ngram_similarity_filter.cpp b/core/search/ngram_similarity_filter.cpp index 69d0a651b..b3740e651 100644 --- a/core/search/ngram_similarity_filter.cpp +++ b/core/search/ngram_similarity_filter.cpp @@ -32,8 +32,7 @@ namespace irs { filter::prepared::ptr by_ngram_similarity::prepare( - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const { + const PrepareContext& ctx) const { const auto& ngrams = options().ngrams; if (ngrams.empty() || field().empty()) { @@ -45,33 +44,35 @@ filter::prepared::ptr by_ngram_similarity::prepare( const auto min_match_count = std::clamp(static_cast(std::ceil(ngrams.size() * threshold)), size_t{1}, ngrams.size()); - - if (ord.empty() && 1 == min_match_count) { + const auto sub_boost = ctx.boost * boost(); + if (ctx.scorers.empty() && 1 == min_match_count) { irs::by_terms disj; for (auto& terms = disj.mutable_options()->terms; auto& term : options().ngrams) { terms.emplace(term, irs::kNoBoost); } *disj.mutable_field() = this->field(); - disj.boost(this->boost()); - return disj.prepare(rdr, irs::Scorers::kUnordered, boost, ctx); + return disj.prepare({ + .index = ctx.index, + .memory = ctx.memory, + .ctx = ctx.ctx, + .boost = sub_boost, + }); } - // TODO(MBkkt) ord.empty() && ngrams.size() == min_match_count, conjunction? - - NGramStates query_states{rdr.size()}; + NGramStates query_states{ctx.memory, ctx.index.size()}; // per segment terms states const auto terms_count = ngrams.size(); - std::vector term_states; + ManagedVector term_states{{ctx.memory}}; term_states.reserve(terms_count); // prepare ngrams stats - field_collectors field_stats{ord}; - term_collectors term_stats{ord, terms_count}; + field_collectors field_stats{ctx.scorers}; + term_collectors term_stats{ctx.scorers, terms_count}; const std::string_view field_name = this->field(); - for (const auto& segment : rdr) { + for (const auto& segment : ctx.index) { // get term dictionary for field const term_reader* field = segment.field(field_name); @@ -119,16 +120,16 @@ filter::prepared::ptr by_ngram_similarity::prepare( term_states.reserve(terms_count); } - bstring stats(ord.stats_size(), 0); + bstring stats(ctx.scorers.stats_size(), 0); auto* stats_buf = stats.data(); for (size_t term_idx = 0; term_idx < terms_count; ++term_idx) { - term_stats.finish(stats_buf, term_idx, field_stats, rdr); + term_stats.finish(stats_buf, term_idx, field_stats, ctx.index); } - return memory::make_managed( - min_match_count, std::move(query_states), std::move(stats), - this->boost() * boost); + return memory::make_tracked( + ctx.memory, min_match_count, std::move(query_states), std::move(stats), + sub_boost); } } // namespace irs diff --git a/core/search/ngram_similarity_filter.hpp b/core/search/ngram_similarity_filter.hpp index dd6a6e371..973d788f8 100644 --- a/core/search/ngram_similarity_filter.hpp +++ b/core/search/ngram_similarity_filter.hpp @@ -51,11 +51,7 @@ struct by_ngram_similarity_options { class by_ngram_similarity : public filter_base { public: - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; }; } // namespace irs diff --git a/core/search/ngram_similarity_query.hpp b/core/search/ngram_similarity_query.hpp index edde28a1e..c4bdf8747 100644 --- a/core/search/ngram_similarity_query.hpp +++ b/core/search/ngram_similarity_query.hpp @@ -46,8 +46,6 @@ class NGramSimilarityQuery : public filter::prepared { states_{std::move(states)}, stats_{std::move(stats)} {} - using filter::prepared::execute; - doc_iterator::ptr execute(const ExecutionContext& ctx) const final; void visit(const SubReader& segment, PreparedStateVisitor& visitor, diff --git a/core/search/phrase_filter.cpp b/core/search/phrase_filter.cpp index 09108ebe4..b9686d328 100644 --- a/core/search/phrase_filter.cpp +++ b/core/search/phrase_filter.cpp @@ -31,11 +31,10 @@ #include "search/states/phrase_state.hpp" #include "search/states_cache.hpp" +namespace irs { namespace { -using namespace irs; - -struct get_visitor { +struct GetVisitor { using result_type = field_visitor; result_type operator()(const by_term_options& part) const { @@ -85,25 +84,23 @@ struct get_visitor { } }; -struct prepare : util::noncopyable { +struct Prepare : util::noncopyable { using result_type = filter::prepared::ptr; result_type operator()(const by_term_options& opts) const { - return by_term::prepare(index, order, boost, field, opts.term); + return by_term::prepare(ctx, field, opts.term); } result_type operator()(const by_prefix_options& part) const { - return by_prefix::prepare(index, order, boost, field, part.term, - part.scored_terms_limit); + return by_prefix::prepare(ctx, field, part.term, part.scored_terms_limit); } result_type operator()(const by_wildcard_options& part) const { - return by_wildcard::prepare(index, order, boost, field, part.term, - part.scored_terms_limit); + return by_wildcard::prepare(ctx, field, part.term, part.scored_terms_limit); } result_type operator()(const by_edit_distance_filter_options& part) const { - return by_edit_distance::prepare(index, order, boost, field, part.term, + return by_edit_distance::prepare(ctx, field, part.term, 0, // collect all terms part.max_distance, part.provider, part.with_transpositions, part.prefix); @@ -114,8 +111,7 @@ struct prepare : util::noncopyable { } result_type operator()(const by_range_options& part) const { - return by_range::prepare(index, order, boost, field, part.range, - part.scored_terms_limit); + return by_range::prepare(ctx, field, part.range, part.scored_terms_limit); } template @@ -124,20 +120,15 @@ struct prepare : util::noncopyable { return filter::prepared::empty(); } - prepare(const IndexReader& index, const Scorers& order, std::string_view field, - const score_t boost) noexcept - : index(index), order(order), field(field), boost(boost) {} + Prepare(const PrepareContext& ctx, std::string_view field) noexcept + : ctx{ctx}, field{field} {} - const IndexReader& index; - const irs::Scorers& order; + const PrepareContext& ctx; const std::string_view field; - const score_t boost; }; } // namespace -namespace irs { - // Filter visitor for phrase queries template class phrase_term_visitor final : public filter_visitor, @@ -198,22 +189,16 @@ class phrase_term_visitor final : public filter_visitor, bool volatile_boost_ = false; }; -} // namespace irs - -namespace irs { - -filter::prepared::ptr by_phrase::prepare( - const IndexReader& index, const Scorers& ord, score_t boost, - const attribute_provider* /*ctx*/) const { +filter::prepared::ptr by_phrase::prepare(const PrepareContext& ctx) const { if (field().empty() || options().empty()) { // empty field or phrase return filter::prepared::empty(); } if (1 == options().size()) { + auto sub_ctx = ctx.Boost(boost()); auto query = - std::visit(::prepare{index, ord, field(), this->boost() * boost}, - options().begin()->second); + std::visit(Prepare{sub_ctx, field()}, options().begin()->second); if (query) { return query; @@ -222,27 +207,26 @@ filter::prepared::ptr by_phrase::prepare( // prepare phrase stats (collector for each term) if (options().simple()) { - return fixed_prepare_collect(index, ord, boost); + return fixed_prepare_collect(ctx); } - return variadic_prepare_collect(index, ord, boost); + return variadic_prepare_collect(ctx); } -filter::prepared::ptr by_phrase::fixed_prepare_collect(const IndexReader& index, - const Scorers& ord, - score_t boost) const { +filter::prepared::ptr by_phrase::fixed_prepare_collect( + const PrepareContext& ctx) const { const auto phrase_size = options().size(); - const auto is_ord_empty = ord.empty(); + const auto is_ord_empty = ctx.scorers.empty(); // stats collectors - field_collectors field_stats(ord); - term_collectors term_stats(ord, phrase_size); + field_collectors field_stats(ctx.scorers); + term_collectors term_stats(ctx.scorers, phrase_size); // per segment phrase states - FixedPhraseQuery::states_t phrase_states{index.size()}; + FixedPhraseQuery::states_t phrase_states{ctx.memory, ctx.index.size()}; // per segment phrase terms - PhraseTerms phrase_terms; + FixedPhraseState::Terms phrase_terms{{ctx.memory}}; phrase_terms.reserve(phrase_size); // iterate over the segments @@ -250,7 +234,7 @@ filter::prepared::ptr by_phrase::fixed_prepare_collect(const IndexReader& index, phrase_term_visitor ptv(phrase_terms); - for (const auto& segment : index) { + for (const auto& segment : ctx.index) { // get term dictionary for field const auto* reader = segment.field(field); @@ -299,7 +283,7 @@ filter::prepared::ptr by_phrase::fixed_prepare_collect(const IndexReader& index, const size_t base_offset = options().begin()->first; // finish stats - bstring stats(ord.stats_size(), 0); // aggregated phrase stats + bstring stats(ctx.scorers.stats_size(), 0); // aggregated phrase stats auto* stats_buf = stats.data(); FixedPhraseQuery::positions_t positions(phrase_size); @@ -308,48 +292,48 @@ filter::prepared::ptr by_phrase::fixed_prepare_collect(const IndexReader& index, size_t term_idx = 0; for (const auto& term : options()) { *pos_itr = position::value_t(term.first - base_offset); - term_stats.finish(stats_buf, term_idx, field_stats, index); + term_stats.finish(stats_buf, term_idx, field_stats, ctx.index); ++pos_itr; ++term_idx; } - return memory::make_managed( - std::move(phrase_states), std::move(positions), std::move(stats), - this->boost() * boost); + return memory::make_tracked( + ctx.memory, std::move(phrase_states), std::move(positions), + std::move(stats), ctx.boost * boost()); } filter::prepared::ptr by_phrase::variadic_prepare_collect( - const IndexReader& index, const Scorers& ord, score_t boost) const { + const PrepareContext& ctx) const { const auto phrase_size = options().size(); // stats collectors - field_collectors field_stats(ord); + field_collectors field_stats{ctx.scorers}; std::vector phrase_part_visitors; phrase_part_visitors.reserve(phrase_size); std::vector phrase_part_stats; phrase_part_stats.reserve(phrase_size); for (const auto& word : options()) { - phrase_part_stats.emplace_back(ord, 0); - phrase_part_visitors.emplace_back(std::visit(get_visitor{}, word.second)); + phrase_part_stats.emplace_back(ctx.scorers, 0); + phrase_part_visitors.emplace_back(std::visit(GetVisitor{}, word.second)); } // per segment phrase states - VariadicPhraseQuery::states_t phrase_states{index.size()}; + VariadicPhraseQuery::states_t phrase_states{ctx.memory, ctx.index.size()}; - // per segment phrase terms - std::vector num_terms(phrase_size); // number of terms per part - PhraseTerms phrase_terms; + // per segment phrase terms: number of terms per part + ManagedVector num_terms(phrase_size, {ctx.memory}); + VariadicPhraseState::Terms phrase_terms{{ctx.memory}}; // reserve space for at least 1 term per part phrase_terms.reserve(phrase_size); // iterate over the segments const std::string_view field = this->field(); - const auto is_ord_empty = ord.empty(); + const auto is_ord_empty = ctx.scorers.empty(); phrase_term_visitor ptv(phrase_terms); - for (const auto& segment : index) { + for (const auto& segment : ctx.index) { // get term dictionary for field const auto* reader = segment.field(field); @@ -414,7 +398,7 @@ filter::prepared::ptr by_phrase::variadic_prepare_collect( // finish stats IRS_ASSERT(phrase_size == phrase_part_stats.size()); - bstring stats(ord.stats_size(), 0); // aggregated phrase stats + bstring stats(ctx.scorers.stats_size(), 0); // aggregated phrase stats auto* stats_buf = stats.data(); auto collector = phrase_part_stats.begin(); @@ -425,15 +409,15 @@ filter::prepared::ptr by_phrase::variadic_prepare_collect( *pos_itr = position::value_t(term.first - base_offset); for (size_t term_idx = 0, size = collector->size(); term_idx < size; ++term_idx) { - collector->finish(stats_buf, term_idx, field_stats, index); + collector->finish(stats_buf, term_idx, field_stats, ctx.index); } ++pos_itr; ++collector; } - return memory::make_managed( - std::move(phrase_states), std::move(positions), std::move(stats), - this->boost() * boost); + return memory::make_tracked( + ctx.memory, std::move(phrase_states), std::move(positions), + std::move(stats), ctx.boost * boost()); } } // namespace irs diff --git a/core/search/phrase_filter.hpp b/core/search/phrase_filter.hpp index 402f4b116..643c649ac 100644 --- a/core/search/phrase_filter.hpp +++ b/core/search/phrase_filter.hpp @@ -146,20 +146,13 @@ class by_phrase_options { // Phrase filter class by_phrase : public filter_base { public: - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; private: - filter::prepared::ptr fixed_prepare_collect(const IndexReader& index, - const Scorers& ord, - score_t boost) const; + filter::prepared::ptr fixed_prepare_collect(const PrepareContext& ctx) const; - filter::prepared::ptr variadic_prepare_collect(const IndexReader& index, - const Scorers& ord, - score_t boost) const; + filter::prepared::ptr variadic_prepare_collect( + const PrepareContext& ctx) const; }; } // namespace irs diff --git a/core/search/phrase_query.hpp b/core/search/phrase_query.hpp index 605d985da..c438f4227 100644 --- a/core/search/phrase_query.hpp +++ b/core/search/phrase_query.hpp @@ -78,8 +78,6 @@ class FixedPhraseQuery : public PhraseQuery { : PhraseQuery{std::move(states), std::move(positions), std::move(stats), boost} {} - using filter::prepared::execute; - doc_iterator::ptr execute(const ExecutionContext& ctx) const final; doc_iterator::ptr ExecuteWithOffsets(const SubReader& segment) const; @@ -92,8 +90,6 @@ class VariadicPhraseQuery : public PhraseQuery { : PhraseQuery{std::move(states), std::move(positions), std::move(stats), boost} {} - using filter::prepared::execute; - doc_iterator::ptr execute(const ExecutionContext& ctx) const final; doc_iterator::ptr ExecuteWithOffsets(const SubReader& segment) const; diff --git a/core/search/prefix_filter.cpp b/core/search/prefix_filter.cpp index b3bf3081a..8e6a32092 100644 --- a/core/search/prefix_filter.cpp +++ b/core/search/prefix_filter.cpp @@ -29,13 +29,12 @@ #include "search/states_cache.hpp" #include "shared.hpp" +namespace irs { namespace { -using namespace irs; - template -void visit(const SubReader& segment, const term_reader& reader, - bytes_view prefix, Visitor& visitor) { +void VisitImpl(const SubReader& segment, const term_reader& reader, + bytes_view prefix, Visitor& visitor) { auto terms = reader.iterator(SeekMode::NORMAL); // seek to prefix @@ -68,42 +67,33 @@ void visit(const SubReader& segment, const term_reader& reader, } // namespace -namespace irs { - -filter::prepared::ptr by_prefix::prepare(const IndexReader& index, - const Scorers& ord, score_t boost, +filter::prepared::ptr by_prefix::prepare(const PrepareContext& ctx, std::string_view field, bytes_view prefix, size_t scored_terms_limit) { // object for collecting order stats limited_sample_collector collector( - ord.empty() ? 0 : scored_terms_limit); - MultiTermQuery::States states{index.size()}; + ctx.scorers.empty() ? 0 : scored_terms_limit); + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; multiterm_visitor mtv{collector, states}; - // iterate over the segments - for (const auto& segment : index) { - // get term dictionary for field - const auto* reader = segment.field(field); - - if (!reader) { - continue; + for (const auto& segment : ctx.index) { + if (const auto* reader = segment.field(field); reader) { + VisitImpl(segment, *reader, prefix, mtv); } - - ::visit(segment, *reader, prefix, mtv); } - std::vector stats; - collector.score(index, ord, stats); + MultiTermQuery::Stats stats{{ctx.memory}}; + collector.score(ctx.index, ctx.scorers, stats); - return memory::make_managed(std::move(states), - std::move(stats), boost, + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost, ScoreMergeType::kSum, size_t{1}); } void by_prefix::visit(const SubReader& segment, const term_reader& reader, bytes_view prefix, filter_visitor& visitor) { - ::visit(segment, reader, prefix, visitor); + VisitImpl(segment, reader, prefix, visitor); } } // namespace irs diff --git a/core/search/prefix_filter.hpp b/core/search/prefix_filter.hpp index 66ee0b3f4..6b2c1f3bd 100644 --- a/core/search/prefix_filter.hpp +++ b/core/search/prefix_filter.hpp @@ -72,19 +72,17 @@ struct by_prefix_options : by_prefix_filter_options { //////////////////////////////////////////////////////////////////////////////// class by_prefix : public filter_base { public: - static prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, std::string_view field, - bytes_view prefix, size_t scored_terms_limit); + static prepared::ptr prepare(const PrepareContext& ctx, + std::string_view field, bytes_view prefix, + size_t scored_terms_limit); static void visit(const SubReader& segment, const term_reader& reader, bytes_view prefix, filter_visitor& visitor); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(index, ord, this->boost() * boost, field(), options().term, + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { + auto sub_ctx = ctx; + sub_ctx.boost *= boost(); + return prepare(sub_ctx, field(), options().term, options().scored_terms_limit); } }; diff --git a/core/search/proxy_filter.cpp b/core/search/proxy_filter.cpp index 2075637d4..eb095a51a 100644 --- a/core/search/proxy_filter.cpp +++ b/core/search/proxy_filter.cpp @@ -38,21 +38,32 @@ class lazy_filter_bitset : private util::noncopyable { using word_t = size_t; lazy_filter_bitset(const ExecutionContext& ctx, - const filter::prepared& filter) { - auto& segment = ctx.segment; - - const size_t bits = segment.docs_count() + doc_limits::min(); - real_doc_itr_ = segment.mask(filter.execute({.segment = segment, - .scorers = ctx.scorers, - .ctx = ctx.ctx, - .wand = ctx.wand})); + const filter::prepared& filter) + : manager_{ctx.memory} { + const size_t bits = ctx.segment.docs_count() + doc_limits::min(); words_ = bitset::bits_to_words(bits); - cost_ = cost::extract(*real_doc_itr_); - set_ = std::make_unique(words_); - std::memset(set_.get(), 0, sizeof(word_t) * words_); + + auto bytes = sizeof(*this) + sizeof(word_t) * words_; + manager_.Increase(bytes); + Finally decrease = [&]() noexcept { ctx.memory.DecreaseChecked(bytes); }; + + // TODO(MBkkt) use mask from segment manually to avoid virtual call + real_doc_itr_ = ctx.segment.mask(filter.execute(ctx)); + real_doc_ = irs::get(*real_doc_itr_); - begin_ = set_.get(); + cost_ = cost::extract(*real_doc_itr_); + + set_ = std::allocator{}.allocate(words_); + std::memset(set_, 0, sizeof(word_t) * words_); + begin_ = set_; end_ = begin_; + + bytes = 0; + } + + ~lazy_filter_bitset() { + std::allocator{}.deallocate(set_, words_); + manager_.Decrease(sizeof(*this) + sizeof(word_t) * words_); } bool get(size_t word_idx, word_t* data) { @@ -62,7 +73,7 @@ class lazy_filter_bitset : private util::noncopyable { return false; } - word_t* requested = set_.get() + word_idx; + word_t* requested = set_ + word_idx; if (requested >= end_) { auto block_limit = ((word_idx + 1) * kBits) - 1; while (real_doc_itr_->next()) { @@ -81,13 +92,16 @@ class lazy_filter_bitset : private util::noncopyable { cost::cost_t get_cost() const noexcept { return cost_; } private: - std::unique_ptr set_; - const word_t* begin_{nullptr}; - const word_t* end_{nullptr}; + IResourceManager& manager_; + doc_iterator::ptr real_doc_itr_; const document* real_doc_{nullptr}; - size_t words_{0}; cost::cost_t cost_; + + word_t* set_{nullptr}; + size_t words_{0}; + const word_t* begin_{nullptr}; + const word_t* end_{nullptr}; }; class lazy_filter_bitset_iterator : public doc_iterator, @@ -148,9 +162,8 @@ class lazy_filter_bitset_iterator : public doc_iterator, void reset() noexcept { word_idx_ = 0; word_ = 0; - base_ = doc_limits::invalid() - - bits_required(); // before the - // first word + // before the first word + base_ = doc_limits::invalid() - bits_required(); doc_.value = doc_limits::invalid(); } @@ -164,10 +177,16 @@ class lazy_filter_bitset_iterator : public doc_iterator, }; struct proxy_query_cache { - explicit proxy_query_cache(filter::ptr&& ptr) - : real_filter_(std::move(ptr)) {} + proxy_query_cache(IResourceManager& memory, filter::ptr&& ptr) noexcept + : readers_{Alloc{memory}}, real_filter_(std::move(ptr)) {} + + using Alloc = ManagedTypedAllocator< + std::pair>>; - absl::flat_hash_map> + absl::flat_hash_map< + const SubReader*, std::unique_ptr, + absl::container_internal::hash_default_hash, + absl::container_internal::hash_default_eq, Alloc> readers_; filter::prepared::ptr prepared_real_filter_; filter::ptr real_filter_; @@ -190,7 +209,8 @@ class proxy_query : public filter::prepared { } IRS_ASSERT(cached); - return memory::make_managed(*cached); + return memory::make_tracked(ctx.memory, + *cached); } void visit(const SubReader&, PreparedStateVisitor&, score_t) const final { @@ -201,28 +221,22 @@ class proxy_query : public filter::prepared { mutable proxy_filter::cache_ptr cache_; }; -filter::prepared::ptr proxy_filter::prepare( - const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* ctx) const { - if (!cache_ || !cache_->real_filter_) { - IRS_ASSERT(false); - return filter::prepared::empty(); - } - if (!ord.empty()) { +filter::prepared::ptr proxy_filter::prepare(const PrepareContext& ctx) const { + if (!cache_ || !cache_->real_filter_ || !ctx.scorers.empty()) { // Currently we do not support caching scores. // Proxy filter should not be used with scorers! IRS_ASSERT(false); return filter::prepared::empty(); } if (!cache_->prepared_real_filter_) { - cache_->prepared_real_filter_ = - cache_->real_filter_->prepare(rdr, ord, boost, ctx); + cache_->prepared_real_filter_ = cache_->real_filter_->prepare(ctx); } - return memory::make_managed(cache_); + return memory::make_tracked(ctx.memory, cache_); } -filter& proxy_filter::cache_filter(filter::ptr&& ptr) { - cache_ = std::make_shared(std::move(ptr)); +filter& proxy_filter::cache_filter(IResourceManager& memory, + filter::ptr&& ptr) { + cache_ = std::make_shared(memory, std::move(ptr)); IRS_ASSERT(cache_->real_filter_); return *cache_->real_filter_; } diff --git a/core/search/proxy_filter.hpp b/core/search/proxy_filter.hpp index f2f475f2f..6629864d9 100644 --- a/core/search/proxy_filter.hpp +++ b/core/search/proxy_filter.hpp @@ -42,16 +42,14 @@ class proxy_filter final : public filter { public: using cache_ptr = std::shared_ptr; - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers&, - score_t boost, - const attribute_provider*) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; template - std::pair set_filter(Args&&... args) { + std::pair set_filter(IResourceManager& memory, + Args&&... args) { static_assert(std::is_base_of_v); - auto& ptr = cache_filter(std::make_unique(std::forward(args)...)); + auto& ptr = + cache_filter(memory, std::make_unique(std::forward(args)...)); return {static_cast(ptr), cache_}; } @@ -65,7 +63,7 @@ class proxy_filter final : public filter { } private: - filter& cache_filter(filter::ptr&& ptr); + filter& cache_filter(IResourceManager& memory, filter::ptr&& ptr); mutable cache_ptr cache_; }; diff --git a/core/search/range_filter.cpp b/core/search/range_filter.cpp index 8421bb1e4..15368d8f7 100644 --- a/core/search/range_filter.cpp +++ b/core/search/range_filter.cpp @@ -29,10 +29,9 @@ #include "search/term_filter.hpp" #include "shared.hpp" +namespace irs { namespace { -using namespace irs; - template void collect_terms(const SubReader& segment, const term_reader& field, seek_term_iterator& terms, Visitor& visitor, Comparer cmp) { @@ -61,8 +60,8 @@ void collect_terms(const SubReader& segment, const term_reader& field, } template -void visit(const SubReader& segment, const term_reader& reader, - const by_range_options::range_type& rng, Visitor& visitor) { +void VisitImpl(const SubReader& segment, const term_reader& reader, + const by_range_options::range_type& rng, Visitor& visitor) { auto terms = reader.iterator(SeekMode::NORMAL); if (IRS_UNLIKELY(!terms)) { @@ -94,26 +93,23 @@ void visit(const SubReader& segment, const term_reader& reader, switch (rng.max_type) { case BoundType::UNBOUNDED: - ::collect_terms(segment, reader, *terms, visitor, - [](bytes_view) { return true; }); + collect_terms(segment, reader, *terms, visitor, + [](bytes_view) { return true; }); break; case BoundType::INCLUSIVE: - ::collect_terms(segment, reader, *terms, visitor, - [max](bytes_view term) { return term <= max; }); + collect_terms(segment, reader, *terms, visitor, + [max](bytes_view term) { return term <= max; }); break; case BoundType::EXCLUSIVE: - ::collect_terms(segment, reader, *terms, visitor, - [max](bytes_view term) { return term < max; }); + collect_terms(segment, reader, *terms, visitor, + [max](bytes_view term) { return term < max; }); break; } } } // namespace -namespace irs { - -filter::prepared::ptr by_range::prepare(const IndexReader& index, - const Scorers& ord, score_t boost, +filter::prepared::ptr by_range::prepare(const PrepareContext& ctx, std::string_view field, const options_type::range_type& rng, size_t scored_terms_limit) { @@ -127,7 +123,7 @@ filter::prepared::ptr by_range::prepare(const IndexReader& index, rng.max_type != BoundType::UNBOUNDED && rng.min == rng.max) { if (rng.min_type == rng.max_type && rng.min_type == BoundType::INCLUSIVE) { // degenerated case - return by_term::prepare(index, ord, boost, field, rng.min); + return by_term::prepare(ctx, field, rng.min); } // can't satisfy conditon @@ -136,35 +132,28 @@ filter::prepared::ptr by_range::prepare(const IndexReader& index, // object for collecting order stats limited_sample_collector collector( - ord.empty() ? 0 : scored_terms_limit); - MultiTermQuery::States states{index.size()}; + ctx.scorers.empty() ? 0 : scored_terms_limit); + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; multiterm_visitor mtv{collector, states}; - // iterate over the segments - for (const auto& segment : index) { - // get term dictionary for field - const auto* reader = segment.field(field); - - if (!reader) { - // can't find field with the specified name - continue; + for (const auto& segment : ctx.index) { + if (const auto* reader = segment.field(field); reader) { + VisitImpl(segment, *reader, rng, mtv); } - - ::visit(segment, *reader, rng, mtv); } - MultiTermQuery::Stats stats; - collector.score(index, ord, stats); + MultiTermQuery::Stats stats{{ctx.memory}}; + collector.score(ctx.index, ctx.scorers, stats); - return memory::make_managed(std::move(states), - std::move(stats), boost, + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost, ScoreMergeType::kSum, size_t{1}); } void by_range::visit(const SubReader& segment, const term_reader& reader, const options_type::range_type& rng, filter_visitor& visitor) { - ::visit(segment, reader, rng, visitor); + VisitImpl(segment, reader, rng, visitor); } } // namespace irs diff --git a/core/search/range_filter.hpp b/core/search/range_filter.hpp index 526b6257c..644f37cd4 100644 --- a/core/search/range_filter.hpp +++ b/core/search/range_filter.hpp @@ -77,8 +77,8 @@ struct by_range_options : by_range_filter_options { ////////////////////////////////////////////////////////////////////////////// class by_range : public filter_base { public: - static prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, std::string_view field, + static prepared::ptr prepare(const PrepareContext& ctx, + std::string_view field, const options_type::range_type& rng, size_t scored_terms_limit); @@ -86,12 +86,8 @@ class by_range : public filter_base { const options_type::range_type& rng, filter_visitor& visitor); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& ord, - score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(index, ord, this->boost() * boost, field(), options().range, + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { + return prepare(ctx.Boost(boost()), field(), options().range, options().scored_terms_limit); } }; diff --git a/core/search/same_position_filter.cpp b/core/search/same_position_filter.cpp index b3a1ba5fd..20cdc43f2 100644 --- a/core/search/same_position_filter.cpp +++ b/core/search/same_position_filter.cpp @@ -104,16 +104,14 @@ class same_position_iterator : public Conjunction { class same_position_query : public filter::prepared { public: - typedef std::vector terms_states_t; - typedef StatesCache states_t; - typedef std::vector stats_t; + using terms_states_t = ManagedVector; + using states_t = StatesCache; + using stats_t = ManagedVector; explicit same_position_query(states_t&& states, stats_t&& stats, score_t boost) : prepared(boost), states_(std::move(states)), stats_(std::move(stats)) {} - using filter::prepared::execute; - void visit(const SubReader&, PreparedStateVisitor&, score_t) const final { // FIXME(gnusi): implement } @@ -190,8 +188,7 @@ class same_position_query : public filter::prepared { } // namespace filter::prepared::ptr by_same_position::prepare( - const IndexReader& index, const Scorers& ord, score_t boost, - const attribute_provider* /*ctx*/) const { + const PrepareContext& ctx) const { auto& terms = options().terms; const auto size = terms.size(); @@ -201,21 +198,22 @@ filter::prepared::ptr by_same_position::prepare( } // per segment query state - same_position_query::states_t query_states{index.size()}; + same_position_query::states_t query_states{ctx.memory, ctx.index.size()}; // per segment terms states - same_position_query::states_t::state_type term_states; + same_position_query::states_t::state_type term_states{ + same_position_query::states_t::state_type::allocator_type{ctx.memory}}; term_states.reserve(size); // !!! FIXME !!! // that's completely wrong, we have to collect stats for each field // instead of aggregating them using a single collector - field_collectors field_stats(ord); + field_collectors field_stats(ctx.scorers); // prepare phrase stats (collector for each term) - term_collectors term_stats(ord, size); + term_collectors term_stats(ctx.scorers, size); - for (const auto& segment : index) { + for (const auto& segment : ctx.index) { size_t term_idx = 0; for (const auto& branch : terms) { @@ -233,14 +231,14 @@ filter::prepared::ptr by_same_position::prepare( continue; } - field_stats.collect(segment, - *field); // collect field statistics once per segment + // collect field statistics once per segment + field_stats.collect(segment, *field); // find terms seek_term_iterator::ptr term = field->iterator(SeekMode::NORMAL); if (!term->seek(branch.second)) { - if (ord.empty()) { + if (ctx.scorers.empty()) { break; } else { // continue here because we should collect @@ -251,7 +249,7 @@ filter::prepared::ptr by_same_position::prepare( term->read(); // read term attributes term_stats.collect(segment, *field, term_idx, *term); - term_states.emplace_back(); + term_states.emplace_back(ctx.memory); auto& state = term_states.back(); @@ -273,15 +271,16 @@ filter::prepared::ptr by_same_position::prepare( // finish stats size_t term_idx = 0; - same_position_query::stats_t stats(size); + same_position_query::stats_t stats( + size, same_position_query::stats_t::allocator_type{ctx.memory}); for (auto& stat : stats) { - stat.resize(ord.stats_size()); + stat.resize(ctx.scorers.stats_size()); auto* stats_buf = stat.data(); - term_stats.finish(stats_buf, term_idx++, field_stats, index); + term_stats.finish(stats_buf, term_idx++, field_stats, ctx.index); } - return memory::make_managed( - std::move(query_states), std::move(stats), this->boost() * boost); + return memory::make_tracked( + ctx.memory, std::move(query_states), std::move(stats), ctx.boost * boost()); } } // namespace irs diff --git a/core/search/same_position_filter.hpp b/core/search/same_position_filter.hpp index 01a211547..e1cb64fd7 100644 --- a/core/search/same_position_filter.hpp +++ b/core/search/same_position_filter.hpp @@ -58,11 +58,7 @@ class by_same_position : public filter_with_options { static constexpr IndexFeatures kRequiredFeatures = IndexFeatures::FREQ | IndexFeatures::POS; - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, - const attribute_provider* ctx) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; }; } // namespace irs diff --git a/core/search/scorer.hpp b/core/search/scorer.hpp index c7a82b0e8..6ab6a6f43 100644 --- a/core/search/scorer.hpp +++ b/core/search/scorer.hpp @@ -125,10 +125,9 @@ struct WandWriter { virtual ~WandWriter() = default; - virtual bool Prepare( - const ColumnProvider& reader, - const std::map& features, - const attribute_provider& attrs) = 0; + virtual bool Prepare(const ColumnProvider& reader, + const feature_map_t& features, + const attribute_provider& attrs) = 0; virtual void Reset() = 0; @@ -170,8 +169,7 @@ struct Scorer { // The index features required for proper operation of this sort::prepared virtual IndexFeatures index_features() const = 0; - virtual void get_features( - std::set& features) const = 0; + virtual void get_features(feature_set_t& features) const = 0; // Create an object to be used for collecting index statistics, one // instance per matched field. @@ -179,11 +177,11 @@ struct Scorer { virtual FieldCollector::ptr prepare_field_collector() const = 0; // Create a stateful scorer used for computation of document scores - virtual ScoreFunction prepare_scorer( - const ColumnProvider& segment, - const std::map& features, - const byte_type* stats, const attribute_provider& doc_attrs, - score_t boost) const = 0; + virtual ScoreFunction prepare_scorer(const ColumnProvider& segment, + const feature_map_t& features, + const byte_type* stats, + const attribute_provider& doc_attrs, + score_t boost) const = 0; // Create an object to be used for collecting index statistics, one // instance per matched term. @@ -476,7 +474,7 @@ class ScorerBase : public Scorer { void collect(byte_type*, const FieldCollector*, const TermCollector*) const override {} - void get_features(std::set&) const override {} + void get_features(feature_set_t&) const override {} IRS_FORCE_INLINE static const StatsType* stats_cast( const byte_type* buf) noexcept { diff --git a/core/search/states/multiterm_state.hpp b/core/search/states/multiterm_state.hpp index 3ec693294..83a9c9c8d 100644 --- a/core/search/states/multiterm_state.hpp +++ b/core/search/states/multiterm_state.hpp @@ -41,6 +41,9 @@ struct MultiTermState { float_t boost{kNoBoost}; }; + explicit MultiTermState(IResourceManager& memory) noexcept + : scored_states{{memory}}, unscored_terms{{memory}} {} + using UnscoredTermState = seek_cookie::ptr; // Return true if state is empty @@ -57,12 +60,12 @@ struct MultiTermState { const term_reader* reader{}; // Scored term states - std::vector scored_states; + ManagedVector scored_states; // Matching terms that may have been skipped // while collecting statistics and should not be // scored by the disjunction. - std::vector unscored_terms; + ManagedVector unscored_terms; // Estimated cost of scored states cost::cost_t scored_states_estimation{}; diff --git a/core/search/states/ngram_state.hpp b/core/search/states/ngram_state.hpp index 61d6421e4..f30b0dfd0 100644 --- a/core/search/states/ngram_state.hpp +++ b/core/search/states/ngram_state.hpp @@ -29,8 +29,10 @@ namespace irs { struct term_reader; struct NGramState { + explicit NGramState(IResourceManager& memory) noexcept : terms{{memory}} {} + const term_reader* field{}; - std::vector terms; + ManagedVector terms; }; } // namespace irs diff --git a/core/search/states/phrase_state.hpp b/core/search/states/phrase_state.hpp index 36e114d91..e1510f767 100644 --- a/core/search/states/phrase_state.hpp +++ b/core/search/states/phrase_state.hpp @@ -28,11 +28,11 @@ namespace irs { struct term_reader; -template -using PhraseTerms = std::vector; - // Cached per reader fixed phrase state struct FixedPhraseState { + explicit FixedPhraseState(IResourceManager& memory) noexcept + : terms{{memory}} {} + // Mimic std::pair interface struct TermState { TermState(seek_cookie::ptr&& first, score_t /*second*/) noexcept @@ -41,7 +41,8 @@ struct FixedPhraseState { seek_cookie::ptr first; }; - PhraseTerms terms; + using Terms = ManagedVector; + Terms terms; const term_reader* reader{}; }; @@ -50,10 +51,14 @@ static_assert(std::is_nothrow_move_assignable_v); // Cached per reader variadic phrase state struct VariadicPhraseState { + explicit VariadicPhraseState(IResourceManager& memory) noexcept + : num_terms{{memory}}, terms{{memory}} {} + using TermState = std::pair; - std::vector num_terms; // number of terms per phrase part - PhraseTerms terms; + ManagedVector num_terms; // number of terms per phrase part + using Terms = ManagedVector; + Terms terms; const term_reader* reader{}; bool volatile_boost{}; }; diff --git a/core/search/states/term_state.hpp b/core/search/states/term_state.hpp index ef7a7b281..aa7d3f485 100644 --- a/core/search/states/term_state.hpp +++ b/core/search/states/term_state.hpp @@ -30,6 +30,8 @@ struct term_reader; // Cached per reader term state struct TermState { + explicit TermState(IResourceManager& /*memory*/) noexcept {} + const term_reader* reader{}; seek_cookie::ptr cookie; }; diff --git a/core/search/states_cache.hpp b/core/search/states_cache.hpp index b4f62c341..f9a0314a1 100644 --- a/core/search/states_cache.hpp +++ b/core/search/states_cache.hpp @@ -22,6 +22,7 @@ #pragma once +#include "resource_manager.hpp" #include "shared.hpp" #include "utils/noncopyable.hpp" @@ -39,16 +40,23 @@ class StatesCache : private util::noncopyable { public: using state_type = State; - explicit StatesCache(size_t size) { states_.reserve(size); } + explicit StatesCache(IResourceManager& memory, size_t size) + : states_{Alloc{memory}} { + states_.reserve(size); + } StatesCache(StatesCache&&) = default; StatesCache& operator=(StatesCache&&) = default; - state_type& insert(const SubReader& rdr) { return states_[&rdr]; } + state_type& insert(const SubReader& segment) { + auto result = + states_.emplace(&segment, states_.get_allocator().ResourceManager()); + return result.first->second; + } - const state_type* find(const SubReader& rdr) const noexcept { - auto it = states_.find(&rdr); - return states_.end() == it ? nullptr : &(it->second); + const state_type* find(const SubReader& segment) const noexcept { + const auto it = states_.find(&segment); + return it != states_.end() ? &it->second : nullptr; } template @@ -59,10 +67,16 @@ class StatesCache : private util::noncopyable { bool empty() const noexcept { return states_.empty(); } private: - using states_map = absl::flat_hash_map; + using Alloc = + ManagedTypedAllocator>; + + using StatesMap = absl::flat_hash_map< + const SubReader*, state_type, + absl::container_internal::hash_default_hash, + absl::container_internal::hash_default_eq, Alloc>; // FIXME use vector instead? - states_map states_; + StatesMap states_; }; } // namespace irs diff --git a/core/search/term_filter.cpp b/core/search/term_filter.cpp index c3034561d..ed7003189 100644 --- a/core/search/term_filter.cpp +++ b/core/search/term_filter.cpp @@ -27,10 +27,9 @@ #include "search/filter_visitor.hpp" #include "search/term_query.hpp" +namespace irs { namespace { -using namespace irs; - // Filter visitor for term queries class term_visitor : private util::noncopyable { public: @@ -66,8 +65,8 @@ class term_visitor : private util::noncopyable { }; template -void visit(const SubReader& segment, const term_reader& field, bytes_view term, - Visitor& visitor) { +void VisitImpl(const SubReader& segment, const term_reader& field, + bytes_view term, Visitor& visitor) { // find term auto terms = field.iterator(SeekMode::RANDOM_ONLY); @@ -85,25 +84,22 @@ void visit(const SubReader& segment, const term_reader& field, bytes_view term, } // namespace -namespace irs { - void by_term::visit(const SubReader& segment, const term_reader& field, bytes_view term, filter_visitor& visitor) { - ::visit(segment, field, term, visitor); + VisitImpl(segment, field, term, visitor); } -filter::prepared::ptr by_term::prepare(const IndexReader& index, - const Scorers& ord, score_t boost, +filter::prepared::ptr by_term::prepare(const PrepareContext& ctx, std::string_view field, bytes_view term) { - TermQuery::States states(index.size()); - field_collectors field_stats(ord); - term_collectors term_stats(ord, 1); + TermQuery::States states{ctx.memory, ctx.index.size()}; + field_collectors field_stats{ctx.scorers}; + term_collectors term_stats{ctx.scorers, 1}; term_visitor visitor(term_stats, states); // iterate over the segments - for (const auto& segment : index) { + for (const auto& segment : ctx.index) { // get field const auto* reader = segment.field(field); @@ -114,16 +110,16 @@ filter::prepared::ptr by_term::prepare(const IndexReader& index, field_stats.collect(segment, *reader); // collect field statistics once per segment - ::visit(segment, *reader, term, visitor); + VisitImpl(segment, *reader, term, visitor); } - bstring stats(ord.stats_size(), 0); + bstring stats(ctx.scorers.stats_size(), 0); auto* stats_buf = stats.data(); - term_stats.finish(stats_buf, 0, field_stats, index); + term_stats.finish(stats_buf, 0, field_stats, ctx.index); - return memory::make_managed(std::move(states), std::move(stats), - boost); + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost); } } // namespace irs diff --git a/core/search/term_filter.hpp b/core/search/term_filter.hpp index 6b325c734..9fc52e89b 100644 --- a/core/search/term_filter.hpp +++ b/core/search/term_filter.hpp @@ -46,18 +46,16 @@ struct by_term_options { // User-side term filter class by_term : public filter_base { public: - static prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, - score_t boost, std::string_view field, - bytes_view term); + static prepared::ptr prepare(const PrepareContext& ctx, + std::string_view field, bytes_view term); static void visit(const SubReader& segment, const term_reader& field, bytes_view term, filter_visitor& visitor); - using filter::prepare; - - prepared::ptr prepare(const IndexReader& rdr, const Scorers& ord, score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(rdr, ord, boost * this->boost(), field(), options().term); + prepared::ptr prepare(const PrepareContext& ctx) const final { + auto sub_ctx = ctx; + sub_ctx.boost *= boost(); + return prepare(sub_ctx, field(), options().term); } }; diff --git a/core/search/terms_filter.cpp b/core/search/terms_filter.cpp index 20aff2a7b..c5669e3b1 100644 --- a/core/search/terms_filter.cpp +++ b/core/search/terms_filter.cpp @@ -31,14 +31,13 @@ #include "search/multiterm_query.hpp" #include "search/term_filter.hpp" +namespace irs { namespace { -using namespace irs; - template -void visit(const SubReader& segment, const term_reader& field, - const by_terms_options::search_terms& search_terms, - Visitor& visitor) { +void VisitImpl(const SubReader& segment, const term_reader& field, + const by_terms_options::search_terms& search_terms, + Visitor& visitor) { auto terms = field.iterator(SeekMode::NORMAL); if (IRS_UNLIKELY(!terms)) { @@ -93,26 +92,21 @@ void collect_terms(const IndexReader& index, std::string_view field, continue; } - visit(segment, *reader, terms, visitor); + VisitImpl(segment, *reader, terms, visitor); } } } // namespace -namespace irs { - void by_terms::visit(const SubReader& segment, const term_reader& field, const by_terms_options::search_terms& terms, filter_visitor& visitor) { - ::visit(segment, field, terms, visitor); + VisitImpl(segment, field, terms, visitor); } -filter::prepared::ptr by_terms::prepare(const IndexReader& index, - const Scorers& order, score_t boost, - const attribute_provider* ctx) const { +filter::prepared::ptr by_terms::prepare(const PrepareContext& ctx) const { const auto& [terms, min_match, merge_type] = options(); const size_t size = terms.size(); - boost *= this->boost(); if (0 == size || min_match > size) { // Empty or unreachable search criteria @@ -120,29 +114,40 @@ filter::prepared::ptr by_terms::prepare(const IndexReader& index, } if (0 == min_match) { - if (order.empty()) { - return MakeAllDocsFilter(kNoBoost)->prepare(index); + if (ctx.scorers.empty()) { + return MakeAllDocsFilter(kNoBoost)->prepare({ + .index = ctx.index, + .memory = ctx.memory, + }); } else { Or disj; // Don't contribute to the score disj.add(MakeAllDocsFilter(0.)); // Reset min_match to 1 disj.add(*this).mutable_options()->min_match = 1; - return disj.prepare(index, order, kNoBoost, ctx); + return disj.prepare({ + .index = ctx.index, + .memory = ctx.memory, + .scorers = ctx.scorers, + .ctx = ctx.ctx, + }); } } + const auto sub_boost = ctx.boost * boost(); + if (1 == size) { const auto term = std::begin(terms); - return by_term::prepare(index, order, boost * term->boost, field(), - term->term); + auto sub_ctx = ctx; + sub_ctx.boost = sub_boost * term->boost; + return by_term::prepare(sub_ctx, field(), term->term); } - field_collectors field_stats{order}; - term_collectors term_stats{order, size}; - MultiTermQuery::States states{index.size()}; + field_collectors field_stats{ctx.scorers}; + term_collectors term_stats{ctx.scorers, size}; + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; all_terms_collector collector{states, field_stats, term_stats}; - collect_terms(index, field(), terms, collector); + collect_terms(ctx.index, field(), terms, collector); // FIXME(gnusi): Filter out unmatched states during collection if (min_match > 1) { @@ -155,15 +160,17 @@ filter::prepared::ptr by_terms::prepare(const IndexReader& index, return prepared::empty(); } - MultiTermQuery::Stats stats{size}; + MultiTermQuery::Stats stats{{ctx.memory}}; + stats.resize(size); for (size_t term_idx = 0; auto& stat : stats) { - stat.resize(order.stats_size(), 0); + stat.resize(ctx.scorers.stats_size(), 0); auto* stats_buf = stat.data(); - term_stats.finish(stats_buf, term_idx++, field_stats, index); + term_stats.finish(stats_buf, term_idx++, field_stats, ctx.index); } - return memory::make_managed( - std::move(states), std::move(stats), boost, merge_type, min_match); + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), sub_boost, + merge_type, min_match); } } // namespace irs diff --git a/core/search/terms_filter.hpp b/core/search/terms_filter.hpp index f750ac09a..186d1f72b 100644 --- a/core/search/terms_filter.hpp +++ b/core/search/terms_filter.hpp @@ -90,11 +90,7 @@ class by_terms final : public filter_base, const by_terms_options::search_terms& terms, filter_visitor& visitor); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& order, - score_t boost, - const attribute_provider* /*ctx*/) const final; + filter::prepared::ptr prepare(const PrepareContext& ctx) const final; }; } // namespace irs diff --git a/core/search/tfidf.cpp b/core/search/tfidf.cpp index 441daabe0..285a1df8f 100644 --- a/core/search/tfidf.cpp +++ b/core/search/tfidf.cpp @@ -277,7 +277,7 @@ void TFIDF::collect(byte_type* stats_buf, const FieldCollector* field, // TODO(MBkkt) SEARCH-444 IRS_ASSERT(idf.value >= 0.f); } -void TFIDF::get_features(std::set& features) const { +void TFIDF::get_features(feature_set_t& features) const { if (normalize()) { features.emplace(irs::type::id()); } diff --git a/core/search/tfidf.hpp b/core/search/tfidf.hpp index 117f0f859..75b414e68 100644 --- a/core/search/tfidf.hpp +++ b/core/search/tfidf.hpp @@ -51,15 +51,15 @@ class TFIDF final : public irs::ScorerBase { return IndexFeatures::FREQ; } - void get_features(std::set& features) const final; + void get_features(feature_set_t& features) const final; FieldCollector::ptr prepare_field_collector() const final; - ScoreFunction prepare_scorer( - const ColumnProvider& segment, - const std::map& features, - const byte_type* stats_buf, const attribute_provider& doc_attrs, - score_t boost) const final; + ScoreFunction prepare_scorer(const ColumnProvider& segment, + const feature_map_t& features, + const byte_type* stats_buf, + const attribute_provider& doc_attrs, + score_t boost) const final; TermCollector::ptr prepare_term_collector() const final; diff --git a/core/search/wildcard_filter.cpp b/core/search/wildcard_filter.cpp index 2d3549d14..99110c45a 100644 --- a/core/search/wildcard_filter.cpp +++ b/core/search/wildcard_filter.cpp @@ -142,26 +142,22 @@ field_visitor by_wildcard::visitor(bytes_view term) { }); } -filter::prepared::ptr by_wildcard::prepare(const IndexReader& index, - const Scorers& order, score_t boost, +filter::prepared::ptr by_wildcard::prepare(const PrepareContext& ctx, std::string_view field, bytes_view term, size_t scored_terms_limit) { bstring buf; return executeWildcard( buf, term, []() -> filter::prepared::ptr { return prepared::empty(); }, - [&index, &order, boost, &field](bytes_view term) -> filter::prepared::ptr { - return by_term::prepare(index, order, boost, field, term); + [&](bytes_view term) -> filter::prepared::ptr { + return by_term::prepare(ctx, field, term); }, - [&index, &order, boost, &field, - scored_terms_limit](bytes_view term) -> filter::prepared::ptr { - return by_prefix::prepare(index, order, boost, field, term, - scored_terms_limit); + [&, scored_terms_limit](bytes_view term) -> filter::prepared::ptr { + return by_prefix::prepare(ctx, field, term, scored_terms_limit); }, - [&index, &order, boost, &field, - scored_terms_limit](bytes_view term) -> filter::prepared::ptr { - return prepare_automaton_filter(field, from_wildcard(term), - scored_terms_limit, index, order, boost); + [&, scored_terms_limit](bytes_view term) -> filter::prepared::ptr { + return prepare_automaton_filter(ctx, field, from_wildcard(term), + scored_terms_limit); }); } diff --git a/core/search/wildcard_filter.hpp b/core/search/wildcard_filter.hpp index 679d2fa35..32ce0296c 100644 --- a/core/search/wildcard_filter.hpp +++ b/core/search/wildcard_filter.hpp @@ -63,18 +63,14 @@ class by_wildcard final : public filter_base { public: static ptr make(); - static prepared::ptr prepare(const IndexReader& index, const Scorers& order, - score_t boost, std::string_view field, - bytes_view term, size_t scored_terms_limit); + static prepared::ptr prepare(const PrepareContext& ctx, + std::string_view field, bytes_view term, + size_t scored_terms_limit); static field_visitor visitor(bytes_view term); - using filter::prepare; - - filter::prepared::ptr prepare(const IndexReader& index, const Scorers& order, - score_t boost, - const attribute_provider* /*ctx*/) const final { - return prepare(index, order, this->boost() * boost, field(), options().term, + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { + return prepare(ctx.Boost(boost()), field(), options().term, options().scored_terms_limit); } }; diff --git a/core/store/fs_directory.cpp b/core/store/fs_directory.cpp index 0a2e6bc91..cb48add08 100644 --- a/core/store/fs_directory.cpp +++ b/core/store/fs_directory.cpp @@ -163,7 +163,8 @@ class fs_index_output : public buffered_index_output { DEFINE_FACTORY_INLINE(index_output) // cppcheck-suppress unknownMacro static index_output::ptr open(const path_char_t* name, - const ResourceManagementOptions& rm) noexcept { + const ResourceManagementOptions& rm) noexcept + try { IRS_ASSERT(name); size_t descriptors{1}; rm.file_descriptors->Increase(descriptors); @@ -181,13 +182,10 @@ class fs_index_output : public buffered_index_output { return nullptr; } - try { - auto res = fs_index_output::make(std::move(handle), rm); - descriptors = 0; - return res; - } catch (...) { - } - + auto res = fs_index_output::make(std::move(handle), rm); + descriptors = 0; + return res; + } catch (...) { return nullptr; } @@ -220,7 +218,7 @@ class fs_index_output : public buffered_index_output { private: fs_index_output(file_utils::handle_t&& handle, - const ResourceManagementOptions& rm) noexcept + const ResourceManagementOptions& rm) : handle_(std::move(handle)), rm_{rm} { IRS_ASSERT(handle_); rm_.transactions->Increase(sizeof(fs_index_output)); @@ -270,46 +268,45 @@ class fs_index_input : public buffered_index_input { static index_input::ptr open(const path_char_t* name, size_t pool_size, IOAdvice advice, - const ResourceManagementOptions& rm) noexcept { + const ResourceManagementOptions& rm) noexcept try { - IRS_ASSERT(name); - - size_t descriptors{1}; - rm.file_descriptors->Increase(descriptors); - irs::Finally cleanup = [&]() noexcept { - rm.file_descriptors->DecreaseChecked(descriptors); - }; - - auto handle = file_handle::make(rm); - handle->io_advice = advice; - handle->handle = - irs::file_utils::open(name, get_read_mode(handle->io_advice), - get_posix_fadvice(handle->io_advice)); - - if (nullptr == handle->handle) { - IRS_LOG_ERROR( - absl::StrCat("Failed to open input file, error: ", GET_ERROR(), - ", path: ", file_utils::ToStr(name))); - - return nullptr; - } - uint64_t size; - if (!file_utils::byte_size(size, *handle)) { - IRS_LOG_ERROR(absl::StrCat( - "Failed to get stat for input file, error: ", GET_ERROR(), - ", path: ", file_utils::ToStr(name))); + IRS_ASSERT(name); - return nullptr; - } + size_t descriptors{1}; + rm.file_descriptors->Increase(descriptors); + irs::Finally cleanup = [&]() noexcept { + rm.file_descriptors->DecreaseChecked(descriptors); + }; - handle->size = size; + auto handle = file_handle::make(rm); + handle->io_advice = advice; + handle->handle = + irs::file_utils::open(name, get_read_mode(handle->io_advice), + get_posix_fadvice(handle->io_advice)); + + if (nullptr == handle->handle) { + IRS_LOG_ERROR( + absl::StrCat("Failed to open input file, error: ", GET_ERROR(), + ", path: ", file_utils::ToStr(name))); - auto res = ptr(new fs_index_input(std::move(handle), pool_size)); - descriptors = 0; - return res; - } catch (...) { return nullptr; } + uint64_t size; + if (!file_utils::byte_size(size, *handle)) { + IRS_LOG_ERROR( + absl::StrCat("Failed to get stat for input file, error: ", GET_ERROR(), + ", path: ", file_utils::ToStr(name))); + + return nullptr; + } + + handle->size = size; + + auto res = ptr(new fs_index_input(std::move(handle), pool_size)); + descriptors = 0; + return res; + } catch (...) { + return nullptr; } size_t length() const final { return handle_->size; } @@ -377,9 +374,9 @@ class fs_index_input : public buffered_index_input { const ResourceManagementOptions& resource_manager; }; - fs_index_input(file_handle::ptr&& handle, size_t pool_size) noexcept; + fs_index_input(file_handle::ptr&& handle, size_t pool_size); - fs_index_input(const fs_index_input& rhs) noexcept; + fs_index_input(const fs_index_input& rhs); ~fs_index_input(); @@ -417,15 +414,14 @@ class pooled_fs_index_input final : public fs_index_input { file_handle::ptr reopen(const file_handle& src) const; }; -fs_index_input::fs_index_input(file_handle::ptr&& handle, - size_t pool_size) noexcept +fs_index_input::fs_index_input(file_handle::ptr&& handle, size_t pool_size) : handle_(std::move(handle)), pool_size_(pool_size), pos_(0) { IRS_ASSERT(handle_); - handle_->resource_manager.readers->Increase(sizeof(pooled_fs_index_input)); + handle_->resource_manager.readers->Increase(sizeof(fs_index_input)); buffered_index_input::reset(buf_, sizeof buf_, 0); } -fs_index_input::fs_index_input(const fs_index_input& rhs) noexcept +fs_index_input::fs_index_input(const fs_index_input& rhs) : handle_(rhs.handle_), pool_size_(rhs.pool_size_), pos_(rhs.file_pointer()) { IRS_ASSERT(handle_); handle_->resource_manager.readers->Increase(sizeof(pooled_fs_index_input)); diff --git a/core/utils/automaton_utils.cpp b/core/utils/automaton_utils.cpp index c4478a11c..6fc981578 100644 --- a/core/utils/automaton_utils.cpp +++ b/core/utils/automaton_utils.cpp @@ -388,9 +388,10 @@ void utf8_transitions_builder::finish(automaton& a, automaton::StateId from) { a.EmplaceArc(rho_states_[3], label, rho_states_[2]); } -filter::prepared::ptr prepare_automaton_filter( - std::string_view field, const automaton& acceptor, size_t scored_terms_limit, - const IndexReader& index, const Scorers& order, score_t boost) { +filter::prepared::ptr prepare_automaton_filter(const PrepareContext& ctx, + std::string_view field, + const automaton& acceptor, + size_t scored_terms_limit) { auto matcher = make_automaton_matcher(acceptor); if (fst::kError == matcher.Properties(0)) { @@ -405,26 +406,21 @@ filter::prepared::ptr prepare_automaton_filter( // object for collecting order stats limited_sample_collector collector( - order.empty() ? 0 : scored_terms_limit); - MultiTermQuery::States states{index.size()}; + ctx.scorers.empty() ? 0 : scored_terms_limit); + MultiTermQuery::States states{ctx.memory, ctx.index.size()}; multiterm_visitor mtv{collector, states}; - for (const auto& segment : index) { - // get term dictionary for field - const auto* reader = segment.field(field); - - if (!reader) { - continue; + for (const auto& segment : ctx.index) { + if (const auto* reader = segment.field(field); reader) { + visit(segment, *reader, matcher, mtv); } - - visit(segment, *reader, matcher, mtv); } - MultiTermQuery::Stats stats; - collector.score(index, order, stats); + MultiTermQuery::Stats stats{{ctx.memory}}; + collector.score(ctx.index, ctx.scorers, stats); - return memory::make_managed(std::move(states), - std::move(stats), boost, + return memory::make_tracked(ctx.memory, std::move(states), + std::move(stats), ctx.boost, ScoreMergeType::kSum, size_t{1}); } diff --git a/core/utils/automaton_utils.hpp b/core/utils/automaton_utils.hpp index 8f06ed15c..81ed01f11 100644 --- a/core/utils/automaton_utils.hpp +++ b/core/utils/automaton_utils.hpp @@ -475,8 +475,9 @@ inline automaton make_all() { /// @param bool query boost /// @returns compiled filter ////////////////////////////////////////////////////////////////////////////// -filter::prepared::ptr prepare_automaton_filter( - std::string_view field, const automaton& acceptor, size_t scored_terms_limit, - const IndexReader& index, const Scorers& order, score_t boost); +filter::prepared::ptr prepare_automaton_filter(const PrepareContext& ctx, + std::string_view field, + const automaton& acceptor, + size_t scored_terms_limit); } // namespace irs diff --git a/core/utils/container_utils.hpp b/core/utils/container_utils.hpp index eddfaddbf..9f7189a88 100644 --- a/core/utils/container_utils.hpp +++ b/core/utils/container_utils.hpp @@ -127,7 +127,7 @@ class raw_block_vector_base : private util::noncopyable { protected: IRS_NO_UNIQUE_ADDRESS ManagedTypedAllocator alloc_; - std::vector> buffers_; + ManagedVector buffers_; }; ////////////////////////////////////////////////////////////////////////////// diff --git a/core/utils/memory.hpp b/core/utils/memory.hpp index e0d137070..bd716b4b8 100644 --- a/core/utils/memory.hpp +++ b/core/utils/memory.hpp @@ -298,12 +298,14 @@ struct OnHeap final : Base { }; template -struct OnHeapTracked final : Base { +struct Tracked final : Base { static_assert(std::is_base_of_v); template - OnHeapTracked(IResourceManager& rm, Args&&... args) - : Base{std::forward(args)...}, rm_{rm} {} + Tracked(IResourceManager& rm, Args&&... args) + : Base{std::forward(args)...}, rm_{rm} { + rm.Increase(sizeof(*this)); + } private: void Destroy() const noexcept final { @@ -336,8 +338,7 @@ class managed_ptr final : std::unique_ptr { template friend managed_ptr make_managed(Args&&... args); template - friend managed_ptr make_tracked_managed(IResourceManager&, - Args&&... args); + friend managed_ptr make_tracked(IResourceManager&, Args&&... args); constexpr explicit managed_ptr(T* p) noexcept : Ptr{p} {} @@ -396,10 +397,9 @@ managed_ptr make_managed(Args&&... args) { } template -managed_ptr make_tracked_managed(IResourceManager& rm, Args&&... args) { - rm.Increase(sizeof(OnHeapTracked)); +managed_ptr make_tracked(IResourceManager& rm, Args&&... args) { return managed_ptr{ - new OnHeapTracked{rm, std::forward(args)...}}; + new Tracked{rm, std::forward(args)...}}; } template diff --git a/core/utils/mmap_utils.cpp b/core/utils/mmap_utils.cpp index 456b32211..438e88ba0 100644 --- a/core/utils/mmap_utils.cpp +++ b/core/utils/mmap_utils.cpp @@ -52,7 +52,7 @@ void mmap_handle::init() noexcept { dontneed_ = false; } -bool mmap_handle::open(const path_char_t* path) noexcept { +bool mmap_handle::open(const path_char_t* path) noexcept try { IRS_ASSERT(path); close(); @@ -99,6 +99,8 @@ bool mmap_handle::open(const path_char_t* path) noexcept { } return true; +} catch (...) { + return false; } } // namespace irs::mmap_utils diff --git a/tests/search/all_filter_tests.cpp b/tests/search/all_filter_tests.cpp index e2ea2f64e..54a71768d 100644 --- a/tests/search/all_filter_tests.cpp +++ b/tests/search/all_filter_tests.cpp @@ -51,7 +51,10 @@ TEST_P(all_filter_test_case, all_sequential) { CheckQuery(irs::all(), docs, cost, rdr); // check iterator attributes, no order - auto it = irs::all().prepare(*rdr)->execute(segment); + MaxMemoryCounter counter; + auto it = irs::all() + .prepare({.index = *rdr, .memory = counter}) + ->execute({.segment = segment}); ASSERT_TRUE(irs::get(*it)); auto* it_cost = irs::get(*it); ASSERT_TRUE(it_cost); @@ -59,6 +62,9 @@ TEST_P(all_filter_test_case, all_sequential) { auto& score = irs::score::get(*it); ASSERT_TRUE(score.Func() == &irs::ScoreFunction::DefaultScore); ASSERT_EQ(&score, irs::get_mutable(it.get())); + it.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); } TEST_P(all_filter_test_case, all_order) { diff --git a/tests/search/bm25_test.cpp b/tests/search/bm25_test.cpp index 14dda2c19..910f1d1ef 100644 --- a/tests/search/bm25_test.cpp +++ b/tests/search/bm25_test.cpp @@ -121,6 +121,9 @@ void bm25_test_case::test_query_norms(irs::type_info::type_id norm, auto& segment = *(reader.begin()); const auto* column = segment.column("seq"); ASSERT_NE(nullptr, column); + + MaxMemoryCounter counter; + // by_range multiple { auto values = column->iterator(irs::ColumnHint::kNormal); @@ -141,8 +144,13 @@ void bm25_test_case::test_query_norms(irs::type_info::type_id norm, constexpr std::array expected{7, 3, 0, 1, 5}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -164,6 +172,9 @@ void bm25_test_case::test_query_norms(irs::type_info::type_id norm, ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range multiple (3 values) { @@ -187,8 +198,13 @@ void bm25_test_case::test_query_norms(irs::type_info::type_id norm, : std::array{7, 0, 5, 3, 2, 1}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); while (docs->next()) { @@ -209,6 +225,9 @@ void bm25_test_case::test_query_norms(irs::type_info::type_id norm, ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(bm25_test_case, consts) { @@ -387,6 +406,8 @@ TEST_P(bm25_test_case, test_phrase) { ASSERT_EQ(1, index->size()); auto& segment = *(index.begin()); + MaxMemoryCounter counter; + // "jumps high" with order { irs::by_phrase filter; @@ -404,8 +425,13 @@ TEST_P(bm25_test_case, test_phrase) { "Q", // jumps high jumps left jumps right jumps down walks back "R"}; // jumps high jumps left jumps right walks down walks back - auto prepared_filter = filter.prepare(*index, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -432,6 +458,9 @@ TEST_P(bm25_test_case, test_phrase) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // "cookies ca* p_e bisKuit meringue|marshmallows" with order { @@ -462,8 +491,13 @@ TEST_P(bm25_test_case, test_phrase) { "SPWLC2", // cookies cake pie biscwit meringue pie biscuit paste "SPWLC3"}; // cookies cake pie biscuet marshmallows cake meringue - auto prepared_filter = filter.prepare(*index, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -490,6 +524,9 @@ TEST_P(bm25_test_case, test_phrase) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(bm25_test_case, test_query) { @@ -518,6 +555,9 @@ TEST_P(bm25_test_case, test_query) { auto& segment = *(reader.begin()); const auto* column = segment.column("seq"); ASSERT_NE(nullptr, column); + + MaxMemoryCounter counter; + // by_term { auto values = column->iterator(irs::ColumnHint::kNormal); @@ -534,8 +574,13 @@ TEST_P(bm25_test_case, test_query) { constexpr std::array expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -557,6 +602,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by term multi-segment, same term (same score for all docs) { @@ -618,7 +666,11 @@ TEST_P(bm25_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -627,7 +679,8 @@ TEST_P(bm25_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -650,6 +703,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_term disjunction multi-segment, different terms (same score for all // docs) @@ -723,7 +779,11 @@ TEST_P(bm25_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -732,7 +792,8 @@ TEST_P(bm25_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -755,6 +816,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_prefix empty multi-segment, different terms (same score for all docs) { @@ -818,7 +882,11 @@ TEST_P(bm25_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -827,7 +895,8 @@ TEST_P(bm25_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -850,6 +919,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range single { @@ -871,8 +943,13 @@ TEST_P(bm25_test_case, test_query) { constexpr std::array expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); while (docs->next()) { @@ -893,6 +970,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range single + scored_terms_limit(1) { @@ -915,8 +995,13 @@ TEST_P(bm25_test_case, test_query) { constexpr std::array expected{3, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -938,6 +1023,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // FIXME!!! // // by_range single + scored_terms_limit(0) @@ -957,8 +1045,9 @@ TEST_P(bm25_test_case, test_query) { // constexpr std::array expected{ 3, 7 }; // // irs::bytes_view_input in; - // auto prepared_filter = filter.prepare(reader, prepared_order); - // auto docs = prepared_filter->execute(segment, prepared_order); + // auto prepared_filter = filter.prepare({.index=reader, + // .scorers=prepared_order}); auto docs = + // prepared_filter->execute({.segment=segment, .scorers=prepared_order}); // auto* score = irs::get(*docs); // ASSERT_TRUE(bool(score)); // @@ -1001,8 +1090,13 @@ TEST_P(bm25_test_case, test_query) { constexpr std::array expected{7, 3, 0, 1, 5}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); while (docs->next()) { @@ -1023,6 +1117,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range multiple (3 values) { @@ -1044,8 +1141,13 @@ TEST_P(bm25_test_case, test_query) { constexpr std::array expected{7, 0, 5, 3, 2, 1}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1067,6 +1169,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by phrase { @@ -1089,8 +1194,13 @@ TEST_P(bm25_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); while (docs->next()) { @@ -1112,6 +1222,9 @@ TEST_P(bm25_test_case, test_query) { ASSERT_EQ(expected_entry.second, entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all { @@ -1123,8 +1236,13 @@ TEST_P(bm25_test_case, test_query) { irs::all filter; filter.boost(1.5f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1139,6 +1257,9 @@ TEST_P(bm25_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all { @@ -1150,8 +1271,13 @@ TEST_P(bm25_test_case, test_query) { irs::all filter; filter.boost(0.f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_TRUE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1168,6 +1294,9 @@ TEST_P(bm25_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // column existence { @@ -1180,8 +1309,13 @@ TEST_P(bm25_test_case, test_query) { *filter.mutable_field() = "seq"; filter.mutable_options()->acceptor = {}; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_FALSE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1198,6 +1332,9 @@ TEST_P(bm25_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // column existence { @@ -1211,8 +1348,13 @@ TEST_P(bm25_test_case, test_query) { filter.mutable_options()->acceptor = {}; filter.boost(0.f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_TRUE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1230,6 +1372,9 @@ TEST_P(bm25_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(bm25_test_case, test_query_norms) { @@ -1509,6 +1654,8 @@ TEST_P(bm25_test_case, test_order) { auto reader = irs::DirectoryReader(dir(), codec()); auto& segment = *(reader.begin()); + MaxMemoryCounter counter; + irs::by_term query; *query.mutable_field() = "field"; @@ -1541,11 +1688,14 @@ TEST_P(bm25_test_case, test_order) { constexpr std::array expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared = - boost == irs::kNoBoost - ? query.prepare(reader, prepared_order) - : query.prepare(reader, prepared_order, boost, nullptr); - auto docs = prepared->execute(segment, prepared_order); + auto prepared = query.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + .boost = boost, + }); + auto docs = + prepared->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1567,6 +1717,9 @@ TEST_P(bm25_test_case, test_order) { [](const auto& lhs, uint64_t rhs) { return lhs.second == rhs; }); EXPECT_TRUE(eq); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } } } diff --git a/tests/search/boolean_filter_tests.cpp b/tests/search/boolean_filter_tests.cpp index 3e1c173ff..341a3e9cd 100644 --- a/tests/search/boolean_filter_tests.cpp +++ b/tests/search/boolean_filter_tests.cpp @@ -260,10 +260,9 @@ struct boosted : public irs::filter { }; irs::filter::prepared::ptr prepare( - const irs::IndexReader&, const irs::Scorers&, irs::score_t boost, - const irs::attribute_provider* /*ctx*/) const final { + const irs::PrepareContext& ctx) const final { return irs::memory::make_managed(docs, - this->boost() * boost); + ctx.boost * boost()); } irs::type_info::type_id type() const noexcept final { @@ -324,9 +323,11 @@ TEST(boolean_query_boost, hierarchy) { sub.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -409,9 +410,11 @@ TEST(boolean_query_boost, hierarchy) { node.docs = {1, 2, 3}; } - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -505,9 +508,11 @@ TEST(boolean_query_boost, hierarchy) { node.docs = {1, 2, 3}; } - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -552,7 +557,7 @@ TEST(boolean_query_boost, and_filter) { { irs::And root; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prep->boost()); } @@ -564,7 +569,7 @@ TEST(boolean_query_boost, and_filter) { irs::And root; root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prep->boost()); } @@ -583,9 +588,11 @@ TEST(boolean_query_boost, and_filter) { node.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -611,9 +618,11 @@ TEST(boolean_query_boost, and_filter) { } root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -649,9 +658,11 @@ TEST(boolean_query_boost, and_filter) { } root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -699,8 +710,10 @@ TEST(boolean_query_boost, and_filter) { node.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -746,8 +759,10 @@ TEST(boolean_query_boost, and_filter) { node.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -791,8 +806,10 @@ TEST(boolean_query_boost, and_filter) { node.boost(0.f); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -815,7 +832,7 @@ TEST(boolean_query_boost, or_filter) { { irs::Or root; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prep->boost()); } @@ -827,7 +844,7 @@ TEST(boolean_query_boost, or_filter) { irs::Or root; root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prep->boost()); } @@ -846,8 +863,10 @@ TEST(boolean_query_boost, or_filter) { } root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -878,9 +897,11 @@ TEST(boolean_query_boost, or_filter) { } root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -916,8 +937,10 @@ TEST(boolean_query_boost, or_filter) { } root.boost(value); - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -978,8 +1001,10 @@ TEST(boolean_query_boost, or_filter) { node.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -1038,8 +1063,10 @@ TEST(boolean_query_boost, or_filter) { node.boost(value); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -1095,8 +1122,10 @@ TEST(boolean_query_boost, or_filter) { node.boost(0.f); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); @@ -1160,9 +1189,8 @@ struct unestimated : public irs::filter { } }; - filter::prepared::ptr prepare(const irs::IndexReader&, const irs::Scorers&, - irs::score_t, - const irs::attribute_provider*) const final { + filter::prepared::ptr prepare( + const irs::PrepareContext& /*ctx*/) const final { return irs::memory::make_managed(); } @@ -1217,9 +1245,8 @@ struct estimated : public irs::filter { irs::cost::cost_t est; }; - filter::prepared::ptr prepare(const irs::IndexReader&, const irs::Scorers&, - irs::score_t, - const irs::attribute_provider*) const final { + filter::prepared::ptr prepare( + const irs::PrepareContext& /*ctx*/) const final { return irs::memory::make_managed(est, &evaluated); } @@ -1234,6 +1261,8 @@ struct estimated : public irs::filter { } // namespace detail TEST(boolean_query_estimation, or_filter) { + MaxMemoryCounter counter; + // estimated subqueries { irs::Or root; @@ -1243,9 +1272,12 @@ TEST(boolean_query_estimation, or_filter) { root.add().est = 1; root.add().est = 100; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were not estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1263,6 +1295,9 @@ TEST(boolean_query_estimation, or_filter) { ASSERT_TRUE(est_query->evaluated); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // unestimated subqueries { @@ -1272,9 +1307,9 @@ TEST(boolean_query_estimation, or_filter) { root.add(); root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ(0, irs::cost::extract(*docs)); } @@ -1290,9 +1325,9 @@ TEST(boolean_query_estimation, or_filter) { root.add().est = 100; root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); /* check that subqueries were not estimated */ for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1334,9 +1369,10 @@ TEST(boolean_query_estimation, or_filter) { const irs::Scorer* sort{&impl}; auto pord = irs::Scorers::Prepare(std::span{&sort, 1}); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were not estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1361,9 +1397,9 @@ TEST(boolean_query_estimation, or_filter) { { irs::Or root; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ(0, irs::cost::extract(*docs)); } } @@ -1378,9 +1414,9 @@ TEST(boolean_query_estimation, and_filter) { root.add().est = 1; root.add().est = 100; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1401,9 +1437,9 @@ TEST(boolean_query_estimation, and_filter) { root.add(); root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1429,9 +1465,9 @@ TEST(boolean_query_estimation, and_filter) { root.add().est = 100; root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1459,9 +1495,9 @@ TEST(boolean_query_estimation, and_filter) { root.add().filter().est = 0; root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); // check that subqueries were estimated for (auto it = root.begin(), end = root.end(); it != end; ++it) { @@ -1477,9 +1513,9 @@ TEST(boolean_query_estimation, and_filter) { // empty case { irs::And root; - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - auto docs = prep->execute(irs::SubReader::empty()); + auto docs = prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ(0, irs::cost::extract(*docs)); } } @@ -15493,10 +15529,10 @@ TEST_P(boolean_filter_test_case, or_sequential_multiple_segments) { append(root, "name", "F"); append(root, "name", "I"); - auto prep = root.prepare(rdr); + auto prep = root.prepare({.index = rdr}); auto segment = rdr.begin(); { - auto docs = prep->execute(*segment); + auto docs = prep->execute({.segment = *segment}); ASSERT_TRUE(docs->next()); ASSERT_EQ(2, docs->value()); ASSERT_FALSE(docs->next()); @@ -15504,7 +15540,7 @@ TEST_P(boolean_filter_test_case, or_sequential_multiple_segments) { ++segment; { - auto docs = prep->execute(*segment); + auto docs = prep->execute({.segment = *segment}); ASSERT_TRUE(docs->next()); ASSERT_EQ(2, docs->value()); ASSERT_FALSE(docs->next()); @@ -15512,7 +15548,7 @@ TEST_P(boolean_filter_test_case, or_sequential_multiple_segments) { ++segment; { - auto docs = prep->execute(*segment); + auto docs = prep->execute({.segment = *segment}); ASSERT_TRUE(docs->next()); ASSERT_EQ(2, docs->value()); ASSERT_FALSE(docs->next()); @@ -15889,13 +15925,15 @@ TEST_P(boolean_filter_test_case, not_standalone_sequential_ordered) { }; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared_filter = not_node.prepare(*rdr, prepared_order); + auto prepared_filter = + not_node.prepare({.index = *rdr, .scorers = prepared_order}); std::multimap> scored_result; ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; - auto filter_itr = prepared_filter->execute(segment, prepared_order); + auto filter_itr = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); ASSERT_EQ(32, irs::cost::extract(*filter_itr)); size_t docs_count = 0; @@ -15980,13 +16018,15 @@ TEST_P(boolean_filter_test_case, not_sequential_ordered) { }; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared_filter = root.prepare(*rdr, prepared_order); + auto prepared_filter = + root.prepare({.index = *rdr, .scorers = prepared_order}); std::multimap> scored_result; ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; - auto filter_itr = prepared_filter->execute(segment, prepared_order); + auto filter_itr = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); ASSERT_EQ(32, irs::cost::extract(*filter_itr)); size_t docs_count = 0; @@ -16433,7 +16473,7 @@ TEST_P(boolean_filter_test_case, mixed_ordered) { ASSERT_FALSE(prepared_ord.empty()); ASSERT_EQ(2, prepared_ord.buckets().size()); - auto prepared = root.prepare(*rdr, prepared_ord); + auto prepared = root.prepare({.index = *rdr, .scorers = prepared_ord}); ASSERT_NE(nullptr, prepared); std::vector expected_docs{ @@ -16442,7 +16482,7 @@ TEST_P(boolean_filter_test_case, mixed_ordered) { auto expected_doc = expected_docs.begin(); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_ord); + auto docs = prepared->execute({.segment = sub, .scorers = prepared_ord}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -16568,13 +16608,13 @@ TEST(And_test, optimize_double_negation) { root.add().filter().filter() = make_filter("test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } TEST(And_test, prepare_empty_filter) { irs::And root; - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, prepared); ASSERT_EQ(typeid(irs::filter::prepared::empty().get()), typeid(prepared.get())); @@ -16586,7 +16626,7 @@ TEST(And_test, optimize_single_node) { irs::And root; append(root, "test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } @@ -16596,7 +16636,7 @@ TEST(And_test, optimize_single_node) { root.add().add().add() = make_filter("test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } } @@ -16607,9 +16647,10 @@ TEST(And_test, optimize_all_filters) { irs::And root; root.add().boost(5.f); - auto prepared = root.prepare(irs::SubReader::empty()); - ASSERT_EQ(typeid(irs::all().prepare(irs::SubReader::empty()).get()), - typeid(prepared.get())); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); + ASSERT_EQ( + typeid(irs::all().prepare({.index = irs::SubReader::empty()}).get()), + typeid(prepared.get())); ASSERT_EQ(5.f, prepared->boost()); } @@ -16620,9 +16661,10 @@ TEST(And_test, optimize_all_filters) { root.add().boost(2.f); root.add().boost(3.f); - auto prepared = root.prepare(irs::SubReader::empty()); - ASSERT_EQ(typeid(irs::all().prepare(irs::SubReader::empty()).get()), - typeid(prepared.get())); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); + ASSERT_EQ( + typeid(irs::all().prepare({.index = irs::SubReader::empty()}).get()), + typeid(prepared.get())); ASSERT_EQ(10.f, prepared->boost()); } @@ -16635,7 +16677,8 @@ TEST(And_test, optimize_all_filters) { tests::sort::boost sort{}; auto pord = irs::Scorers::Prepare(sort); - auto prepared = root.prepare(irs::SubReader::empty(), pord); + auto prepared = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); ASSERT_EQ(8.f, prepared->boost()); } @@ -16647,7 +16690,8 @@ TEST(And_test, optimize_all_filters) { append(root, "test_field", "test_term"); root.add().boost(5.f); auto pord = irs::Scorers::Prepare(sort); - auto prepared = root.prepare(irs::SubReader::empty(), pord); + auto prepared = + root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); ASSERT_EQ(6.f, prepared->boost()); } @@ -16668,8 +16712,9 @@ TEST(And_test, not_boosted) { node.docs = {1}; node.boost(5); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); auto* doc = irs::get(*docs); @@ -16755,7 +16800,7 @@ TEST(Or_test, optimize_double_negation) { auto& term = root.add().filter().filter() = make_filter("test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } @@ -16765,7 +16810,7 @@ TEST(Or_test, optimize_single_node) { irs::Or root; append(root, "test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } @@ -16775,7 +16820,7 @@ TEST(Or_test, optimize_single_node) { root.add().add().add() = make_filter("test_field", "test_term"); - auto prepared = root.prepare(irs::SubReader::empty()); + auto prepared = root.prepare({.index = irs::SubReader::empty()}); ASSERT_NE(nullptr, dynamic_cast(prepared.get())); } } @@ -16800,9 +16845,9 @@ TEST(Or_test, optimize_all_unscored) { root.add(); root.add(); - auto prep = root.prepare(irs::SubReader::empty(), irs::Scorers::kUnordered); + auto prep = root.prepare({.index = irs::SubReader::empty()}); - prep->execute(irs::SubReader::empty()); + prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ( 0, detail::boosted::execute_count); // specific filters should be opt out } @@ -16828,9 +16873,9 @@ TEST(Or_test, optimize_all_scored) { root.add(); tests::sort::boost sort{}; auto pord = irs::Scorers::Prepare(sort); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - prep->execute(irs::SubReader::empty()); + prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ(3, detail::boosted::execute_count); // specific filters should // executed as score needs them } @@ -16843,9 +16888,9 @@ TEST(Or_test, optimize_only_all_boosted) { root.add().boost(3); root.add().boost(5); - auto prep = root.prepare(irs::SubReader::empty(), pord); + auto prep = root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); - prep->execute(irs::SubReader::empty()); + prep->execute({.segment = irs::SubReader::empty()}); ASSERT_EQ(16, prep->boost()); } @@ -16864,8 +16909,9 @@ TEST(Or_test, boosted_not) { node.docs = {1}; node.boost(5); } - auto prep = root.prepare(irs::SubReader::empty(), pord); - auto docs = prep->execute(irs::SubReader::empty(), pord); + auto prep = root.prepare({.index = irs::SubReader::empty(), .scorers = pord}); + auto docs = + prep->execute({.segment = irs::SubReader::empty(), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); auto* doc = irs::get(*docs); diff --git a/tests/search/column_existence_filter_test.cpp b/tests/search/column_existence_filter_test.cpp index 15b6b0acb..11c65b553 100644 --- a/tests/search/column_existence_filter_test.cpp +++ b/tests/search/column_existence_filter_test.cpp @@ -79,13 +79,18 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // 'prefix' column { const std::string column_name = "prefix"; irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -93,7 +98,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); auto* doc = irs::get(*filter_it); ASSERT_TRUE(bool(doc)); @@ -107,6 +112,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'name' column { @@ -114,7 +122,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -122,7 +133,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -139,6 +150,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'seq' column { @@ -146,7 +160,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -154,7 +171,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); size_t docs_count = 0; @@ -167,6 +184,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'same' column { @@ -174,7 +194,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -182,7 +205,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -198,6 +221,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'value' column { @@ -205,7 +231,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -213,7 +242,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -225,6 +254,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'duplicated' column { @@ -232,7 +264,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -240,7 +275,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -252,6 +287,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // invalid column { @@ -259,12 +297,15 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(0, irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -273,6 +314,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(irs::doc_limits::eof(), filter_it->value()); ASSERT_FALSE(filter_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void simple_sequential_exact_match() { @@ -285,13 +329,18 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // 'prefix' column { const std::string column_name = "prefix"; irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -299,7 +348,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); auto* doc = irs::get(*filter_it); ASSERT_TRUE(bool(doc)); @@ -313,6 +362,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'name' column { @@ -320,7 +372,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -328,7 +383,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -345,6 +400,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'seq' column { @@ -352,7 +410,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -360,7 +421,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); size_t docs_count = 0; @@ -373,6 +434,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'same' column { @@ -380,7 +444,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -388,7 +455,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -404,6 +471,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(segment.docs_count(), docs_count); ASSERT_EQ(segment.live_docs_count(), docs_count); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'value' column { @@ -411,7 +481,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -419,7 +492,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -431,6 +504,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'duplicated' column { @@ -438,7 +514,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -446,7 +525,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kNormal); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -458,6 +537,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_FALSE(column_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // invalid column { @@ -465,12 +547,15 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_name, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(0, irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -479,6 +564,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(irs::doc_limits::eof(), filter_it->value()); ASSERT_FALSE(filter_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void simple_sequential_prefix_match() { @@ -492,13 +580,18 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // looking for 'foo*' columns { const std::string column_prefix = "foo"; irs::by_column_existence filter = make_filter(column_prefix, true); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -509,7 +602,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto* value = irs::get(*values); ASSERT_NE(nullptr, value); - auto it = prepared->execute(segment); + auto it = prepared->execute({.segment = segment}); auto* doc = irs::get(*it); ASSERT_TRUE(bool(doc)); @@ -558,6 +651,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ("%", irs::to_string(value->value.data())); ASSERT_FALSE(it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // looking for 'koob*' columns { @@ -565,7 +661,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_prefix, true); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -576,7 +675,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto* value = irs::get(*values); ASSERT_NE(nullptr, value); - auto it = prepared->execute(segment); + auto it = prepared->execute({.segment = segment}); auto* doc = irs::get(*it); ASSERT_TRUE(bool(doc)); @@ -601,6 +700,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ("Z", irs::to_string(value->value.data())); ASSERT_FALSE(it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // looking for 'oob*' columns { @@ -608,7 +710,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_prefix, true); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -619,7 +724,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto* value = irs::get(*values); ASSERT_NE(nullptr, value); - auto it = prepared->execute(segment); + auto it = prepared->execute({.segment = segment}); auto* doc = irs::get(*it); ASSERT_TRUE(bool(doc)); @@ -644,6 +749,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ("$", irs::to_string(value->value.data())); ASSERT_FALSE(it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // looking for 'collection*' columns { @@ -651,7 +759,10 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_prefix, true); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -662,7 +773,7 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto* value = irs::get(*values); ASSERT_NE(nullptr, value); - auto it = prepared->execute(segment); + auto it = prepared->execute({.segment = segment}); auto* doc = irs::get(*it); ASSERT_TRUE(bool(doc)); @@ -684,6 +795,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ("N", irs::to_string(value->value.data())); ASSERT_FALSE(it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // invalid prefix { @@ -691,12 +805,15 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { irs::by_column_existence filter = make_filter(column_prefix, true); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); ASSERT_EQ(0, irs::cost::extract(*filter_it)); auto* doc = irs::get(*filter_it); @@ -705,6 +822,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(irs::doc_limits::eof(), filter_it->value()); ASSERT_FALSE(filter_it->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void simple_sequential_order() { @@ -717,6 +837,8 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // 'seq' column { const std::string column_name = "seq"; @@ -753,7 +875,11 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { }; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared_filter = filter.prepare(*rdr, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *rdr, + .memory = counter, + .scorers = prepared_order, + }); std::multimap scored_result; ASSERT_EQ(1, rdr->size()); @@ -762,7 +888,8 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_itr = column->iterator(irs::ColumnHint::kNormal); - auto filter_itr = prepared_filter->execute(segment, prepared_order); + auto filter_itr = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_itr)); auto* doc = irs::get(*filter_itr); @@ -806,6 +933,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 'seq*' column (prefix single) { @@ -843,7 +973,11 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { }; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared_filter = filter.prepare(*rdr, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *rdr, + .memory = counter, + .scorers = prepared_order, + }); std::multimap scored_result; ASSERT_EQ(1, rdr->size()); @@ -852,7 +986,8 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name); ASSERT_NE(nullptr, column); auto column_itr = column->iterator(irs::ColumnHint::kNormal); - auto filter_itr = prepared_filter->execute(segment, prepared_order); + auto filter_itr = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); ASSERT_EQ(column->size(), irs::cost::extract(*filter_itr)); size_t docs_count = 0; @@ -894,6 +1029,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // 's*' column (prefix multiple) { @@ -932,7 +1070,11 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { }; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared_filter = filter.prepare(*rdr, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *rdr, + .memory = counter, + .scorers = prepared_order, + }); std::multimap scored_result; ASSERT_EQ(1, rdr->size()); @@ -941,7 +1083,8 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { auto column = segment.column(column_name_full); ASSERT_NE(nullptr, column); auto column_itr = column->iterator(irs::ColumnHint::kNormal); - auto filter_itr = prepared_filter->execute(segment, prepared_order); + auto filter_itr = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); ASSERT_EQ(column->size() * 2, irs::cost::extract(*filter_itr)); // 2 columns matched @@ -982,6 +1125,9 @@ class column_existence_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } }; @@ -1449,6 +1595,9 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { } auto rdr = open_reader(); + + MaxMemoryCounter counter; + using seek_type = std::tuple; // doing a long (>512) jump to trigger the issue const seek_type seeks[] = {{527, 543}}; @@ -1457,7 +1606,10 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { // target, expected seek result irs::by_column_existence filter = make_filter(target, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -1465,7 +1617,7 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { auto column = segment.column(target); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kPrevDoc); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); auto* doc = irs::get(*filter_it); ASSERT_TRUE(bool(doc)); @@ -1479,11 +1631,18 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { ASSERT_EQ(std::get<1>(seek), doc->value); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); + // seek pattern check { irs::by_column_existence filter = make_filter(target, false); - auto prepared = filter.prepare(*rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(1, rdr->size()); auto& segment = (*rdr)[0]; @@ -1491,7 +1650,7 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { auto column = segment.column(target); ASSERT_NE(nullptr, column); auto column_it = column->iterator(irs::ColumnHint::kPrevDoc); - auto filter_it = prepared->execute(segment); + auto filter_it = prepared->execute({.segment = segment}); auto* doc = irs::get(*filter_it); ASSERT_TRUE(bool(doc)); @@ -1505,6 +1664,9 @@ TEST_P(column_existence_long_filter_test_case, mixed_seeks) { ASSERT_EQ(std::get<1>(seek), doc->value); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } static constexpr auto kTestDirs = tests::getDirectories(); diff --git a/tests/search/filter_test_case_base.cpp b/tests/search/filter_test_case_base.cpp index 392a77f96..3df433765 100644 --- a/tests/search/filter_test_case_base.cpp +++ b/tests/search/filter_test_case_base.cpp @@ -35,9 +35,9 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, result_costs.reserve(rdr.size()); for (const auto& sub : rdr) { - auto random_docs = q->execute(sub); + auto random_docs = q->execute({.segment = sub}); ASSERT_NE(nullptr, random_docs); - auto sequential_docs = q->execute(sub); + auto sequential_docs = q->execute({.segment = sub}); ASSERT_NE(nullptr, sequential_docs); auto* doc = irs::get(*sequential_docs); @@ -46,7 +46,7 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, result_costs.emplace_back(irs::cost::extract(*sequential_docs)); while (sequential_docs->next()) { - auto stateless_random_docs = q->execute(sub); + auto stateless_random_docs = q->execute({.segment = sub}); ASSERT_NE(nullptr, stateless_random_docs); ASSERT_EQ(sequential_docs->value(), doc->value); ASSERT_EQ(doc->value, random_docs->seek(doc->value)); @@ -66,8 +66,8 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, ASSERT_TRUE(irs::doc_limits::eof(doc->value)); // seek to eof - ASSERT_TRUE( - irs::doc_limits::eof(q->execute(sub)->seek(irs::doc_limits::eof()))); + ASSERT_TRUE(irs::doc_limits::eof( + q->execute({.segment = sub})->seek(irs::doc_limits::eof()))); } } @@ -80,9 +80,9 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, result_costs.reserve(rdr.size()); for (const auto& sub : rdr) { - auto random_docs = q->execute(sub, ord); + auto random_docs = q->execute({.segment = sub, .scorers = ord}); ASSERT_NE(nullptr, random_docs); - auto sequential_docs = q->execute(sub, ord); + auto sequential_docs = q->execute({.segment = sub, .scorers = ord}); ASSERT_NE(nullptr, sequential_docs); auto* doc = irs::get(*sequential_docs); @@ -103,7 +103,7 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, }; while (sequential_docs->next()) { - auto stateless_random_docs = q->execute(sub, ord); + auto stateless_random_docs = q->execute({.segment = sub, .scorers = ord}); ASSERT_NE(nullptr, stateless_random_docs); ASSERT_EQ(sequential_docs->value(), doc->value); ASSERT_EQ(doc->value, random_docs->seek(doc->value)); @@ -129,8 +129,8 @@ void FilterTestCaseBase::GetQueryResult(const irs::filter::prepared::ptr& q, ASSERT_TRUE(irs::doc_limits::eof(doc->value)); // seek to eof - ASSERT_TRUE( - irs::doc_limits::eof(q->execute(sub)->seek(irs::doc_limits::eof()))); + ASSERT_TRUE(irs::doc_limits::eof( + q->execute({.segment = sub})->seek(irs::doc_limits::eof()))); } } @@ -142,8 +142,8 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, SCOPED_TRACE(source_location); Docs result; Costs result_costs; - GetQueryResult(filter.prepare(index, irs::Scorers::kUnordered), index, result, - result_costs, source_location); + GetQueryResult(filter.prepare({.index = index}), index, result, result_costs, + source_location); ASSERT_EQ(expected, result); ASSERT_EQ(expected_costs, result_costs); } @@ -155,7 +155,7 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, std::string_view source_location) { SCOPED_TRACE(source_location); auto ord = irs::Scorers::Prepare(order); - auto q = filter.prepare(rdr, ord); + auto q = filter.prepare({.index = rdr, .scorers = ord}); ASSERT_NE(nullptr, q); auto assert_equal_scores = [&](const std::vector& expected, @@ -202,7 +202,7 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, auto test = std::begin(tests); for (const auto& sub : rdr) { ASSERT_NE(test, std::end(tests)); - auto random_docs = q->execute(sub, ord); + auto random_docs = q->execute({.segment = sub, .scorers = ord}); ASSERT_NE(nullptr, random_docs); for (auto& test : *test) { @@ -222,8 +222,8 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, ScoredDocs result; Costs result_costs; auto prepared = irs::Scorers::Prepare(order); - GetQueryResult(filter.prepare(index, prepared), index, prepared, result, - result_costs, source_location); + GetQueryResult(filter.prepare({.index = index, .scorers = prepared}), index, + prepared, result, result_costs, source_location); ASSERT_EQ(expected, result); } @@ -234,8 +234,8 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, SCOPED_TRACE(source_location); Docs result; Costs result_costs; - GetQueryResult(filter.prepare(index, irs::Scorers::kUnordered), index, result, - result_costs, source_location); + GetQueryResult(filter.prepare({.index = index}), index, result, result_costs, + source_location); ASSERT_EQ(expected, result); } @@ -245,7 +245,8 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, const irs::IndexReader& rdr, bool score_must_be_present, bool reverse) { auto prepared_order = irs::Scorers::Prepare(order); - auto prepared_filter = filter.prepare(rdr, prepared_order); + auto prepared_filter = + filter.prepare({.index = rdr, .scorers = prepared_order}); auto score_less = [reverse, size = prepared_order.buckets().size()]( const std::pair& lhs, @@ -275,7 +276,8 @@ void FilterTestCaseBase::CheckQuery(const irs::filter& filter, scored_result{score_less}; for (const auto& sub : rdr) { - auto docs = prepared_filter->execute(sub, prepared_order); + auto docs = + prepared_filter->execute({.segment = sub, .scorers = prepared_order}); auto* doc = irs::get(*docs); // ensure all iterators contain "document" attribute diff --git a/tests/search/granular_range_filter_tests.cpp b/tests/search/granular_range_filter_tests.cpp index 88e4b16d1..20c518640 100644 --- a/tests/search/granular_range_filter_tests.cpp +++ b/tests/search/granular_range_filter_tests.cpp @@ -133,6 +133,8 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { auto& segment = (*rdr)[0]; + MaxMemoryCounter counter; + // without boost { irs::by_granular_range q; @@ -146,9 +148,15 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { q.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -165,7 +173,7 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; q.boost(boost); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({.index = segment}); ASSERT_EQ(boost, prepared->boost()); } } @@ -200,13 +208,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(2, query.options().range.min.size()); ASSERT_EQ(2, query.options().range.max.size()); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -236,13 +244,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(2, query.options().range.min.size()); ASSERT_EQ(2, query.options().range.max.size()); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 11, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -268,13 +276,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6, 7, 10, 11, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -299,13 +307,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -326,13 +334,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { irs::set_granular_term(query.mutable_options()->range.min, min_stream); query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{2, 3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -353,13 +361,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { irs::set_granular_term(query.mutable_options()->range.min, min_stream); query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -384,13 +392,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 9, 10, 11, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -411,13 +419,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { irs::set_granular_term(query.mutable_options()->range.max, max_stream); query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 9, 10, 11, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -433,14 +441,14 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { irs::by_granular_range query; *query.mutable_field() = "value"; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -484,13 +492,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -522,13 +530,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{2, 3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -555,13 +563,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -589,13 +597,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{30, 31, 32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -623,13 +631,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -657,13 +665,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -695,13 +703,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -733,13 +741,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{2, 3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -766,13 +774,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -800,13 +808,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{30, 31, 32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -835,13 +843,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -869,13 +877,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -907,13 +915,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{3, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -945,13 +953,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 5, 7, 9, 10, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -978,13 +986,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1012,13 +1020,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{4, 11, 13, 14, 15, 16, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1046,13 +1054,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 5, 6, 7, 8, 9, 10, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1080,13 +1088,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1117,13 +1125,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{3, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1154,13 +1162,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{4, 11, 13, 14, 15, 16, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1187,13 +1195,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1221,13 +1229,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{14, 15, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1255,13 +1263,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1289,13 +1297,13 @@ class granular_range_filter_test_case : public tests::FilterTestCaseBase { query.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); for (; docs->next();) { @@ -1813,7 +1821,7 @@ TEST(by_granular_range_test, boost) { q.mutable_options()->range.min_type = irs::BoundType::INCLUSIVE; q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -1832,7 +1840,7 @@ TEST(by_granular_range_test, boost) { q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } } @@ -2175,7 +2183,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(reader); + auto prepared = query.prepare({.index = reader}); ASSERT_NE(nullptr, prepared); auto* column = segment.column("_key"); ASSERT_NE(nullptr, column); @@ -2186,7 +2194,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { std::set actual; - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); while (docs->next()) { @@ -2227,7 +2235,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { irs::set_granular_term(query.mutable_options()->range.max, max_stream); query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(reader); + auto prepared = query.prepare({.index = reader}); ASSERT_NE(nullptr, prepared); auto* column = segment.column("_key"); ASSERT_NE(nullptr, column); @@ -2238,7 +2246,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { std::set actual; - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); while (docs->next()) { @@ -2282,7 +2290,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; query.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(reader); + auto prepared = query.prepare({.index = reader}); ASSERT_NE(nullptr, prepared); auto* column = segment.column("_key"); ASSERT_NE(nullptr, column); @@ -2293,7 +2301,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { std::set actual; - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); while (docs->next()) { @@ -2334,7 +2342,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { irs::set_granular_term(query.mutable_options()->range.min, min_stream); query.mutable_options()->range.min_type = irs::BoundType::EXCLUSIVE; - auto prepared = query.prepare(reader); + auto prepared = query.prepare({.index = reader}); ASSERT_NE(nullptr, prepared); auto* column = segment.column("_key"); ASSERT_NE(nullptr, column); @@ -2345,7 +2353,7 @@ TEST_P(granular_range_filter_test_case, by_range_numeric_sequence) { std::set actual; - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); while (docs->next()) { diff --git a/tests/search/levenshtein_filter_test.cpp b/tests/search/levenshtein_filter_test.cpp index de1662ae2..d8d060e89 100644 --- a/tests/search/levenshtein_filter_test.cpp +++ b/tests/search/levenshtein_filter_test.cpp @@ -95,6 +95,8 @@ TEST(by_edit_distance_test, equal) { } TEST(by_edit_distance_test, boost) { + MaxMemoryCounter counter; + // no boost { irs::by_edit_distance q; @@ -102,9 +104,15 @@ TEST(by_edit_distance_test, boost) { q.mutable_options()->term = irs::ViewCast(std::string_view("bar*")); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -116,9 +124,15 @@ TEST(by_edit_distance_test, boost) { irs::ViewCast(std::string_view("bar*")); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #ifndef IRESEARCH_DLL @@ -129,12 +143,24 @@ TEST(by_edit_distance_test, boost) { #endif // __clang__ TEST(by_edit_distance_test, test_type_of_prepared_query) { + MaxMemoryCounter counter; // term query { - auto lhs = make_term_filter("foo", "bar").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "bar").prepare(irs::SubReader::empty()); + auto lhs = make_term_filter("foo", "bar") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "bar") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #ifdef __clang__ @@ -188,14 +214,13 @@ TEST_P(by_edit_distance_test_case, test_order) { scorer.prepare_field_collector_ = [&scorer, &field_collectors_count]() -> irs::FieldCollector::ptr { ++field_collectors_count; - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer, &term_collectors_count]() -> irs::TermCollector::ptr { ++term_collectors_count; - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique(scorer); }; CheckQuery(make_filter("title", "", 1, 0, false), order, docs, rdr); @@ -237,14 +262,13 @@ TEST_P(by_edit_distance_test_case, test_order) { scorer.prepare_field_collector_ = [&scorer, &field_collectors_count]() -> irs::FieldCollector::ptr { ++field_collectors_count; - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer, &term_collectors_count]() -> irs::TermCollector::ptr { ++term_collectors_count; - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique(scorer); }; CheckQuery(make_filter("title", "", 1, 10, false), order, docs, rdr); @@ -286,14 +310,13 @@ TEST_P(by_edit_distance_test_case, test_order) { scorer.prepare_field_collector_ = [&scorer, &field_collectors_count]() -> irs::FieldCollector::ptr { ++field_collectors_count; - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer, &term_collectors_count]() -> irs::TermCollector::ptr { ++term_collectors_count; - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique(scorer); }; CheckQuery(make_filter("title", "", 1, 1, false), order, docs, rdr); @@ -565,6 +588,8 @@ TEST_P(by_edit_distance_test_case, bm25) { ASSERT_NE(nullptr, index); ASSERT_EQ(1, index->size()); + MaxMemoryCounter counter; + { irs::by_edit_distance filter; *filter.mutable_field() = "id"; @@ -574,10 +599,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -602,6 +632,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ASSERT_FALSE(docs->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { irs::by_edit_distance filter; @@ -612,10 +645,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -636,6 +674,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ++expected_doc; } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with prefix { @@ -648,10 +689,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -675,6 +721,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ASSERT_FALSE(docs->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { irs::by_edit_distance filter; @@ -685,10 +734,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -732,6 +786,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ++expected_doc; } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { irs::by_edit_distance filter; @@ -742,10 +799,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -788,6 +850,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ++expected_doc; } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with prefix { @@ -800,10 +865,15 @@ TEST_P(by_edit_distance_test_case, bm25) { opts.provider = irs::default_pdp; opts.with_transpositions = true; - auto prepared = filter.prepare(*index, prepared_order); + auto prepared = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); ASSERT_NE(nullptr, prepared); - auto docs = prepared->execute(index[0], prepared_order); + auto docs = + prepared->execute({.segment = index[0], .scorers = prepared_order}); ASSERT_NE(nullptr, docs); auto* score = irs::get(*docs); @@ -846,6 +916,9 @@ TEST_P(by_edit_distance_test_case, bm25) { ++expected_doc; } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(by_edit_distance_test_case, visit) { diff --git a/tests/search/nested_filter_test.cpp b/tests/search/nested_filter_test.cpp index 0f525f768..6ac473a05 100644 --- a/tests/search/nested_filter_test.cpp +++ b/tests/search/nested_filter_test.cpp @@ -547,17 +547,27 @@ TEST_P(NestedFilterTestCase, JoinAll0) { InitDataSet(); auto reader = open_reader(); + MaxMemoryCounter counter; + irs::ByNestedFilter filter; auto& opts = *filter.mutable_options(); opts.child = MakeByNumericTerm("count", 2); opts.parent = MakeParentProvider("customer"); - opts.match = [](const irs::SubReader& segment) -> irs::doc_iterator::ptr { + opts.match = [&](const irs::SubReader& segment) -> irs::doc_iterator::ptr { return irs::memory::make_managed( - irs::all().prepare(segment)->execute(segment), + irs::all() + .prepare({ + .index = segment, + .memory = counter, + }) + ->execute({.segment = segment}), std::set{6U, 13U, 15U, 20U}); }; CheckQuery(filter, Docs{13, 20}, Costs{11}, reader, SOURCE_LOCATION); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { opts.merge_type = irs::ScoreMergeType::kMax; @@ -573,6 +583,9 @@ TEST_P(NestedFilterTestCase, JoinAll0) { CheckQuery(filter, scorers, {tests}, reader, SOURCE_LOCATION); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { opts.merge_type = irs::ScoreMergeType::kMin; @@ -588,6 +601,9 @@ TEST_P(NestedFilterTestCase, JoinAll0) { CheckQuery(filter, scorers, {tests}, reader, SOURCE_LOCATION); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); { opts.merge_type = irs::ScoreMergeType::kNoop; @@ -603,6 +619,9 @@ TEST_P(NestedFilterTestCase, JoinAll0) { CheckQuery(filter, scorers, {tests}, reader, SOURCE_LOCATION); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(NestedFilterTestCase, JoinMin0) { diff --git a/tests/search/ngram_similarity_filter_tests.cpp b/tests/search/ngram_similarity_filter_tests.cpp index f89835403..f12d2552d 100644 --- a/tests/search/ngram_similarity_filter_tests.cpp +++ b/tests/search/ngram_similarity_filter_tests.cpp @@ -135,35 +135,56 @@ TEST_P(ngram_similarity_filter_test_case, boost) { auto& segment = rdr[0]; { - (void)1; // format work-around + MaxMemoryCounter counter; + // no terms no field { irs::by_ngram_similarity q; - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_EQ(counter.max, 0); + counter.Reset(); // simple disjunction { irs::by_ngram_similarity q = make_filter("field", {"1", "2"}, 0.5f); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // multiple terms { irs::by_ngram_similarity q = make_filter("field", {"1", "2", "3", "4"}, 0.5f); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } - } // namespace tests + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); + } // with boost { + MaxMemoryCounter counter; + irs::score_t boost = 1.5f; // no terms, return empty query @@ -171,18 +192,30 @@ TEST_P(ngram_similarity_filter_test_case, boost) { irs::by_ngram_similarity q; q.boost(boost); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_EQ(counter.max, 0); + counter.Reset(); // simple disjunction { irs::by_ngram_similarity q = make_filter("field", {"1", "2"}, 0.5f); q.boost(boost); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // multiple terms { @@ -190,9 +223,15 @@ TEST_P(ngram_similarity_filter_test_case, boost) { make_filter("field", {"1", "2", "3", "4"}, 0.5f); q.boost(boost); - auto prepared = q.prepare(segment); + auto prepared = q.prepare({ + .index = segment, + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } } @@ -208,14 +247,24 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_1) { } auto rdr = open_reader(); + + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "3", "4"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -234,6 +283,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_1) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_2) { @@ -249,14 +302,24 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_2) { } auto rdr = open_reader(); + + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "3", "4"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -276,6 +339,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_2) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_3) { @@ -290,14 +357,23 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_3) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "3", "4"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -317,6 +393,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_3) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_4) { @@ -331,13 +411,22 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_4) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "1"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -357,6 +446,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_4) { ASSERT_EQ(2, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_5) { @@ -373,13 +466,22 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_5) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "1"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -399,6 +501,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_5) { ASSERT_EQ(4, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_6) { @@ -413,13 +519,22 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_6) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "1"}, 1.0f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -439,6 +554,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_6) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_7) { @@ -454,14 +573,23 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_7) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "3", "4"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -481,6 +609,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_7) { ASSERT_EQ(2, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_8) { @@ -495,14 +627,23 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_8) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "5", "6", "2"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -522,6 +663,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_8) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_9) { @@ -538,14 +683,23 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_9) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"1", "2", "3", "4", "5", "1"}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -565,6 +719,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_9) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, check_matcher_10) { @@ -578,13 +736,22 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_10) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {""}, 0.5f); tests::sort::custom_sort sort; auto prepared_order = irs::Scorers::Prepare(sort); - auto prepared = filter.prepare(rdr, prepared_order); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub, prepared_order); + auto docs = prepared->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); auto* boost = irs::get(*docs); auto* frequency = irs::get(*docs); @@ -604,6 +771,10 @@ TEST_P(ngram_similarity_filter_test_case, check_matcher_10) { ASSERT_EQ(1, frequency->value); ASSERT_FALSE(docs->next()); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, no_match_case) { @@ -615,12 +786,17 @@ TEST_P(ngram_similarity_filter_test_case, no_match_case) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"ee", "we", "qq", "rr", "ff", "never_match"}, 0.1f); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -629,6 +805,10 @@ TEST_P(ngram_similarity_filter_test_case, no_match_case) { ASSERT_EQ(docs->value(), doc->value); ASSERT_TRUE(irs::doc_limits::eof(doc->value)); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, no_serial_match_case) { @@ -640,12 +820,17 @@ TEST_P(ngram_similarity_filter_test_case, no_serial_match_case) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"ee", "ss", "pa", "rr"}, 0.5f); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( bool(doc)); // ensure all iterators contain "document" attribute @@ -653,6 +838,10 @@ TEST_P(ngram_similarity_filter_test_case, no_serial_match_case) { ASSERT_EQ(docs->value(), doc->value); ASSERT_TRUE(irs::doc_limits::eof(doc->value)); } + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, one_match_case) { @@ -664,15 +853,20 @@ TEST_P(ngram_similarity_filter_test_case, one_match_case) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"ee", "ss", "qq", "rr", "ff", "never_match"}, 0.1f); Docs expected{1, 3, 5, 6, 7, 8, 9, 10, 12}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -687,6 +881,10 @@ TEST_P(ngram_similarity_filter_test_case, one_match_case) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, missed_last_test) { @@ -698,15 +896,20 @@ TEST_P(ngram_similarity_filter_test_case, missed_last_test) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"at", "tl", "la", "as", "ll", "never_match"}, 0.5f); Docs expected{1, 2, 5, 8, 11, 12, 13}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -721,6 +924,10 @@ TEST_P(ngram_similarity_filter_test_case, missed_last_test) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, missed_first_test) { @@ -732,15 +939,20 @@ TEST_P(ngram_similarity_filter_test_case, missed_first_test) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"never_match", "at", "tl", "la", "as", "ll"}, 0.5f); Docs expected{1, 2, 5, 8, 11, 12, 13}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -755,6 +967,10 @@ TEST_P(ngram_similarity_filter_test_case, missed_first_test) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, not_miss_match_for_tail) { @@ -766,15 +982,20 @@ TEST_P(ngram_similarity_filter_test_case, not_miss_match_for_tail) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"at", "tl", "la", "as", "ll", "never_match"}, 0.33f); Docs expected{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -789,6 +1010,10 @@ TEST_P(ngram_similarity_filter_test_case, not_miss_match_for_tail) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, missed_middle_test) { @@ -800,16 +1025,21 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle_test) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"at", "never_match", "la", "as", "ll"}, 0.333f); Docs expected{1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 14}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -824,6 +1054,10 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle_test) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, missed_middle2_test) { @@ -835,16 +1069,21 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle2_test) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter( "field", {"at", "never_match", "never_match2", "la", "as", "ll"}, 0.5f); Docs expected{1, 2, 5, 8, 11, 12, 13}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -859,6 +1098,10 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle2_test) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, missed_middle3_test) { @@ -870,6 +1113,8 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle3_test) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter( "field", {"at", "never_match", "tl", "never_match2", "la", "as", "ll"}, 0.28f); @@ -877,10 +1122,13 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle3_test) { Docs expected{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; const size_t expected_size = expected.size(); - auto prepared = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared = filter.prepare({ + .index = rdr, + .memory = counter, + }); size_t count = 0; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( @@ -895,6 +1143,10 @@ TEST_P(ngram_similarity_filter_test_case, missed_middle3_test) { } ASSERT_EQ(expected_size, count); ASSERT_EQ(0, expected.size()); + prepared.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } struct test_score_ctx final : public irs::score_ctx { @@ -1156,13 +1408,18 @@ TEST_P(ngram_similarity_filter_test_case, seek_next) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"never_match", "at", "tl", "la", "as", "ll"}, 0.5f); Docs expected{1, 2, 5, 8, 11, 12, 13}; auto expected_it = std::begin(expected); - auto prepared_filter = filter.prepare(rdr, irs::Scorers::kUnordered); + auto prepared_filter = filter.prepare({ + .index = rdr, + .memory = counter, + }); for (const auto& sub : rdr) { - auto docs = prepared_filter->execute(sub, irs::Scorers::kUnordered); + auto docs = prepared_filter->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE( bool(doc)); // ensure all iterators contain "document" attribute @@ -1186,6 +1443,10 @@ TEST_P(ngram_similarity_filter_test_case, seek_next) { ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } ASSERT_EQ(expected_it, std::end(expected)); + prepared_filter.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(ngram_similarity_filter_test_case, seek) { @@ -1197,15 +1458,24 @@ TEST_P(ngram_similarity_filter_test_case, seek) { auto rdr = open_reader(); + MaxMemoryCounter counter; + irs::by_ngram_similarity filter = make_filter("field", {"never_match", "at", "tl", "la", "as", "ll"}, 0.5f); Docs seek_tagrets{2, 5, 8, 13}; auto seek_it = std::begin(seek_tagrets); auto& prepared_order = irs::Scorers::kUnordered; - auto prepared_filter = filter.prepare(rdr, prepared_order); + auto prepared_filter = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = prepared_order, + }); for (const auto& sub : rdr) { while (std::end(seek_tagrets) != seek_it) { - auto docs = prepared_filter->execute(sub, prepared_order); + auto docs = prepared_filter->execute({ + .segment = sub, + .scorers = prepared_order, + }); auto* doc = irs::get(*docs); ASSERT_TRUE( bool(doc)); // ensure all iterators contain "document" attribute @@ -1226,6 +1496,10 @@ TEST_P(ngram_similarity_filter_test_case, seek) { } } ASSERT_EQ(std::end(seek_tagrets), seek_it); + prepared_filter.reset(); + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #endif diff --git a/tests/search/phrase_filter_tests.cpp b/tests/search/phrase_filter_tests.cpp index 3925145ca..4cda6c307 100644 --- a/tests/search/phrase_filter_tests.cpp +++ b/tests/search/phrase_filter_tests.cpp @@ -71,10 +71,10 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { { irs::by_phrase q; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); @@ -88,10 +88,10 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { irs::by_phrase q; *q.mutable_field() = "phrase_anl"; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); @@ -107,7 +107,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -116,14 +116,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -228,7 +228,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -237,14 +237,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -410,7 +410,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -419,14 +419,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -592,7 +592,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("%ox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -601,14 +601,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -714,7 +714,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("_ox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -723,14 +723,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -836,7 +836,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("f_x")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -845,14 +845,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -958,7 +958,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fo_")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -967,14 +967,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1080,7 +1080,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1089,14 +1089,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1204,7 +1204,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { lt.max_distance = 0; lt.term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1213,14 +1213,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1328,7 +1328,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { lt.max_distance = 1; lt.term = irs::ViewCast(std::string_view("fol")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1337,14 +1337,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1450,7 +1450,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto& st = q.mutable_options()->push_back(); st.terms.emplace(irs::ViewCast(std::string_view("fox"))); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1459,14 +1459,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1573,7 +1573,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { st.terms.emplace(irs::ViewCast(std::string_view("fox"))); st.terms.emplace(irs::ViewCast(std::string_view("that"))); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1582,14 +1582,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1718,7 +1718,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1727,14 +1727,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1772,7 +1772,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::EXCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1781,14 +1781,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_TRUE(irs::doc_limits::eof(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_TRUE(irs::doc_limits::eof(docs_seek->value())); ASSERT_FALSE(docs->next()); @@ -1806,7 +1806,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1815,14 +1815,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_TRUE(irs::doc_limits::eof(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_TRUE(irs::doc_limits::eof(docs_seek->value())); ASSERT_FALSE(docs->next()); @@ -1840,7 +1840,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::EXCLUSIVE; rt.range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1849,14 +1849,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_TRUE(irs::doc_limits::eof(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_TRUE(irs::doc_limits::eof(docs_seek->value())); ASSERT_FALSE(docs->next()); @@ -1874,7 +1874,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1883,14 +1883,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -1968,7 +1968,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::EXCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -1977,14 +1977,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2052,7 +2052,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -2061,14 +2061,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2126,7 +2126,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::EXCLUSIVE; rt.range.max_type = irs::BoundType::EXCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -2135,14 +2135,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2188,7 +2188,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, dynamic_cast(prepared.get())); @@ -2201,14 +2201,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2234,7 +2234,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto& pt = q.mutable_options()->push_back(); pt.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2248,14 +2248,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2301,7 +2301,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2315,14 +2315,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2368,7 +2368,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("f_x%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2382,14 +2382,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2438,7 +2438,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { lt.with_transpositions = true; lt.term = irs::ViewCast(std::string_view("fxo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2452,14 +2452,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2488,7 +2488,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2502,14 +2502,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2546,7 +2546,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { ->push_back(std::numeric_limits::max()) .term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, dynamic_cast(prepared.get())); @@ -2559,14 +2559,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2666,7 +2666,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { std::numeric_limits::max()); pt.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2680,14 +2680,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -2845,7 +2845,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { std::numeric_limits::max()); wt.term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -2859,14 +2859,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3024,7 +3024,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { std::numeric_limits::max()); wt.term = irs::ViewCast(std::string_view("f%x")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -3038,14 +3038,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3147,7 +3147,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { lt.max_distance = 1; lt.term = irs::ViewCast(std::string_view("fkx")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -3161,14 +3161,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3271,7 +3271,7 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); #ifndef IRESEARCH_DLL // check single word phrase optimization ASSERT_NE(nullptr, @@ -3285,14 +3285,14 @@ TEST_P(phrase_filter_test_case, sequential_one_term) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3363,7 +3363,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3372,7 +3372,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* score = irs::get(*docs); @@ -3381,7 +3381,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3427,7 +3427,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3436,14 +3436,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3498,7 +3498,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3507,14 +3507,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3569,7 +3569,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3578,12 +3578,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3631,7 +3631,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3640,14 +3640,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3695,7 +3695,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3704,12 +3704,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3758,7 +3758,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("x2")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3767,14 +3767,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3803,7 +3803,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3812,12 +3812,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3872,7 +3872,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3881,14 +3881,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -3943,7 +3943,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -3952,12 +3952,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4005,7 +4005,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4014,14 +4014,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4070,7 +4070,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("x2")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4079,14 +4079,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4115,7 +4115,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& pt = q.mutable_options()->push_back(); pt.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4124,14 +4124,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4186,7 +4186,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4195,14 +4195,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4257,7 +4257,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("f_x")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4266,12 +4266,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4320,7 +4320,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { lt.with_transpositions = true; lt.term = irs::ViewCast(std::string_view("fxo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4329,14 +4329,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4385,7 +4385,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4394,14 +4394,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4430,7 +4430,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4439,12 +4439,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4517,7 +4517,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4526,14 +4526,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4606,7 +4606,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4615,12 +4615,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4679,7 +4679,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("fox")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4688,14 +4688,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4756,7 +4756,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("x2")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4765,12 +4765,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4799,7 +4799,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& pt2 = q.mutable_options()->push_back(); pt2.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4808,14 +4808,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4888,7 +4888,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt2 = q.mutable_options()->push_back(); wt2.term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4897,14 +4897,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -4977,7 +4977,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt2 = q.mutable_options()->push_back(); wt2.term = irs::ViewCast(std::string_view("f%x")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -4986,12 +4986,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5052,7 +5052,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { rt2.range.min_type = irs::BoundType::INCLUSIVE; rt2.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5061,14 +5061,14 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5101,7 +5101,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { lt2.max_distance = 1; lt2.term = irs::ViewCast(std::string_view("fix")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5110,12 +5110,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5161,7 +5161,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& pt2 = q.mutable_options()->push_back(); pt2.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5170,12 +5170,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5248,7 +5248,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt2 = q.mutable_options()->push_back(); wt2.term = irs::ViewCast(std::string_view("fo%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5257,12 +5257,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5335,7 +5335,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& wt2 = q.mutable_options()->push_back(); wt2.term = irs::ViewCast(std::string_view("f_%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5344,12 +5344,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5428,7 +5428,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { rt2.range.min_type = irs::BoundType::INCLUSIVE; rt2.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5437,12 +5437,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5471,7 +5471,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { pt2.term = irs::ViewCast(std::string_view("bro")); pt3.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5480,12 +5480,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5614,12 +5614,10 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { [&finish_count](irs::byte_type*, const irs::FieldCollector*, const irs::TermCollector*) -> void { ++finish_count; }; sort.prepare_field_collector_ = [&sort]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(sort); + return std::make_unique(sort); }; sort.prepare_term_collector_ = [&sort]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(sort); + return std::make_unique(sort); }; sort.scorer_score = [](irs::doc_id_t doc, irs::score_t* score) { ASSERT_NE(nullptr, score); @@ -5627,7 +5625,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { }; auto pord = irs::Scorers::Prepare(sort); - auto prepared = q.prepare(rdr, pord); + auto prepared = q.prepare({.index = rdr, .scorers = pord}); ASSERT_EQ(1, collect_field_count); // 1 field in 1 segment ASSERT_EQ(6, collect_term_count); // 6 different terms ASSERT_EQ(6, finish_count); // 6 sub-terms in phrase @@ -5642,12 +5640,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { // no order passed - no frequency { - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); } - auto docs = prepared->execute(*sub, pord); + auto docs = prepared->execute({.segment = *sub, .scorers = pord}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -5655,7 +5653,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, pord); + auto docs_seek = prepared->execute({.segment = *sub, .scorers = pord}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5784,7 +5782,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { wt2.term = irs::ViewCast(std::string_view("br_wn")); wt3.term = irs::ViewCast(std::string_view("_%x")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -5794,12 +5792,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5849,7 +5847,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto& st3 = q.mutable_options()->push_back(); st3.terms.emplace(irs::ViewCast(std::string_view("fox"))); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5858,12 +5856,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -5945,7 +5943,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { rt3.range.min_type = irs::BoundType::INCLUSIVE; rt3.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -5954,12 +5952,12 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6008,12 +6006,10 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { [&finish_count](irs::byte_type*, const irs::FieldCollector*, const irs::TermCollector*) -> void { ++finish_count; }; sort.prepare_field_collector_ = [&sort]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(sort); + return std::make_unique(sort); }; sort.prepare_term_collector_ = [&sort]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(sort); + return std::make_unique(sort); }; sort.scorer_score = [](irs::doc_id_t doc, irs::score_t* score) { ASSERT_NE(nullptr, score); @@ -6021,7 +6017,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { }; auto pord = irs::Scorers::Prepare(sort); - auto prepared = q.prepare(rdr, pord); + auto prepared = q.prepare({.index = rdr, .scorers = pord}); ASSERT_EQ(1, collect_field_count); // 1 field in 1 segment ASSERT_EQ(3, collect_term_count); // 3 different terms ASSERT_EQ(3, finish_count); // 3 sub-terms in phrase @@ -6029,7 +6025,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { // no order passed - no frequency { - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); } @@ -6040,7 +6036,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, pord); + auto docs = prepared->execute({.segment = *sub, .scorers = pord}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -6048,7 +6044,7 @@ TEST_P(phrase_filter_test_case, sequential_three_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, pord); + auto docs_seek = prepared->execute({.segment = *sub, .scorers = pord}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); auto* score = irs::get(*docs); ASSERT_FALSE(!score); @@ -6112,7 +6108,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6121,12 +6117,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6161,7 +6157,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6170,12 +6166,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6210,7 +6206,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6219,12 +6215,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6261,7 +6257,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6270,12 +6266,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6310,7 +6306,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& pt = q.mutable_options()->push_back(1); pt.term = irs::ViewCast(std::string_view("qui")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6319,12 +6315,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6359,7 +6355,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(1); wt.term = irs::ViewCast(std::string_view("qui%ck")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6368,12 +6364,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6408,7 +6404,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { pt1.term = irs::ViewCast(std::string_view("fo")); pt2.term = irs::ViewCast(std::string_view("qui")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6417,12 +6413,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6457,7 +6453,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { wt1.term = irs::ViewCast(std::string_view("f%x")); wt2.term = irs::ViewCast(std::string_view("qui%ck")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6466,12 +6462,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6510,7 +6506,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { lt2.max_distance = 1; lt2.term = irs::ViewCast(std::string_view("quik")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6519,14 +6515,14 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::get(*docs)); ASSERT_FALSE(irs::get(*docs)); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6569,7 +6565,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6578,7 +6574,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); auto* boost = irs::get(*docs); @@ -6587,7 +6583,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6637,7 +6634,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6646,7 +6643,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -6654,7 +6651,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6704,7 +6702,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6713,7 +6711,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); auto* boost = irs::get(*docs); @@ -6722,7 +6720,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6807,7 +6806,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6816,7 +6815,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -6824,7 +6823,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -6978,7 +6978,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -6987,7 +6987,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); auto* boost = irs::get(*docs); @@ -6996,7 +6996,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7174,7 +7175,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { "bm25", irs::type::get(), "{ \"b\" : 0 }"); auto prepared_order = irs::Scorers::Prepare(*scorer); - auto prepared = q.prepare(rdr, prepared_order); + auto prepared = q.prepare({.index = rdr, .scorers = prepared_order}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7183,7 +7184,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, prepared_order); + auto docs = prepared->execute({.segment = *sub, .scorers = prepared_order}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -7191,7 +7192,8 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, prepared_order); + auto docs_seek = + prepared->execute({.segment = *sub, .scorers = prepared_order}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7224,7 +7226,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7233,12 +7235,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7275,7 +7277,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(0).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7284,12 +7286,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7318,7 +7320,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { pt1.term = irs::ViewCast(std::string_view("fox")); pt2.term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7327,12 +7329,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7361,7 +7363,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7370,12 +7372,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7412,7 +7414,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7421,12 +7423,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7463,7 +7465,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& pt = q.mutable_options()->push_back(1); pt.term = irs::ViewCast(std::string_view("qui")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7472,12 +7474,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7514,7 +7516,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(1); wt.term = irs::ViewCast(std::string_view("qui%k")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7523,12 +7525,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7565,7 +7567,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { pt1.term = irs::ViewCast(std::string_view("fo")); pt2.term = irs::ViewCast(std::string_view("qui")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7574,12 +7576,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7616,7 +7618,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { wt1.term = irs::ViewCast(std::string_view("fo%")); wt2.term = irs::ViewCast(std::string_view("qui%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7625,12 +7627,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7669,7 +7671,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { lt.max_distance = 1; lt.term = irs::ViewCast(std::string_view("quik")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7678,12 +7680,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7718,10 +7720,10 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(10).term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -7739,10 +7741,10 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& pt = q.mutable_options()->push_back(10); pt.term = irs::ViewCast(std::string_view("qui")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -7760,10 +7762,10 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(10); wt.term = irs::ViewCast(std::string_view("qu_ck")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -7783,10 +7785,10 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { lt.max_distance = 2; lt.term = irs::ViewCast(std::string_view("quc")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -7804,7 +7806,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back(1).term = irs::ViewCast(std::string_view("eye")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -7813,12 +7815,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7856,7 +7858,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("forward")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -7864,12 +7866,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7912,7 +7914,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& pt = q.mutable_options()->push_back(); pt.term = irs::ViewCast(std::string_view("fo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -7920,12 +7922,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -7970,7 +7972,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { }; auto pord = irs::Scorers::Prepare(sort); - auto prepared = q.prepare(rdr, pord); + auto prepared = q.prepare({.index = rdr, .scorers = pord}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -7978,7 +7980,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, pord); + auto docs = prepared->execute({.segment = *sub, .scorers = pord}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -7986,7 +7988,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, pord); + auto docs_seek = prepared->execute({.segment = *sub, .scorers = pord}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); auto* score = irs::get(*docs); ASSERT_FALSE(!score); @@ -8038,7 +8040,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { }; auto pord = irs::Scorers::Prepare(sort); - auto prepared = q.prepare(rdr, pord); + auto prepared = q.prepare({.index = rdr, .scorers = pord}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8046,7 +8048,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, pord); + auto docs = prepared->execute({.segment = *sub, .scorers = pord}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -8054,7 +8056,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, pord); + auto docs_seek = prepared->execute({.segment = *sub, .scorers = pord}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); auto* score = irs::get(*docs); ASSERT_FALSE(!score); @@ -8087,7 +8089,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -8096,12 +8098,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8141,7 +8143,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { }; auto pord = irs::Scorers::Prepare(sort); - auto prepared = q.prepare(rdr, pord); + auto prepared = q.prepare({.index = rdr, .scorers = pord}); auto sub = rdr.begin(); auto column = sub->column("name"); @@ -8150,7 +8152,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub, pord); + auto docs = prepared->execute({.segment = *sub, .scorers = pord}); auto* freq = irs::get(*docs); ASSERT_TRUE(freq); ASSERT_FALSE(irs::get(*docs)); @@ -8158,7 +8160,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub, pord); + auto docs_seek = prepared->execute({.segment = *sub, .scorers = pord}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8184,7 +8186,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("zo\\_%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8193,12 +8195,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8223,7 +8225,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("\\_oo")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8232,12 +8234,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8262,7 +8264,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("z\\_o")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8271,12 +8273,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8303,7 +8305,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("giraff\\_%")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8312,12 +8314,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8344,7 +8346,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("\\_iraffe")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8353,12 +8355,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8385,7 +8387,7 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto& wt = q.mutable_options()->push_back(); wt.term = irs::ViewCast(std::string_view("gira\\_fe")); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({.index = rdr}); auto sub = rdr.begin(); auto column = sub->column("name"); ASSERT_NE(nullptr, column); @@ -8394,12 +8396,12 @@ TEST_P(phrase_filter_test_case, sequential_several_terms) { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(*sub); + auto docs = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); ASSERT_FALSE(irs::doc_limits::valid(docs->value())); - auto docs_seek = prepared->execute(*sub); + auto docs_seek = prepared->execute({.segment = *sub}); ASSERT_FALSE(irs::doc_limits::valid(docs_seek->value())); ASSERT_TRUE(docs->next()); @@ -8467,7 +8469,7 @@ TEST(by_phrase_test, boost) { irs::by_phrase q; *q.mutable_field() = "field"; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -8478,7 +8480,7 @@ TEST(by_phrase_test, boost) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("quick")); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -8491,12 +8493,13 @@ TEST(by_phrase_test, boost) { q.mutable_options()->push_back().term = irs::ViewCast(std::string_view("brown")); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } // with boost { + MaxMemoryCounter counter; irs::score_t boost = 1.5f; // no terms, return empty query @@ -8505,7 +8508,7 @@ TEST(by_phrase_test, boost) { *q.mutable_field() = "field"; q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -8517,9 +8520,15 @@ TEST(by_phrase_test, boost) { irs::ViewCast(std::string_view("quick")); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // single multiple terms { @@ -8531,7 +8540,7 @@ TEST(by_phrase_test, boost) { irs::ViewCast(std::string_view("brown")); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(boost, prepared->boost()); } @@ -8557,7 +8566,7 @@ TEST(by_phrase_test, boost) { rt.range.min_type = irs::BoundType::INCLUSIVE; rt.range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(boost, prepared->boost()); } } diff --git a/tests/search/prefix_filter_test.cpp b/tests/search/prefix_filter_test.cpp index 2560291c8..fdb8a5a33 100644 --- a/tests/search/prefix_filter_test.cpp +++ b/tests/search/prefix_filter_test.cpp @@ -300,13 +300,21 @@ TEST(by_prefix_test, equal) { } TEST(by_prefix_test, boost) { + MaxMemoryCounter counter; + // no boost { irs::by_prefix q = make_filter("field", "term"); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -314,9 +322,15 @@ TEST(by_prefix_test, boost) { irs::by_prefix q = make_filter("field", "term"); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(prefix_filter_test_case, by_prefix) { diff --git a/tests/search/proxy_filter_test.cpp b/tests/search/proxy_filter_test.cpp index 1f407c6d1..a699607f9 100644 --- a/tests/search/proxy_filter_test.cpp +++ b/tests/search/proxy_filter_test.cpp @@ -123,11 +123,10 @@ class doclist_test_filter : public filter { static void reset_prepares() noexcept { prepares_ = 0; } - filter::prepared::ptr prepare(const IndexReader&, const Scorers&, - score_t boost, - const attribute_provider*) const final { + filter::prepared::ptr prepare(const PrepareContext& ctx) const final { ++prepares_; - return memory::make_managed(documents_, boost); + return memory::make_tracked(ctx.memory, documents_, + ctx.boost); } // intentional copy here to simplify multiple runs of same expected @@ -172,18 +171,28 @@ class proxy_filter_test_case : public ::testing::TestWithParam { void verify_filter(const std::vector& expected, size_t line) { SCOPED_TRACE(::testing::Message("Failed on line: ") << line); + MaxMemoryCounter prepare_counter; + MaxMemoryCounter execute_counter; + irs::proxy_filter::cache_ptr cache; for (size_t i = 0; i < 3; ++i) { proxy_filter proxy; if (i == 0) { - auto res = proxy.set_filter(); + auto res = + proxy.set_filter(irs::IResourceManager::kNoop); cache = res.second; res.first.set_expected(expected); } else { proxy.set_cache(cache); } - auto prepared_proxy = proxy.prepare(index_); - auto docs = prepared_proxy->execute(index_[0]); + auto prepared_proxy = proxy.prepare({ + .index = index_, + .memory = prepare_counter, + }); + auto docs = prepared_proxy->execute({ + .segment = index_[0], + .memory = execute_counter, + }); auto costs = irs::get(*docs); EXPECT_TRUE(costs); EXPECT_EQ(costs->estimate(), expected.size()); @@ -198,6 +207,16 @@ class proxy_filter_test_case : public ::testing::TestWithParam { // Real filter should be exectued just once EXPECT_EQ(doclist_test_query::get_execs(), 1); EXPECT_EQ(doclist_test_filter::get_prepares(), 1); + + cache.reset(); + + EXPECT_EQ(prepare_counter.current, 0); + EXPECT_GT(prepare_counter.max, 0); + prepare_counter.Reset(); + + EXPECT_EQ(execute_counter.current, 0); + EXPECT_GT(execute_counter.max, 0); + execute_counter.Reset(); } irs::memory_directory dir_; @@ -266,7 +285,7 @@ TEST_P(proxy_filter_real_filter, with_terms_filter) { init_index(); auto rdr = open_reader(); proxy_filter proxy; - auto [q, cache] = proxy.set_filter(); + auto [q, cache] = proxy.set_filter(irs::IResourceManager::kNoop); *q.mutable_field() = "name"; q.mutable_options()->term = irs::ViewCast(std::string_view("A")); @@ -277,7 +296,7 @@ TEST_P(proxy_filter_real_filter, with_disjunction_filter) { init_index(); auto rdr = open_reader(); proxy_filter proxy; - auto [root, cache] = proxy.set_filter(); + auto [root, cache] = proxy.set_filter(irs::IResourceManager::kNoop); auto& q = root.add(); *q.mutable_field() = "name"; q.mutable_options()->term = diff --git a/tests/search/range_filter_test.cpp b/tests/search/range_filter_test.cpp index e13807fc2..479ebeaaa 100644 --- a/tests/search/range_filter_test.cpp +++ b/tests/search/range_filter_test.cpp @@ -110,6 +110,8 @@ class range_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // long - seq = [7..7] { irs::numeric_token_stream min_stream; @@ -126,13 +128,16 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("seq", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -143,6 +148,9 @@ class range_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // long - seq = [1..7] { @@ -160,13 +168,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("seq", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{2, 3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -190,13 +198,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { (irs::numeric_utils::numeric_traits::max)(), irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{30, 31, 32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -219,13 +227,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { "seq", (irs::numeric_utils::numeric_traits::min)(), irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -253,13 +261,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("seq", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -287,13 +295,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("seq", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{2, 3, 4, 5, 6, 7, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -317,13 +325,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { (irs::numeric_utils::numeric_traits::max)(), irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{30, 31, 32}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -346,13 +354,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { "seq", (irs::numeric_utils::numeric_traits::min)(), irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 4, 5, 6}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -380,13 +388,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("value", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{3, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -414,13 +422,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("value", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::EXCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 5, 7, 9, 10, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -443,13 +451,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { "value", irs::numeric_utils::numeric_traits::ninf(), irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::EXCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{4, 11, 13, 14, 15, 16, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -473,13 +481,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { irs::numeric_utils::numeric_traits::inf(), irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 5, 6, 7, 8, 9, 10, 12}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -506,13 +514,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("value", min_term->value, irs::BoundType::INCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{3, 8}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -539,13 +547,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { make_filter("value", min_term->value, irs::BoundType::EXCLUSIVE, max_term->value, irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{4, 11, 13, 14, 15, 16, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -568,13 +576,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { "value", irs::numeric_utils::numeric_traits::ninf(), irs::BoundType::EXCLUSIVE, max_term->value, irs::BoundType::EXCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{14, 15, 17}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -598,13 +606,13 @@ class range_filter_test_case : public tests::FilterTestCaseBase { irs::numeric_utils::numeric_traits::inf(), irs::BoundType::INCLUSIVE); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({.index = rdr}); std::vector expected{1, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -1025,8 +1033,7 @@ class range_filter_test_case : public tests::FilterTestCaseBase { size_t collect_term_count = 0; size_t finish_count = 0; - irs::Scorer::ptr sort{ - std::make_unique()}; + irs::Scorer::ptr sort{std::make_unique()}; auto& scorer = static_cast(*sort); scorer.collector_collect_field = [&collect_field_count]( @@ -1044,12 +1051,12 @@ class range_filter_test_case : public tests::FilterTestCaseBase { const irs::TermCollector*) -> void { ++finish_count; }; scorer.prepare_field_collector_ = [&scorer]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique( + scorer); }; irs::by_range filter; @@ -1075,8 +1082,7 @@ class range_filter_test_case : public tests::FilterTestCaseBase { irs::by_range filter; *filter.mutable_field() = "value"; - irs::Scorer::ptr sort{ - std::make_unique()}; + irs::Scorer::ptr sort{std::make_unique()}; CheckQuery(filter, std::span{&sort, 1}, docs, rdr); } @@ -1096,8 +1102,7 @@ class range_filter_test_case : public tests::FilterTestCaseBase { filter.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; filter.mutable_options()->scored_terms_limit = 2; - irs::Scorer::ptr sort{ - std::make_unique()}; + irs::Scorer::ptr sort{std::make_unique()}; CheckQuery(filter, std::span{&sort, 1}, docs, rdr); } @@ -1120,8 +1125,7 @@ class range_filter_test_case : public tests::FilterTestCaseBase { filter.mutable_options()->range.max = max_term->value; filter.mutable_options()->range.max_type = irs::BoundType::EXCLUSIVE; - irs::Scorer::ptr sort{ - std::make_unique()}; + irs::Scorer::ptr sort{std::make_unique()}; CheckQuery(filter, std::span{&sort, 1}, docs, rdr); } } @@ -1233,7 +1237,7 @@ TEST(by_range_test, boost) { irs::ViewCast(std::string_view("max_term")); q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -1251,7 +1255,7 @@ TEST(by_range_test, boost) { q.mutable_options()->range.max_type = irs::BoundType::INCLUSIVE; q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(boost, prepared->boost()); } } diff --git a/tests/search/same_position_filter_tests.cpp b/tests/search/same_position_filter_tests.cpp index bdd999735..a6f556e0a 100644 --- a/tests/search/same_position_filter_tests.cpp +++ b/tests/search/same_position_filter_tests.cpp @@ -56,6 +56,8 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { // read segment auto index = open_reader(); + MaxMemoryCounter counter; + // collector count (no branches) { irs::by_same_position filter; @@ -81,16 +83,16 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { const irs::TermCollector*) -> void { ++finish_count; }; scorer.prepare_field_collector_ = [&scorer]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique( + scorer); }; auto pord = irs::Scorers::Prepare(scorer); - auto prepared = filter.prepare(index, pord); + auto prepared = filter.prepare({.index = index, .scorers = pord}); ASSERT_EQ(0, collect_field_count); // should not be executed ASSERT_EQ(0, collect_term_count); // should not be executed ASSERT_EQ(0, finish_count); // no terms optimization @@ -123,20 +125,27 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { const irs::TermCollector*) -> void { ++finish_count; }; scorer.prepare_field_collector_ = [&scorer]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique( + scorer); }; auto pord = irs::Scorers::Prepare(scorer); - auto prepared = filter.prepare(index, pord); + auto prepared = filter.prepare({ + .index = index, + .memory = counter, + .scorers = pord, + }); ASSERT_EQ(2, collect_field_count); // 1 field in 2 segments ASSERT_EQ(2, collect_term_count); // 1 term in 2 segments ASSERT_EQ(1, finish_count); // 1 unique term } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // collector count (multiple terms) { @@ -167,16 +176,16 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { const irs::TermCollector*) -> void { ++finish_count; }; scorer.prepare_field_collector_ = [&scorer]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer]() -> irs::TermCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::term_collector>(scorer); + return std::make_unique( + scorer); }; auto pord = irs::Scorers::Prepare(scorer); - auto prepared = filter.prepare(index, pord); + auto prepared = filter.prepare({.index = index, .scorers = pord}); ASSERT_EQ(4, collect_field_count); // 2 fields (1 per term since treated // as a disjunction) in 2 segments ASSERT_EQ(4, collect_term_count); // 2 term in 2 segments @@ -219,8 +228,8 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { // empty query { irs::by_same_position q; - auto prepared = q.prepare(index); - auto docs = prepared->execute(segment); + auto prepared = q.prepare({.index = index}); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -239,14 +248,14 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { expected_query.mutable_options()->term = irs::ViewCast(std::string_view("100")); - auto prepared = query.prepare(index); - auto expected_prepared = expected_query.prepare(index); + auto prepared = query.prepare({.index = index}); + auto expected_prepared = expected_query.prepare({.index = index}); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); - auto expected_docs = prepared->execute(segment); + auto expected_docs = prepared->execute({.segment = segment}); ASSERT_EQ(irs::doc_limits::invalid(), docs->value()); while (expected_docs->next()) { @@ -268,8 +277,8 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { "b", irs::ViewCast(std::string_view("90"))); q.mutable_options()->terms.emplace_back( "c", irs::ViewCast(std::string_view("9"))); - auto prepared = q.prepare(index); - auto docs = prepared->execute(segment); + auto prepared = q.prepare({.index = index}); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_EQ(docs->value(), doc->value); ASSERT_EQ(irs::doc_limits::invalid(), docs->value()); @@ -287,7 +296,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { q.mutable_options()->terms.emplace_back( "c", irs::ViewCast(std::string_view("6"))); - auto prepared = q.prepare(index); + auto prepared = q.prepare({.index = index}); // next { @@ -296,7 +305,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -320,7 +329,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -353,7 +362,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { q.mutable_options()->terms.emplace_back( "a", irs::ViewCast(std::string_view("700"))); - auto prepared = q.prepare(index); + auto prepared = q.prepare({.index = index}); // next { @@ -362,7 +371,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -386,7 +395,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -412,7 +421,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { q.mutable_options()->terms.emplace_back( "c", irs::ViewCast(std::string_view("7"))); - auto prepared = q.prepare(index); + auto prepared = q.prepare({.index = index}); // next { @@ -421,7 +430,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -489,7 +498,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -529,7 +538,7 @@ class same_position_filter_test_case : public tests::FilterTestCaseBase { // seek to the end { - auto docs = prepared->execute(segment); + auto docs = prepared->execute({.segment = segment}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -574,7 +583,7 @@ TEST(by_same_position_test, boost) { { irs::by_same_position q; - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -584,7 +593,7 @@ TEST(by_same_position_test, boost) { q.mutable_options()->terms.emplace_back( "field", irs::ViewCast(std::string_view("quick"))); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -596,7 +605,7 @@ TEST(by_same_position_test, boost) { q.mutable_options()->terms.emplace_back( "field", irs::ViewCast(std::string_view("brown"))); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } } @@ -610,7 +619,7 @@ TEST(by_same_position_test, boost) { irs::by_same_position q; q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } @@ -621,7 +630,7 @@ TEST(by_same_position_test, boost) { "field", irs::ViewCast(std::string_view("quick"))); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(boost, prepared->boost()); } @@ -634,7 +643,7 @@ TEST(by_same_position_test, boost) { "field", irs::ViewCast(std::string_view("brown"))); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({.index = irs::SubReader::empty()}); ASSERT_EQ(boost, prepared->boost()); } } diff --git a/tests/search/term_filter_tests.cpp b/tests/search/term_filter_tests.cpp index 759f37c69..58c41da91 100644 --- a/tests/search/term_filter_tests.cpp +++ b/tests/search/term_filter_tests.cpp @@ -64,19 +64,26 @@ class term_filter_test_case : public tests::FilterTestCaseBase { // search : single term CheckQuery(make_filter("name", "A"), Docs{1}, Costs{1}, rdr); + MaxMemoryCounter counter; { irs::by_term q = make_filter("name", "A"); - auto prepared = q.prepare(rdr); + auto prepared = q.prepare({ + .index = rdr, + .memory = counter, + }); auto sub = rdr.begin(); - auto docs0 = prepared->execute(*sub); + auto docs0 = prepared->execute({.segment = *sub}); auto* doc = irs::get(*docs0); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs0->value(), doc->value); - auto docs1 = prepared->execute(*sub); + auto docs1 = prepared->execute({.segment = *sub}); ASSERT_TRUE(docs0->next()); ASSERT_EQ(docs0->value(), docs1->seek(docs0->value())); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // search : all terms CheckQuery( @@ -109,10 +116,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { auto scorer = tests::sort::boost{}; auto pord = irs::Scorers::Prepare(scorer); + MaxMemoryCounter counter; + // without boost { - auto prep = filter.prepare(rdr, pord); - auto docs = prep->execute(*(rdr.begin()), pord); + auto prep = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = pord, + }); + auto docs = prep->execute({.segment = *(rdr.begin()), .scorers = pord}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -132,14 +145,21 @@ class term_filter_test_case : public tests::FilterTestCaseBase { ASSERT_FALSE(docs->next()); ASSERT_EQ(docs->value(), doc->value); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { const irs::score_t value = 5; filter.boost(value); - auto prep = filter.prepare(rdr, pord); - auto docs = prep->execute(*(rdr.begin()), pord); + auto prep = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = pord, + }); + auto docs = prep->execute({.segment = *(rdr.begin()), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -154,6 +174,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { ASSERT_FALSE(docs->next()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void by_term_sequential_numeric() { @@ -223,6 +246,8 @@ class term_filter_test_case : public tests::FilterTestCaseBase { auto rdr = open_reader(); + MaxMemoryCounter counter; + // long (20) { irs::numeric_token_stream stream; @@ -232,19 +257,25 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("seq", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{21}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); for (; docs->next();) { actual.push_back(docs->value()); } } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // int (21) { @@ -255,13 +286,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("seq", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{22}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -272,6 +306,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // double (90.564) { @@ -283,13 +320,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{13}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -300,6 +340,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // float (90.564) { @@ -311,13 +354,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{13}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -328,6 +374,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // double (100) { @@ -339,13 +388,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{1, 5, 7, 9, 10}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -356,6 +408,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // float_t(100) { @@ -367,13 +422,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{1, 5, 7, 9, 10}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -384,6 +442,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // int(100) { @@ -395,13 +456,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{1, 5, 7, 9, 10}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -412,6 +476,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // long(100) { @@ -423,13 +490,16 @@ class term_filter_test_case : public tests::FilterTestCaseBase { irs::by_term query = make_filter("value", irs::ViewCast(term->value)); - auto prepared = query.prepare(rdr); + auto prepared = query.prepare({ + .index = rdr, + .memory = counter, + }); std::vector expected{1, 5, 7, 9, 10}; std::vector actual; for (const auto& sub : rdr) { - auto docs = prepared->execute(sub); + auto docs = prepared->execute({.segment = sub}); auto* doc = irs::get(*docs); ASSERT_TRUE(bool(doc)); ASSERT_EQ(docs->value(), doc->value); @@ -440,6 +510,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { } ASSERT_EQ(expected, actual); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void by_term_sequential_order() { @@ -453,6 +526,8 @@ class term_filter_test_case : public tests::FilterTestCaseBase { // read segment auto rdr = open_reader(); + MaxMemoryCounter counter; + { // create filter irs::by_term filter = make_filter("prefix", "abcy"); @@ -489,8 +564,12 @@ class term_filter_test_case : public tests::FilterTestCaseBase { std::set expected{31, 32}; auto pord = irs::Scorers::Prepare(scorer); - auto prep = filter.prepare(rdr, pord); - auto docs = prep->execute(*(rdr.begin()), pord); + auto prep = filter.prepare({ + .index = rdr, + .memory = counter, + .scorers = pord, + }); + auto docs = prep->execute({.segment = *(rdr.begin()), .scorers = pord}); auto* scr = irs::get(*docs); ASSERT_FALSE(!scr); @@ -507,6 +586,9 @@ class term_filter_test_case : public tests::FilterTestCaseBase { ASSERT_EQ(1, collect_term_count); // 1 term in 1 field in 1 segment ASSERT_EQ(1, finish_count); // 1 unique term } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } void by_term_sequential() { @@ -639,13 +721,21 @@ TEST(by_term_test, equal) { } TEST(by_term_test, boost) { + MaxMemoryCounter counter; + // no boost { irs::by_term q = make_filter("field", "term"); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -653,9 +743,15 @@ TEST(by_term_test, boost) { irs::by_term q = make_filter("field", "term"); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } static constexpr auto kTestDirs = tests::getDirectories(); diff --git a/tests/search/terms_filter_test.cpp b/tests/search/terms_filter_test.cpp index ba01ea601..e9101e399 100644 --- a/tests/search/terms_filter_test.cpp +++ b/tests/search/terms_filter_test.cpp @@ -81,13 +81,21 @@ TEST(by_terms_test, equal) { class terms_filter_test_case : public tests::FilterTestCaseBase {}; TEST_P(terms_filter_test_case, boost) { + MaxMemoryCounter counter; + // no boost { irs::by_terms q = make_filter("field", {{"bar", 0.5f}, {"baz", 0.25f}}); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -96,10 +104,16 @@ TEST_P(terms_filter_test_case, boost) { irs::by_terms q = make_filter("field", {{"bar", 0.5f}, {"baz", 0.25f}}); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); // no boost because index is empty } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -116,9 +130,15 @@ TEST_P(terms_filter_test_case, boost) { make_filter("duplicated", {{"abcd", 0.5f}, {"vczc", 0.25f}}); q.boost(boost); - auto prepared = q.prepare(*rdr); + auto prepared = q.prepare({ + .index = *rdr, + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(terms_filter_test_case, simple_sequential_order) { diff --git a/tests/search/tfidf_test.cpp b/tests/search/tfidf_test.cpp index 083064cdb..ce5eed3bc 100644 --- a/tests/search/tfidf_test.cpp +++ b/tests/search/tfidf_test.cpp @@ -119,6 +119,8 @@ void tfidf_test_case::test_query_norms(irs::type_info::type_id norm, const auto* column = segment.column("seq"); ASSERT_NE(nullptr, column); + MaxMemoryCounter counter; + // by_range multiple { auto values = column->iterator(irs::ColumnHint::kNormal); @@ -141,8 +143,13 @@ void tfidf_test_case::test_query_norms(irs::type_info::type_id norm, }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -164,6 +171,9 @@ void tfidf_test_case::test_query_norms(irs::type_info::type_id norm, ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range multiple (3 values) { @@ -187,8 +197,13 @@ void tfidf_test_case::test_query_norms(irs::type_info::type_id norm, }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); while (docs->next()) { @@ -209,6 +224,9 @@ void tfidf_test_case::test_query_norms(irs::type_info::type_id norm, ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(tfidf_test_case, consts) { @@ -383,6 +401,8 @@ TEST_P(tfidf_test_case, test_phrase) { ASSERT_EQ(1, index->size()); auto& segment = *(index.begin()); + MaxMemoryCounter counter; + // "jumps high" with order { irs::by_phrase filter; @@ -402,8 +422,13 @@ TEST_P(tfidf_test_case, test_phrase) { "R" // jumps high jumps left jumps right walks down walks back }; - auto prepared_filter = filter.prepare(*index, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -431,6 +456,9 @@ TEST_P(tfidf_test_case, test_phrase) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // "cookies ca* p_e bisKuit meringue|marshmallows" with order { @@ -462,8 +490,13 @@ TEST_P(tfidf_test_case, test_phrase) { "SPWLC3" // cookies cake pie biscuet marshmallows cake meringue }; - auto prepared_filter = filter.prepare(*index, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = *index, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -491,6 +524,9 @@ TEST_P(tfidf_test_case, test_phrase) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(tfidf_test_case, test_query) { @@ -517,6 +553,9 @@ TEST_P(tfidf_test_case, test_query) { auto& segment = *(reader.begin()); const auto* column = segment.column("seq"); ASSERT_NE(nullptr, column); + + MaxMemoryCounter counter; + // by_term { auto values = column->iterator(irs::ColumnHint::kNormal); @@ -533,8 +572,13 @@ TEST_P(tfidf_test_case, test_query) { std::vector expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -557,6 +601,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by term multi-segment, same term (same score for all docs) { @@ -618,7 +665,11 @@ TEST_P(tfidf_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -627,7 +678,8 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -649,6 +701,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_term disjunction multi-segment, different terms (same score for all // docs) @@ -722,7 +777,11 @@ TEST_P(tfidf_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -731,7 +790,8 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -755,6 +815,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_prefix empty multi-segment, different terms (same score for all docs) { @@ -818,7 +881,11 @@ TEST_P(tfidf_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); for (auto& segment : reader) { const auto* column = segment.column("seq"); @@ -827,7 +894,8 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_NE(nullptr, values); auto* actual_value = irs::get(*values); ASSERT_NE(nullptr, actual_value); - auto docs = prepared_filter->execute(segment, prepared_order); + auto docs = prepared_filter->execute( + {.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -851,6 +919,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range single { @@ -872,8 +943,13 @@ TEST_P(tfidf_test_case, test_query) { std::vector expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -894,6 +970,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range single + scored_terms_limit(1) { @@ -916,8 +995,13 @@ TEST_P(tfidf_test_case, test_query) { std::vector expected{3, 7}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -938,6 +1022,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // FIXME!!! // by_range single + scored_terms_limit(0) @@ -957,8 +1044,9 @@ TEST_P(tfidf_test_case, test_query) { // std::vector expected{ 3, 7 }; // // irs::bytes_view_input in; - // auto prepared_filter = filter.prepare(reader, prepared_order); - // auto docs = prepared_filter->execute(segment, prepared_order); + // auto prepared_filter = filter.prepare({.index=reader, + // .scorers=prepared_order}); auto docs = + // prepared_filter->execute({.segment=segment, .scorers=prepared_order}); // auto* score = irs::get(*docs); // ASSERT_TRUE(bool(score)); // @@ -1001,8 +1089,13 @@ TEST_P(tfidf_test_case, test_query) { std::vector expected{7, 0, 1, 3, 5}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1023,6 +1116,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_range multiple (3 values) { @@ -1044,8 +1140,13 @@ TEST_P(tfidf_test_case, test_query) { std::vector expected{0, 7, 5, 1, 3, 2}; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1066,6 +1167,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected[i++], entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // by_phrase { @@ -1089,8 +1193,13 @@ TEST_P(tfidf_test_case, test_query) { }; irs::bytes_view_input in; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1112,6 +1221,9 @@ TEST_P(tfidf_test_case, test_query) { ASSERT_EQ(expected_entry.second, entry.second); } } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all { @@ -1123,8 +1235,13 @@ TEST_P(tfidf_test_case, test_query) { irs::all filter; filter.boost(1.5f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_FALSE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1141,6 +1258,9 @@ TEST_P(tfidf_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all { @@ -1152,8 +1272,13 @@ TEST_P(tfidf_test_case, test_query) { irs::all filter; filter.boost(0.f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_TRUE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1170,6 +1295,9 @@ TEST_P(tfidf_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // column existence { @@ -1181,8 +1309,13 @@ TEST_P(tfidf_test_case, test_query) { irs::by_column_existence filter; *filter.mutable_field() = "seq"; - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_FALSE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1199,6 +1332,9 @@ TEST_P(tfidf_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // column existence { @@ -1211,8 +1347,13 @@ TEST_P(tfidf_test_case, test_query) { *filter.mutable_field() = "seq"; filter.boost(0.f); - auto prepared_filter = filter.prepare(reader, prepared_order); - auto docs = prepared_filter->execute(segment, prepared_order); + auto prepared_filter = filter.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared_filter->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); ASSERT_TRUE(score->Func() == &irs::ScoreFunction::DefaultScore); @@ -1229,6 +1370,9 @@ TEST_P(tfidf_test_case, test_query) { } ASSERT_EQ(irs::doc_limits::eof(), docs->value()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } TEST_P(tfidf_test_case, test_query_norms) { @@ -1458,6 +1602,8 @@ TEST_P(tfidf_test_case, test_order) { const auto* column = segment.column("seq"); ASSERT_NE(nullptr, column); + MaxMemoryCounter counter; + { auto values = column->iterator(irs::ColumnHint::kNormal); ASSERT_NE(nullptr, values); @@ -1471,8 +1617,13 @@ TEST_P(tfidf_test_case, test_order) { std::vector expected{0, 1, 5, 7}; irs::bytes_view_input in; - auto prepared = query.prepare(reader, prepared_order); - auto docs = prepared->execute(segment, prepared_order); + auto prepared = query.prepare({ + .index = reader, + .memory = counter, + .scorers = prepared_order, + }); + auto docs = + prepared->execute({.segment = segment, .scorers = prepared_order}); auto* score = irs::get(*docs); ASSERT_TRUE(bool(score)); @@ -1493,6 +1644,9 @@ TEST_P(tfidf_test_case, test_order) { [](const auto& lhs, auto rhs) { return lhs.second == rhs; }); ASSERT_TRUE(eq); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #endif // IRESEARCH_DLL diff --git a/tests/search/wand_test.cpp b/tests/search/wand_test.cpp index 71a3144df..4352207ec 100644 --- a/tests/search/wand_test.cpp +++ b/tests/search/wand_test.cpp @@ -122,7 +122,7 @@ std::vector WandTestCase::Collect(const irs::DirectoryReader& index, bool can_use_wand, size_t limit) { auto scorers = irs::Scorers::Prepare(scorer); EXPECT_FALSE(scorers.empty()); - auto query = filter.prepare(index, scorers); + auto query = filter.prepare({.index = index, .scorers = scorers}); EXPECT_NE(nullptr, query); const irs::WandContext mode{.index = wand_idx}; diff --git a/tests/search/wildcard_filter_test.cpp b/tests/search/wildcard_filter_test.cpp index c07e87e56..0754d3d1e 100644 --- a/tests/search/wildcard_filter_test.cpp +++ b/tests/search/wildcard_filter_test.cpp @@ -71,13 +71,21 @@ TEST(by_wildcard_test, equal) { } TEST(by_wildcard_test, boost) { + MaxMemoryCounter counter; + // no boost { irs::by_wildcard q = make_filter("field", "bar*"); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(irs::kNoBoost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // with boost { @@ -86,9 +94,15 @@ TEST(by_wildcard_test, boost) { irs::by_wildcard q = make_filter("field", "bar*"); q.boost(boost); - auto prepared = q.prepare(irs::SubReader::empty()); + auto prepared = q.prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(boost, prepared->boost()); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #ifndef IRESEARCH_DLL @@ -99,77 +113,165 @@ TEST(by_wildcard_test, boost) { #endif // __clang__ TEST(by_wildcard_test, test_type_of_prepared_query) { + MaxMemoryCounter counter; + // term query { - auto lhs = - make_filter("foo", "bar").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "bar").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "bar") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "bar") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // term query { - auto lhs = - make_filter("foo", "").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "").prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "").prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // term query { - auto lhs = - make_filter("foo", "foo%").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "foo\\%").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "foo%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "foo\\%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // prefix query { auto lhs = make_filter("foo", "bar") - .prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "bar%").prepare(irs::SubReader::empty()); + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "bar%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // prefix query { auto lhs = make_filter("foo", "bar") - .prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "bar%%").prepare(irs::SubReader::empty()); + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "bar%%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // term query { - auto lhs = - make_filter("foo", "bar%").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "bar\\%").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "bar%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "bar\\%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all query { - auto lhs = - make_filter("foo", "").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "%").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "").prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // all query { - auto lhs = - make_filter("foo", "").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "%%").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "").prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "%%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); // term query { - auto lhs = - make_filter("foo", "%").prepare(irs::SubReader::empty()); - auto rhs = make_filter("foo", "\\%").prepare(irs::SubReader::empty()); + auto lhs = make_filter("foo", "%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); + auto rhs = make_filter("foo", "\\%") + .prepare({ + .index = irs::SubReader::empty(), + .memory = counter, + }); ASSERT_EQ(typeid(*lhs), typeid(*rhs)); } + EXPECT_EQ(counter.current, 0); + EXPECT_GT(counter.max, 0); + counter.Reset(); } #ifdef __clang__ @@ -220,8 +322,8 @@ TEST_P(wildcard_filter_test_case, simple_sequential_order) { [&finish_count](irs::byte_type*, const irs::FieldCollector*, const irs::TermCollector*) -> void { ++finish_count; }; scorer.prepare_field_collector_ = [&scorer]() -> irs::FieldCollector::ptr { - return std::make_unique< - tests::sort::custom_sort::field_collector>(scorer); + return std::make_unique( + scorer); }; scorer.prepare_term_collector_ = [&scorer]() -> irs::TermCollector::ptr { return std::make_unique(scorer); diff --git a/tests/tests_shared.hpp b/tests/tests_shared.hpp index a252d95e6..25f6ff220 100644 --- a/tests/tests_shared.hpp +++ b/tests/tests_shared.hpp @@ -78,15 +78,36 @@ class test_env { }; struct SimpleMemoryAccounter : public irs::IResourceManager { - bool Increase(size_t value) noexcept override { + void Increase(size_t value) override { counter_ += value; - return result_; + if (!result_) { + throw std::runtime_error{"SimpleMemoryAccounter"}; + } } + void Decrease(size_t value) noexcept override { counter_ -= value; } + size_t counter_{0}; bool result_{true}; }; +struct MaxMemoryCounter final : irs::IResourceManager { + void Reset() noexcept { + current = 0; + max = 0; + } + + void Increase(size_t value) final { + current += value; + max = std::max(max, current); + } + + void Decrease(size_t value) noexcept final { current -= value; } + + size_t current{0}; + size_t max{0}; +}; + struct TestResourceManager { SimpleMemoryAccounter cached_columns; SimpleMemoryAccounter consolidations; diff --git a/utils/index-put.cpp b/utils/index-put.cpp index ef0e60b14..e6b24ce80 100644 --- a/utils/index-put.cpp +++ b/utils/index-put.cpp @@ -377,8 +377,8 @@ int put(const std::string& path, const std::string& dir_type, auto it = WAND_TYPES.find(wand_type); if (it != WAND_TYPES.end()) { scorer = it->second; - scr = irs::scorers::get( - scorer.name, irs::type::get(), scorer.arg); + scr = irs::scorers::get( + scorer.name, irs::type::get(), scorer.arg); } if (!scr) { std::cerr << "Unable to instatiate wand from wand type: " << wand_type diff --git a/utils/index-search.cpp b/utils/index-search.cpp index fcc150eb4..ce8d32c81 100644 --- a/utils/index-search.cpp +++ b/utils/index-search.cpp @@ -257,7 +257,10 @@ irs::filter::prepared::ptr prepareFilter( *query.mutable_field() = "body"; query.mutable_options()->term = irs::ViewCast(terms); - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::HighPhrase: // fall through case category_t::MedPhrase: // fall through @@ -277,7 +280,10 @@ irs::filter::prepared::ptr prepareFilter( opts->push_back().term = term->value; } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::HighNGram: // fall through case category_t::MedNGram: // fall through @@ -303,7 +309,10 @@ irs::filter::prepared::ptr prepareFilter( tmpBuf.size()); } } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::AndHighHigh: // fall through case category_t::AndHighMed: // fall through @@ -324,7 +333,10 @@ irs::filter::prepared::ptr prepareFilter( irs::ViewCast(std::string_view(tmpBuf.c_str() + 1)); } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::Or4High: case category_t::Or6High4Med2Low: @@ -345,7 +357,10 @@ irs::filter::prepared::ptr prepareFilter( irs::ViewCast(std::string_view{tmpBuf}); } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::Prefix3: { // cut '~' at the end of the text @@ -357,7 +372,10 @@ irs::filter::prepared::ptr prepareFilter( opts->scored_terms_limit = scored_terms_limit; opts->term = irs::ViewCast(terms); - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::Wildcard: { terms = std::string_view(text.data(), text.size()); @@ -379,7 +397,10 @@ irs::filter::prepared::ptr prepareFilter( } } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::Fuzzy1: case category_t::Fuzzy2: { @@ -394,7 +415,10 @@ irs::filter::prepared::ptr prepareFilter( opts->max_distance = (category == category_t::Fuzzy1 ? 1 : 2); opts->term = irs::ViewCast(term); - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } case category_t::MinMatch2High2Med: { if (irs::IsNull(terms = splitFreq(text))) { @@ -415,7 +439,10 @@ irs::filter::prepared::ptr prepareFilter( irs::ViewCast(std::string_view{tmpBuf}); } } - return query.prepare(reader, order); + return query.prepare({ + .index = reader, + .scorers = order, + }); } default: return nullptr;