Scoring for union.

This commit is contained in:
Paul Masurel
2018-02-17 11:56:21 +09:00
parent 8760899fa2
commit 0300e7272b
2 changed files with 26 additions and 18 deletions

View File

@@ -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 {

View File

@@ -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 {