mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2025-12-27 20:42:54 +00:00
Compare commits
3 Commits
warming
...
perf/exper
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7a98b11d7 | ||
|
|
a18932165f | ||
|
|
8f82d0b773 |
@@ -142,6 +142,11 @@ impl<TDocSet: DocSet + ?Sized> DocSet for Box<TDocSet> {
|
||||
unboxed.size_hint()
|
||||
}
|
||||
|
||||
fn append_to_bitset(&mut self, bitset: &mut BitSet) {
|
||||
let unboxed: &mut TDocSet = self.borrow_mut();
|
||||
unboxed.append_to_bitset(bitset);
|
||||
}
|
||||
|
||||
fn count(&mut self, delete_bitset: &DeleteBitSet) -> u32 {
|
||||
let unboxed: &mut TDocSet = self.borrow_mut();
|
||||
unboxed.count(delete_bitset)
|
||||
@@ -151,9 +156,4 @@ impl<TDocSet: DocSet + ?Sized> DocSet for Box<TDocSet> {
|
||||
let unboxed: &mut TDocSet = self.borrow_mut();
|
||||
unboxed.count_including_deleted()
|
||||
}
|
||||
|
||||
fn append_to_bitset(&mut self, bitset: &mut BitSet) {
|
||||
let unboxed: &mut TDocSet = self.borrow_mut();
|
||||
unboxed.append_to_bitset(bitset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +214,102 @@ impl<TDocSet: DocSet, TOtherDocSet: DocSet> DocSet for Intersection<TDocSet, TOt
|
||||
}
|
||||
}
|
||||
|
||||
// `ahead` is assumed to be initialized (ahead.advance() has been called at least once,
|
||||
// and this returned true).
|
||||
//
|
||||
// If behind is either uninitialized or `ahead.doc() > behind.doc()`.
|
||||
fn next_in_intersection<'a, TScorer: Scorer>(
|
||||
ahead: &'a mut TScorer,
|
||||
behind: &'a mut TScorer,
|
||||
) -> Option<DocId> {
|
||||
let candidate = ahead.doc();
|
||||
match behind.skip_next(candidate) {
|
||||
SkipResult::Reached => Some(candidate),
|
||||
SkipResult::OverStep => {
|
||||
// yeah for tail-recursion
|
||||
next_in_intersection(behind, ahead)
|
||||
}
|
||||
SkipResult::End => None,
|
||||
}
|
||||
}
|
||||
|
||||
enum SkipResultComplex {
|
||||
Reached,
|
||||
Overstep { other_ord: usize, candidate: DocId },
|
||||
End,
|
||||
}
|
||||
|
||||
fn skip_several_scorers<TDocSet: DocSet>(
|
||||
others: &mut [TDocSet],
|
||||
except_candidate_ord: usize,
|
||||
target: DocId,
|
||||
) -> SkipResultComplex {
|
||||
for (ord, docset) in others.iter_mut().enumerate() {
|
||||
// `candidate_ord` is already at the
|
||||
// right position.
|
||||
//
|
||||
// Calling `skip_next` would advance this docset
|
||||
// and miss it.
|
||||
if ord == except_candidate_ord {
|
||||
continue;
|
||||
}
|
||||
match docset.skip_next(target) {
|
||||
SkipResult::Reached => {}
|
||||
SkipResult::OverStep => {
|
||||
return SkipResultComplex::Overstep {
|
||||
other_ord: ord,
|
||||
candidate: docset.doc(),
|
||||
};
|
||||
}
|
||||
SkipResult::End => {
|
||||
return SkipResultComplex::End;
|
||||
}
|
||||
}
|
||||
}
|
||||
SkipResultComplex::Reached
|
||||
}
|
||||
|
||||
fn for_each<'a, TScorer: Scorer, TOtherscorer: Scorer>(
|
||||
left: &'a mut TScorer,
|
||||
right: &'a mut TScorer,
|
||||
others: &'a mut [TOtherscorer],
|
||||
callback: &mut FnMut(DocId, Score),
|
||||
) {
|
||||
let mut other_candidate_ord: usize = usize::max_value();
|
||||
if !left.advance() {
|
||||
return;
|
||||
}
|
||||
while let Some(candidate) = next_in_intersection(left, right) {
|
||||
// test the remaining scorers
|
||||
match skip_several_scorers(others, other_candidate_ord, candidate) {
|
||||
SkipResultComplex::Reached => {
|
||||
let intersection_score: Score = left.score()
|
||||
+ right.score()
|
||||
+ others.iter_mut().map(|other| other.score()).sum::<Score>();
|
||||
callback(candidate, intersection_score);
|
||||
if !left.advance() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
SkipResultComplex::Overstep {
|
||||
other_ord,
|
||||
candidate,
|
||||
} => match left.skip_next(candidate) {
|
||||
SkipResult::End => {
|
||||
return;
|
||||
}
|
||||
SkipResult::Reached => {
|
||||
other_candidate_ord = other_ord;
|
||||
}
|
||||
SkipResult::OverStep => other_candidate_ord = usize::max_value(),
|
||||
},
|
||||
SkipResultComplex::End => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TScorer, TOtherScorer> Scorer for Intersection<TScorer, TOtherScorer>
|
||||
where
|
||||
TScorer: Scorer,
|
||||
@@ -224,6 +320,10 @@ where
|
||||
+ self.right.score()
|
||||
+ self.others.iter_mut().map(Scorer::score).sum::<Score>()
|
||||
}
|
||||
|
||||
fn for_each(&mut self, callback: &mut FnMut(DocId, Score)) {
|
||||
for_each(&mut self.left, &mut self.right, &mut self.others, callback);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -16,6 +16,9 @@ pub trait Scorer: downcast_rs::Downcast + DocSet + 'static {
|
||||
|
||||
/// Iterates through all of the document matched by the DocSet
|
||||
/// `DocSet` and push the scored documents to the collector.
|
||||
///
|
||||
/// This method assumes that the Scorer is brand new, and `.advance()`
|
||||
/// and `.skip()` haven't been called yet.
|
||||
fn for_each(&mut self, callback: &mut FnMut(DocId, Score)) {
|
||||
while self.advance() {
|
||||
callback(self.doc(), self.score());
|
||||
|
||||
@@ -260,6 +260,23 @@ where
|
||||
fn score(&mut self) -> Score {
|
||||
self.score
|
||||
}
|
||||
|
||||
fn for_each(&mut self, callback: &mut FnMut(DocId, Score)) {
|
||||
// TODO how do we deal with the fact that people may have called .advance() before.
|
||||
while self.refill() {
|
||||
let offset = self.offset;
|
||||
for cursor in 0..HORIZON_NUM_TINYBITSETS {
|
||||
while let Some(val) = self.bitsets[cursor].pop_lowest() {
|
||||
let delta = val + (cursor as u32) * 64;
|
||||
let doc = offset + delta;
|
||||
let score_combiner = &mut self.scores[delta as usize];
|
||||
let score = score_combiner.score();
|
||||
callback(doc, score);
|
||||
score_combiner.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user