use crate::query::Scorer;
use crate::Score;
pub trait ScoreCombiner: Default + Clone + Send + Copy + 'static {
fn update<TScorer: Scorer>(&mut self, scorer: &mut TScorer);
fn clear(&mut self);
fn score(&self) -> Score;
}
#[derive(Default, Clone, Copy)] pub struct DoNothingCombiner;
impl ScoreCombiner for DoNothingCombiner {
fn update<TScorer: Scorer>(&mut self, _scorer: &mut TScorer) {}
fn clear(&mut self) {}
fn score(&self) -> Score {
1.0
}
}
#[derive(Default, Clone, Copy)]
pub struct SumCombiner {
score: Score,
}
impl ScoreCombiner for SumCombiner {
fn update<TScorer: Scorer>(&mut self, scorer: &mut TScorer) {
self.score += scorer.score();
}
fn clear(&mut self) {
self.score = 0.0;
}
fn score(&self) -> Score {
self.score
}
}
#[derive(Default, Clone, Copy)]
pub struct SumWithCoordsCombiner {
num_fields: usize,
score: Score,
}
impl ScoreCombiner for SumWithCoordsCombiner {
fn update<TScorer: Scorer>(&mut self, scorer: &mut TScorer) {
self.score += scorer.score();
self.num_fields += 1;
}
fn clear(&mut self) {
self.score = 0.0;
self.num_fields = 0;
}
fn score(&self) -> Score {
self.score
}
}
#[derive(Default, Clone, Copy)]
pub struct DisjunctionMaxCombiner {
max: Score,
sum: Score,
tie_breaker: Score,
}
impl DisjunctionMaxCombiner {
pub fn with_tie_breaker(tie_breaker: Score) -> DisjunctionMaxCombiner {
DisjunctionMaxCombiner {
max: 0.0,
sum: 0.0,
tie_breaker,
}
}
}
impl ScoreCombiner for DisjunctionMaxCombiner {
fn update<TScorer: Scorer>(&mut self, scorer: &mut TScorer) {
let score = scorer.score();
self.max = Score::max(score, self.max);
self.sum += score;
}
fn clear(&mut self) {
self.max = 0.0;
self.sum = 0.0;
}
fn score(&self) -> Score {
self.max + (self.sum - self.max) * self.tie_breaker
}
}