pub struct BlockMaxScoreExecutor<S: ScoringIterator> { /* private fields */ }Expand description
Unified Block-Max MaxScore executor for top-k retrieval
Combines three optimizations from the literature into one executor:
- MaxScore partitioning (Turtle & Flood 1995): terms split into essential (must check) and non-essential (only scored if candidate is promising)
- Block-max pruning (Ding & Suel 2011): skip blocks where per-block upper bounds can’t beat the current threshold
- Conjunction optimization (Lucene/Grand 2023): progressively intersect essential terms as threshold rises, skipping docs that lack enough terms
Works with any type implementing ScoringIterator (text or sparse).
Replaces separate WAND and MaxScore executors with better performance
across all query lengths.
Implementations§
Source§impl<S: ScoringIterator> BlockMaxScoreExecutor<S>
impl<S: ScoringIterator> BlockMaxScoreExecutor<S>
Sourcepub fn new(scorers: Vec<S>, k: usize) -> Self
pub fn new(scorers: Vec<S>, k: usize) -> Self
Create a new executor with exact search (heap_factor = 1.0)
Sourcepub fn with_heap_factor(scorers: Vec<S>, k: usize, heap_factor: f32) -> Self
pub fn with_heap_factor(scorers: Vec<S>, k: usize, heap_factor: f32) -> Self
Create a new executor with approximate search
heap_factor controls the trade-off between speed and recall:
- 1.0 = exact search
- 0.8 = ~20% faster, minor recall loss
- 0.5 = much faster, noticeable recall loss
Sourcepub fn execute(self) -> Vec<ScoredDoc>
pub fn execute(self) -> Vec<ScoredDoc>
Execute Block-Max MaxScore and return top-k results
Algorithm:
- Partition terms into essential/non-essential based on max_score
- Find min_doc across essential scorers
- Conjunction check: skip if not enough essential terms present
- Block-max check: skip if block upper bounds can’t beat threshold
- Score essential scorers, check if non-essential scoring is needed
- Score non-essential scorers, group by ordinal, insert results
Auto Trait Implementations§
impl<S> Freeze for BlockMaxScoreExecutor<S>
impl<S> RefUnwindSafe for BlockMaxScoreExecutor<S>where
S: RefUnwindSafe,
impl<S> Send for BlockMaxScoreExecutor<S>where
S: Send,
impl<S> Sync for BlockMaxScoreExecutor<S>where
S: Sync,
impl<S> Unpin for BlockMaxScoreExecutor<S>where
S: Unpin,
impl<S> UnwindSafe for BlockMaxScoreExecutor<S>where
S: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self to the equivalent element of its superset.