Skip to content

Commit 51370f7

Browse files
committed
Fixed major issue with OR queries. They are now propperly scaned for multiple occurrences.
1 parent f9bf398 commit 51370f7

File tree

1 file changed

+36
-8
lines changed

1 file changed

+36
-8
lines changed

src/query.rs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,13 @@ impl Part {
130130
) -> Box<(dyn FnMut(&'a str) -> Option<Box<dyn Iterator<Item = T> + 'a>> + 'a)> {
131131
Box::new(f)
132132
}
133-
fn as_doc_iter<'a, 'b, T: Ord + 'a, AndMI: Iterator<Item = T> + 'a>(
133+
fn as_doc_iter<
134+
'a,
135+
'b,
136+
T: Ord + 'a,
137+
AndMI: Iterator<Item = T> + 'a,
138+
OrMI: Iterator<Item = T> + 'a,
139+
>(
134140
&'a self,
135141
mut iter: impl std::ops::DerefMut<
136142
Target = (impl FnMut(&'a str) -> Option<Box<dyn Iterator<Item = T> + 'a>> + ?Sized + 'a),
@@ -143,25 +149,26 @@ impl Part {
143149
Box<dyn Iterator<Item = T> + 'a>,
144150
Box<dyn Iterator<Item = T> + 'a>,
145151
) -> AndMI,
152+
or_merger: &impl Fn(Box<dyn Iterator<Item = T> + 'a>, Box<dyn Iterator<Item = T> + 'a>) -> OrMI,
146153
) -> Result<Box<dyn Iterator<Item = T> + 'a>, IterError> {
147154
let iter = match self {
148155
Self::And(pair) => match (&pair.left, &pair.right) {
149156
(other, Part::Not(not)) | (Part::Not(not), other) => and_not_modify(
150-
other.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
151-
not.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
157+
other.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
158+
not.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
152159
),
153160
_ => Self::iter_to_box(and_merger(
154161
pair.left
155-
.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
162+
.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
156163
pair.right
157-
.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
164+
.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
158165
)),
159166
},
160-
Self::Or(pair) => Self::iter_to_box(set::union(
167+
Self::Or(pair) => Self::iter_to_box(or_merger(
161168
pair.left
162-
.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
169+
.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
163170
pair.right
164-
.as_doc_iter(&mut *iter, and_not_modify, and_merger)?,
171+
.as_doc_iter(&mut *iter, and_not_modify, and_merger, or_merger)?,
165172
)),
166173
Self::Not(_) => return Err(IterError::StrayNot),
167174
Self::String(s) => {
@@ -229,6 +236,7 @@ impl<'a, 'b, P: Provider<'a>> Documents<'a, 'b, P> {
229236
},
230237
&|i, _| i,
231238
&set::intersect,
239+
&set::union,
232240
)
233241
}
234242
pub fn take_proximate_map(&mut self) -> ProximateMap<'b> {
@@ -462,6 +470,7 @@ impl Query {
462470
}),
463471
)
464472
},
473+
// AND merger
465474
&|left, right| {
466475
crate::set::progressive(
467476
left,
@@ -480,6 +489,25 @@ impl Query {
480489
_ => None,
481490
})
482491
},
492+
// OR merger
493+
&|left, right| {
494+
crate::set::progressive(
495+
left,
496+
right,
497+
#[inline]
498+
|a, b| a.0.start().cmp(&b.0.start()),
499+
// Compares IDs
500+
#[inline]
501+
|a, b| (*a).cmp(b),
502+
)
503+
.map(|inclusion| match inclusion {
504+
ProgressiveInclusion::Both(mut a, b) => {
505+
a.0.merge(&b.0);
506+
a
507+
}
508+
ProgressiveInclusion::Left(a) | ProgressiveInclusion::Right(a) => a,
509+
})
510+
},
483511
)
484512
.map(|iter| {
485513
iter.map(|occ| {

0 commit comments

Comments
 (0)