pub struct StrategySelector { /* private fields */ }Expand description
Picks a concrete FilterStrategy for a validated filter from its
estimated selectivity — the Tier-2, tunable counterpart to
choose_strategy.
The rule is simple and monotone: a narrow predicate (low
estimate_selectivity, at or below the
threshold) resolves to FilterStrategy::PreFilter, because evaluating it
up front skips the distance computation for the rows it rejects; a broad
predicate resolves to FilterStrategy::PostFilter, because pre-filtering
would materialise nearly the whole corpus for little gain. The selector
never returns FilterStrategy::Auto (it is the thing that resolves it) or
FilterStrategy::InFilter (which needs graph-traversal co-design).
The type is immutable: with_prefilter_threshold
returns a new selector rather than mutating in place.
§Examples
use iqdb_filter::{FilterEvaluator, FilterStrategy, StrategySelector};
use iqdb_types::{Filter, Value};
let selector = StrategySelector::new().with_prefilter_threshold(0.3);
let narrow = FilterEvaluator::new(Filter::eq("id", Value::Int(7)))?;
let broad = FilterEvaluator::new(Filter::neq("id", Value::Int(7)))?;
assert_eq!(selector.choose(&narrow), FilterStrategy::PreFilter);
assert_eq!(selector.choose(&broad), FilterStrategy::PostFilter);Implementations§
Source§impl StrategySelector
impl StrategySelector
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a selector with the DEFAULT_PREFILTER_THRESHOLD.
§Examples
use iqdb_filter::{StrategySelector, DEFAULT_PREFILTER_THRESHOLD};
let selector = StrategySelector::new();
assert_eq!(selector.prefilter_threshold(), DEFAULT_PREFILTER_THRESHOLD);Sourcepub fn with_prefilter_threshold(self, threshold: f64) -> Self
pub fn with_prefilter_threshold(self, threshold: f64) -> Self
Returns a new selector that pre-filters when estimated selectivity is at
or below threshold.
threshold is clamped to [0.0, 1.0]: 0.0 pre-filters only the most
extreme predicates (effectively always post-filter), 1.0 always
pre-filters.
§Examples
use iqdb_filter::StrategySelector;
let always_pre = StrategySelector::new().with_prefilter_threshold(1.0);
assert_eq!(always_pre.prefilter_threshold(), 1.0);
// Out-of-range values are clamped, never panic.
let clamped = StrategySelector::new().with_prefilter_threshold(2.5);
assert_eq!(clamped.prefilter_threshold(), 1.0);Sourcepub fn prefilter_threshold(&self) -> f64
pub fn prefilter_threshold(&self) -> f64
The selectivity cutoff this selector uses.
Sourcepub fn choose(&self, evaluator: &FilterEvaluator) -> FilterStrategy
pub fn choose(&self, evaluator: &FilterEvaluator) -> FilterStrategy
Resolves the strategy for evaluator’s filter.
Returns FilterStrategy::PreFilter when the estimated selectivity is
at or below prefilter_threshold, and
FilterStrategy::PostFilter otherwise.
§Examples
use iqdb_filter::{FilterEvaluator, FilterStrategy, StrategySelector};
use iqdb_types::{Filter, Value};
let evaluator = FilterEvaluator::new(Filter::eq("k", Value::Int(1)))?;
assert_eq!(StrategySelector::new().choose(&evaluator), FilterStrategy::PreFilter);Sourcepub fn choose_with_index<K>(
&self,
evaluator: &FilterEvaluator,
index: &MetadataIndex<K>,
) -> FilterStrategy
pub fn choose_with_index<K>( &self, evaluator: &FilterEvaluator, index: &MetadataIndex<K>, ) -> FilterStrategy
Resolves the strategy using the index-backed selectivity estimate
from index (MetadataIndex::estimate_selectivity),
which uses real posting counts where it can.
Prefer this over choose when an index is available:
the count-based estimate is sharper than the structural one, so the
pre/post decision is better informed.
§Examples
use iqdb_filter::{FilterEvaluator, FilterStrategy, MetadataIndex, StrategySelector};
use iqdb_types::{Filter, Metadata, Value};
// 1 of 4 rows matches: a genuinely narrow predicate the index can see.
let rows = [
(0_usize, [("tier".to_string(), Value::Int(1))].into_iter().collect::<Metadata>()),
(1, [("tier".to_string(), Value::Int(2))].into_iter().collect::<Metadata>()),
(2, [("tier".to_string(), Value::Int(2))].into_iter().collect::<Metadata>()),
(3, [("tier".to_string(), Value::Int(2))].into_iter().collect::<Metadata>()),
];
let index = MetadataIndex::build(&["tier"], rows.iter().map(|(k, m)| (*k, Some(m))));
let evaluator = FilterEvaluator::new(Filter::eq("tier", Value::Int(1)))?;
let selector = StrategySelector::new();
assert_eq!(selector.choose_with_index(&evaluator, &index), FilterStrategy::PreFilter);Trait Implementations§
Source§impl Clone for StrategySelector
impl Clone for StrategySelector
Source§fn clone(&self) -> StrategySelector
fn clone(&self) -> StrategySelector
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more