mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2026-05-31 07:30:39 +00:00
Scoring for union.
This commit is contained in:
@@ -4,6 +4,7 @@ use postings::SkipResult;
|
||||
use common::TinySet;
|
||||
use std::cmp::Ordering;
|
||||
use DocId;
|
||||
use Score;
|
||||
use query::score_combiner::{DoNothingCombiner, ScoreCombiner};
|
||||
|
||||
const HORIZON_NUM_TINYBITSETS: usize = 32;
|
||||
@@ -18,6 +19,7 @@ pub struct Union<TScorer, TScoreCombiner=DoNothingCombiner>
|
||||
cursor: usize,
|
||||
offset: DocId,
|
||||
doc: DocId,
|
||||
score: Score,
|
||||
}
|
||||
|
||||
impl<TScorer, TScoreCombiner> From<Vec<TScorer>>
|
||||
@@ -44,6 +46,7 @@ impl<TScorer, TScoreCombiner> From<Vec<TScorer>>
|
||||
cursor: HORIZON_NUM_TINYBITSETS,
|
||||
offset: 0,
|
||||
doc: 0,
|
||||
score: 0f32
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +92,11 @@ impl<TScorer: Scorer, TScoreCombiner: ScoreCombiner> Union<TScorer, TScoreCombin
|
||||
fn advance_buffered(&mut self) -> bool {
|
||||
while self.cursor < HORIZON_NUM_TINYBITSETS {
|
||||
if let Some(val) = self.bitsets[self.cursor].pop_lowest() {
|
||||
self.doc = self.offset + val + (self.cursor as u32) * 64;
|
||||
let delta = val + (self.cursor as u32) * 64;
|
||||
self.doc = self.offset + delta;
|
||||
let score_combiner = &mut self.scores[delta as usize];
|
||||
self.score = score_combiner.score();
|
||||
score_combiner.clear();
|
||||
return true;
|
||||
} else {
|
||||
self.cursor += 1;
|
||||
@@ -129,6 +136,9 @@ impl<TScorer: Scorer, TScoreCombiner: ScoreCombiner> DocSet for Union<TScorer, T
|
||||
for obsolete_tinyset in &mut self.bitsets[self.cursor..new_cursor] {
|
||||
*obsolete_tinyset = TinySet::empty();
|
||||
}
|
||||
for score_combiner in &mut self.scores[self.cursor*64..new_cursor*64] {
|
||||
score_combiner.clear();
|
||||
}
|
||||
self.cursor = new_cursor;
|
||||
|
||||
// Advancing until we reach the end of the bucket
|
||||
@@ -150,6 +160,9 @@ impl<TScorer: Scorer, TScoreCombiner: ScoreCombiner> DocSet for Union<TScorer, T
|
||||
for obsolete_tinyset in self.bitsets.iter_mut() {
|
||||
*obsolete_tinyset = TinySet::empty();
|
||||
}
|
||||
for score_combiner in self.scores.iter_mut() {
|
||||
score_combiner.clear();
|
||||
}
|
||||
|
||||
// The target is outside of the buffered horizon.
|
||||
// advance all docsets to a doc >= to the target.
|
||||
@@ -186,6 +199,14 @@ impl<TScorer: Scorer, TScoreCombiner: ScoreCombiner> DocSet for Union<TScorer, T
|
||||
}
|
||||
}
|
||||
|
||||
impl<TScorer, TScoreCombiner> Scorer for Union<TScorer, TScoreCombiner>
|
||||
where TScoreCombiner: ScoreCombiner,
|
||||
TScorer: Scorer {
|
||||
fn score(&mut self) -> Score {
|
||||
self.score
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
||||
@@ -11,13 +11,15 @@ use query::RequiredOptionalScorer;
|
||||
use query::score_combiner::{SumWithCoordsCombiner, DoNothingCombiner, ScoreCombiner};
|
||||
use Result;
|
||||
|
||||
fn scorer_union<'a, TScoreCombiner: ScoreCombiner + 'static>(docsets: Vec<Box<Scorer + 'a>>) -> Box<Scorer + 'a> {
|
||||
fn scorer_union<'a, TScoreCombiner>(docsets: Vec<Box<Scorer + 'a>>) -> Box<Scorer + 'a>
|
||||
where TScoreCombiner: ScoreCombiner + 'static
|
||||
{
|
||||
assert!(!docsets.is_empty());
|
||||
if docsets.len() == 1 {
|
||||
docsets.into_iter().next().unwrap() //< we checked the size beforehands
|
||||
} else {
|
||||
// TODO have a UnionScorer instead.
|
||||
box ConstScorer::new(Union::<_, TScoreCombiner>::from(docsets))
|
||||
box Union::<_, TScoreCombiner>::from(docsets)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,21 +86,6 @@ impl BooleanWeight {
|
||||
Ok(positive_scorer)
|
||||
}
|
||||
}
|
||||
|
||||
// fn scorer_if_scoring_enabled<'a>(
|
||||
// &'a self,
|
||||
// reader: &'a SegmentReader,
|
||||
// ) -> Result<Box<Scorer + 'a>> {
|
||||
// let sub_scorers: Vec<Box<Scorer + 'a>> = self.weights
|
||||
// .iter()
|
||||
// .map(|&(_, ref weight)| weight)
|
||||
// .map(|weight| weight.scorer(reader))
|
||||
// .collect::<Result<_>>()?;
|
||||
// let occurs: Vec<Occur> = self.weights.iter().map(|&(ref occur, _)| *occur).collect();
|
||||
// let occur_filter = OccurFilter::new(&occurs);
|
||||
// let boolean_scorer = BooleanScorer::new(sub_scorers, occur_filter);
|
||||
// Ok(box boolean_scorer)
|
||||
// }
|
||||
}
|
||||
|
||||
impl Weight for BooleanWeight {
|
||||
|
||||
Reference in New Issue
Block a user