Compare commits

...

2 Commits

Author SHA1 Message Date
Stu Hood
18d1e52d8c seek_into_the_danger_zone should seek to TERMINATED when it receives TERMINATED. 2026-01-22 14:31:04 -08:00
Stu Hood
458c11f59f Repro. 2026-01-22 14:31:04 -08:00
3 changed files with 61 additions and 0 deletions

View File

@@ -304,6 +304,41 @@ mod tests {
assert_eq!(intersection.doc(), TERMINATED);
}
#[test]
fn test_intersection_termination() {
use crate::query::score_combiner::DoNothingCombiner;
use crate::query::{BufferedUnionScorer, ConstScorer, VecDocSet};
let a1 = ConstScorer::new(VecDocSet::from(vec![0, 10000]), 1.0);
let a2 = ConstScorer::new(VecDocSet::from(vec![0, 10000]), 1.0);
let mut b_scorers = vec![];
for _ in 0..2 {
// Union matches 0 and 10000.
b_scorers.push(ConstScorer::new(VecDocSet::from(vec![0, 10000]), 1.0));
}
let union = BufferedUnionScorer::build(b_scorers, || DoNothingCombiner::default(), 30000);
// Mismatching scorer: matches 0 and 20000. Cost 100 to ensure it is last.
let mut m_docs = vec![0, 20000];
for i in 30000..30100 {
m_docs.push(i);
}
let m = ConstScorer::new(VecDocSet::from(m_docs), 1.0);
// Costs: A1=2, A2=2, Union=4, M=102.
// Sorted: A1, A2, Union, M.
// Left=A1, Right=A2, Others=[Union, M].
let mut intersection = crate::query::intersect_scorers(
vec![Box::new(a1), Box::new(a2), Box::new(union), Box::new(m)],
40000,
);
while intersection.doc() != TERMINATED {
intersection.advance();
}
}
// Strategy to generate sorted and deduplicated vectors of u32 document IDs
fn sorted_deduped_vec(max_val: u32, max_size: usize) -> impl Strategy<Value = Vec<u32>> {
prop::collection::vec(0..max_val, 0..max_size).prop_map(|mut vec| {

View File

@@ -231,6 +231,10 @@ where
// processed and removed, so we need to use seek, which uses the regular advance.
self.seek(target) == target
} else {
if target == TERMINATED {
self.seek(TERMINATED);
return true;
}
// The docsets are not in the buffered range, so we can use seek_into_the_danger_zone
// of the underlying docsets
let is_hit = self

View File

@@ -254,6 +254,28 @@ mod tests {
vec![1, 2, 3, 7, 8, 9, 99, 100, 101, 500, 20000],
);
}
#[test]
fn test_buffered_union_seek_into_danger_zone_terminated() {
let scorer1 = ConstScorer::new(VecDocSet::from(vec![1, 2]), 1.0);
let scorer2 = ConstScorer::new(VecDocSet::from(vec![2, 3]), 1.0);
let mut union_scorer = BufferedUnionScorer::build(
vec![scorer1, scorer2],
|| DoNothingCombiner::default(),
100,
);
// Advance to end
while union_scorer.doc() != TERMINATED {
union_scorer.advance();
}
assert_eq!(union_scorer.doc(), TERMINATED);
// This should return true
assert!(union_scorer.seek_into_the_danger_zone(TERMINATED));
}
}
#[cfg(all(test, feature = "unstable"))]