mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2026-01-07 09:32:54 +00:00
Added unit test to show bug in intersection
This commit is contained in:
@@ -25,4 +25,3 @@ impl Drop for DirectoryLock {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ pub trait DocSet {
|
||||
/// More specifically, if the docset is already positionned on the target
|
||||
/// skipping will advance to the next position and return SkipResult::Overstep.
|
||||
///
|
||||
/// If `.skip_next()` oversteps, then the docset must be positionned correctly
|
||||
/// on an existing document. In other words, `.doc()` should return the first document
|
||||
/// greater than `DocId`.
|
||||
fn skip_next(&mut self, target: DocId) -> SkipResult {
|
||||
if !self.advance() {
|
||||
return SkipResult::End;
|
||||
|
||||
@@ -32,37 +32,6 @@ impl<TDocSet: DocSet> IntersectionDocSet<TDocSet> {
|
||||
}
|
||||
|
||||
impl<TDocSet: DocSet> DocSet for IntersectionDocSet<TDocSet> {
|
||||
/// Returns the minimum `.size_hint()` of the intersected docsets.
|
||||
fn size_hint(&self) -> u32 {
|
||||
self.docsets
|
||||
.iter()
|
||||
.map(|docset| docset.size_hint())
|
||||
.min()
|
||||
.unwrap() // safe as docsets cannot be empty.
|
||||
}
|
||||
|
||||
fn skip_next(&mut self, mut target: DocId) -> SkipResult {
|
||||
let mut overstep = false;
|
||||
for docset in &mut self.docsets {
|
||||
match docset.skip_next(target) {
|
||||
SkipResult::End => {
|
||||
return SkipResult::End;
|
||||
}
|
||||
SkipResult::OverStep => {
|
||||
overstep = true;
|
||||
target = docset.doc();
|
||||
}
|
||||
SkipResult::Reached => {}
|
||||
}
|
||||
}
|
||||
if overstep {
|
||||
SkipResult::OverStep
|
||||
} else {
|
||||
SkipResult::Reached
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(never_loop)]
|
||||
fn advance(&mut self) -> bool {
|
||||
if self.finished {
|
||||
@@ -102,13 +71,53 @@ impl<TDocSet: DocSet> DocSet for IntersectionDocSet<TDocSet> {
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_next(&mut self, mut target: DocId) -> SkipResult {
|
||||
// We optimize skipping by skipping every single member
|
||||
// of the intersection to target.
|
||||
|
||||
// TODO fix BUG...
|
||||
// what if we overstep on the second member of the intersection?
|
||||
// The first member is not necessarily correct.
|
||||
let mut overstep = false;
|
||||
for docset in &mut self.docsets {
|
||||
match docset.skip_next(target) {
|
||||
SkipResult::End => {
|
||||
return SkipResult::End;
|
||||
}
|
||||
SkipResult::OverStep => {
|
||||
overstep = true;
|
||||
// update the target
|
||||
// for the remaining members of the intersection.
|
||||
target = docset.doc();
|
||||
}
|
||||
SkipResult::Reached => {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.doc = target;
|
||||
if overstep {
|
||||
SkipResult::OverStep
|
||||
} else {
|
||||
SkipResult::Reached
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn doc(&self) -> DocId {
|
||||
self.doc
|
||||
}
|
||||
fn size_hint(&self) -> u32 {
|
||||
self.docsets
|
||||
.iter()
|
||||
.map(|docset| docset.size_hint())
|
||||
.min()
|
||||
.unwrap_or(0u32)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use postings::SkipResult;
|
||||
|
||||
use postings::{DocSet, IntersectionDocSet, VecPostings};
|
||||
|
||||
@@ -144,6 +153,23 @@ mod tests {
|
||||
assert_eq!(intersection.doc(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_skip() {
|
||||
let left = VecPostings::from(vec![4]);
|
||||
let right = VecPostings::from(vec![2, 5]);
|
||||
let mut intersection = IntersectionDocSet::from(vec![left, right]);
|
||||
assert_eq!(intersection.skip_next(4), SkipResult::End);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_skip_2() {
|
||||
let left = VecPostings::from(vec![0, 1, 2, 4]);
|
||||
let right = VecPostings::from(vec![2, 5]);
|
||||
let mut intersection = IntersectionDocSet::from(vec![left, right]);
|
||||
assert_eq!(intersection.skip_next(2), SkipResult::Reached);
|
||||
assert_eq!(intersection.doc(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_empty() {
|
||||
let a = VecPostings::from(vec![1, 3]);
|
||||
|
||||
Reference in New Issue
Block a user