1use downcast_rs::impl_downcast;
85
86use crate::{DocId, Score, SegmentOrdinal, SegmentReader};
87
88mod count_collector;
89pub use self::count_collector::Count;
90
91mod histogram_collector;
92pub use histogram_collector::HistogramCollector;
93
94mod multi_collector;
95pub use self::multi_collector::{FruitHandle, MultiCollector, MultiFruit};
96
97mod top_collector;
98
99mod top_score_collector;
100pub use self::top_collector::ComparableDoc;
101pub use self::top_score_collector::{TopDocs, TopNComputer};
102
103mod custom_score_top_collector;
104pub use self::custom_score_top_collector::{CustomScorer, CustomSegmentScorer};
105
106mod tweak_score_top_collector;
107pub use self::tweak_score_top_collector::{ScoreSegmentTweaker, ScoreTweaker};
108mod facet_collector;
109pub use self::facet_collector::{FacetCollector, FacetCounts};
110use crate::query::Weight;
111
112mod docset_collector;
113pub use self::docset_collector::DocSetCollector;
114
115mod filter_collector_wrapper;
116pub use self::filter_collector_wrapper::{BytesFilterCollector, FilterCollector};
117
118pub trait Fruit: Send + downcast_rs::Downcast {}
121
122impl<T> Fruit for T where T: Send + downcast_rs::Downcast {}
123
124pub trait Collector: Sync + Send {
141 type Fruit: Fruit;
144
145 type Child: SegmentCollector;
147
148 fn for_segment(
151 &self,
152 segment_local_id: SegmentOrdinal,
153 segment: &SegmentReader,
154 ) -> crate::Result<Self::Child>;
155
156 fn requires_scoring(&self) -> bool;
158
159 fn merge_fruits(
162 &self,
163 segment_fruits: Vec<<Self::Child as SegmentCollector>::Fruit>,
164 ) -> crate::Result<Self::Fruit>;
165
166 fn collect_segment(
168 &self,
169 weight: &dyn Weight,
170 segment_ord: u32,
171 reader: &SegmentReader,
172 ) -> crate::Result<<Self::Child as SegmentCollector>::Fruit> {
173 let mut segment_collector = self.for_segment(segment_ord, reader)?;
174
175 match (reader.alive_bitset(), self.requires_scoring()) {
176 (Some(alive_bitset), true) => {
177 weight.for_each(reader, &mut |doc, score| {
178 if alive_bitset.is_alive(doc) {
179 segment_collector.collect(doc, score);
180 }
181 })?;
182 }
183 (Some(alive_bitset), false) => {
184 weight.for_each_no_score(reader, &mut |docs| {
185 for doc in docs.iter().cloned() {
186 if alive_bitset.is_alive(doc) {
187 segment_collector.collect(doc, 0.0);
188 }
189 }
190 })?;
191 }
192 (None, true) => {
193 weight.for_each(reader, &mut |doc, score| {
194 segment_collector.collect(doc, score);
195 })?;
196 }
197 (None, false) => {
198 weight.for_each_no_score(reader, &mut |docs| {
199 segment_collector.collect_block(docs);
200 })?;
201 }
202 }
203
204 Ok(segment_collector.harvest())
205 }
206}
207
208impl<TSegmentCollector: SegmentCollector> SegmentCollector for Option<TSegmentCollector> {
209 type Fruit = Option<TSegmentCollector::Fruit>;
210
211 fn collect(&mut self, doc: DocId, score: Score) {
212 if let Some(segment_collector) = self {
213 segment_collector.collect(doc, score);
214 }
215 }
216
217 fn harvest(self) -> Self::Fruit {
218 self.map(|segment_collector| segment_collector.harvest())
219 }
220}
221
222impl<TCollector: Collector> Collector for Option<TCollector> {
223 type Fruit = Option<TCollector::Fruit>;
224
225 type Child = Option<<TCollector as Collector>::Child>;
226
227 fn for_segment(
228 &self,
229 segment_local_id: SegmentOrdinal,
230 segment: &SegmentReader,
231 ) -> crate::Result<Self::Child> {
232 Ok(if let Some(inner) = self {
233 let inner_segment_collector = inner.for_segment(segment_local_id, segment)?;
234 Some(inner_segment_collector)
235 } else {
236 None
237 })
238 }
239
240 fn requires_scoring(&self) -> bool {
241 self.as_ref()
242 .map(|inner| inner.requires_scoring())
243 .unwrap_or(false)
244 }
245
246 fn merge_fruits(
247 &self,
248 segment_fruits: Vec<<Self::Child as SegmentCollector>::Fruit>,
249 ) -> crate::Result<Self::Fruit> {
250 if let Some(inner) = self.as_ref() {
251 let inner_segment_fruits: Vec<_> = segment_fruits
252 .into_iter()
253 .flat_map(|fruit_opt| fruit_opt.into_iter())
254 .collect();
255 let fruit = inner.merge_fruits(inner_segment_fruits)?;
256 Ok(Some(fruit))
257 } else {
258 Ok(None)
259 }
260 }
261}
262
263pub trait SegmentCollector: 'static {
269 type Fruit: Fruit;
272
273 fn collect(&mut self, doc: DocId, score: Score);
275
276 fn collect_block(&mut self, docs: &[DocId]) {
282 for doc in docs {
283 self.collect(*doc, 0.0);
284 }
285 }
286
287 fn harvest(self) -> Self::Fruit;
289}
290
291impl<Left, Right> Collector for (Left, Right)
295where
296 Left: Collector,
297 Right: Collector,
298{
299 type Fruit = (Left::Fruit, Right::Fruit);
300 type Child = (Left::Child, Right::Child);
301
302 fn for_segment(
303 &self,
304 segment_local_id: u32,
305 segment: &SegmentReader,
306 ) -> crate::Result<Self::Child> {
307 let left = self.0.for_segment(segment_local_id, segment)?;
308 let right = self.1.for_segment(segment_local_id, segment)?;
309 Ok((left, right))
310 }
311
312 fn requires_scoring(&self) -> bool {
313 self.0.requires_scoring() || self.1.requires_scoring()
314 }
315
316 fn merge_fruits(
317 &self,
318 segment_fruits: Vec<<Self::Child as SegmentCollector>::Fruit>,
319 ) -> crate::Result<(Left::Fruit, Right::Fruit)> {
320 let mut left_fruits = vec![];
321 let mut right_fruits = vec![];
322 for (left_fruit, right_fruit) in segment_fruits {
323 left_fruits.push(left_fruit);
324 right_fruits.push(right_fruit);
325 }
326 Ok((
327 self.0.merge_fruits(left_fruits)?,
328 self.1.merge_fruits(right_fruits)?,
329 ))
330 }
331}
332
333impl<Left, Right> SegmentCollector for (Left, Right)
334where
335 Left: SegmentCollector,
336 Right: SegmentCollector,
337{
338 type Fruit = (Left::Fruit, Right::Fruit);
339
340 fn collect(&mut self, doc: DocId, score: Score) {
341 self.0.collect(doc, score);
342 self.1.collect(doc, score);
343 }
344
345 fn harvest(self) -> <Self as SegmentCollector>::Fruit {
346 (self.0.harvest(), self.1.harvest())
347 }
348}
349
350impl<One, Two, Three> Collector for (One, Two, Three)
353where
354 One: Collector,
355 Two: Collector,
356 Three: Collector,
357{
358 type Fruit = (One::Fruit, Two::Fruit, Three::Fruit);
359 type Child = (One::Child, Two::Child, Three::Child);
360
361 fn for_segment(
362 &self,
363 segment_local_id: u32,
364 segment: &SegmentReader,
365 ) -> crate::Result<Self::Child> {
366 let one = self.0.for_segment(segment_local_id, segment)?;
367 let two = self.1.for_segment(segment_local_id, segment)?;
368 let three = self.2.for_segment(segment_local_id, segment)?;
369 Ok((one, two, three))
370 }
371
372 fn requires_scoring(&self) -> bool {
373 self.0.requires_scoring() || self.1.requires_scoring() || self.2.requires_scoring()
374 }
375
376 fn merge_fruits(
377 &self,
378 children: Vec<<Self::Child as SegmentCollector>::Fruit>,
379 ) -> crate::Result<Self::Fruit> {
380 let mut one_fruits = vec![];
381 let mut two_fruits = vec![];
382 let mut three_fruits = vec![];
383 for (one_fruit, two_fruit, three_fruit) in children {
384 one_fruits.push(one_fruit);
385 two_fruits.push(two_fruit);
386 three_fruits.push(three_fruit);
387 }
388 Ok((
389 self.0.merge_fruits(one_fruits)?,
390 self.1.merge_fruits(two_fruits)?,
391 self.2.merge_fruits(three_fruits)?,
392 ))
393 }
394}
395
396impl<One, Two, Three> SegmentCollector for (One, Two, Three)
397where
398 One: SegmentCollector,
399 Two: SegmentCollector,
400 Three: SegmentCollector,
401{
402 type Fruit = (One::Fruit, Two::Fruit, Three::Fruit);
403
404 fn collect(&mut self, doc: DocId, score: Score) {
405 self.0.collect(doc, score);
406 self.1.collect(doc, score);
407 self.2.collect(doc, score);
408 }
409
410 fn harvest(self) -> <Self as SegmentCollector>::Fruit {
411 (self.0.harvest(), self.1.harvest(), self.2.harvest())
412 }
413}
414
415impl<One, Two, Three, Four> Collector for (One, Two, Three, Four)
418where
419 One: Collector,
420 Two: Collector,
421 Three: Collector,
422 Four: Collector,
423{
424 type Fruit = (One::Fruit, Two::Fruit, Three::Fruit, Four::Fruit);
425 type Child = (One::Child, Two::Child, Three::Child, Four::Child);
426
427 fn for_segment(
428 &self,
429 segment_local_id: u32,
430 segment: &SegmentReader,
431 ) -> crate::Result<Self::Child> {
432 let one = self.0.for_segment(segment_local_id, segment)?;
433 let two = self.1.for_segment(segment_local_id, segment)?;
434 let three = self.2.for_segment(segment_local_id, segment)?;
435 let four = self.3.for_segment(segment_local_id, segment)?;
436 Ok((one, two, three, four))
437 }
438
439 fn requires_scoring(&self) -> bool {
440 self.0.requires_scoring()
441 || self.1.requires_scoring()
442 || self.2.requires_scoring()
443 || self.3.requires_scoring()
444 }
445
446 fn merge_fruits(
447 &self,
448 children: Vec<<Self::Child as SegmentCollector>::Fruit>,
449 ) -> crate::Result<Self::Fruit> {
450 let mut one_fruits = vec![];
451 let mut two_fruits = vec![];
452 let mut three_fruits = vec![];
453 let mut four_fruits = vec![];
454 for (one_fruit, two_fruit, three_fruit, four_fruit) in children {
455 one_fruits.push(one_fruit);
456 two_fruits.push(two_fruit);
457 three_fruits.push(three_fruit);
458 four_fruits.push(four_fruit);
459 }
460 Ok((
461 self.0.merge_fruits(one_fruits)?,
462 self.1.merge_fruits(two_fruits)?,
463 self.2.merge_fruits(three_fruits)?,
464 self.3.merge_fruits(four_fruits)?,
465 ))
466 }
467}
468
469impl<One, Two, Three, Four> SegmentCollector for (One, Two, Three, Four)
470where
471 One: SegmentCollector,
472 Two: SegmentCollector,
473 Three: SegmentCollector,
474 Four: SegmentCollector,
475{
476 type Fruit = (One::Fruit, Two::Fruit, Three::Fruit, Four::Fruit);
477
478 fn collect(&mut self, doc: DocId, score: Score) {
479 self.0.collect(doc, score);
480 self.1.collect(doc, score);
481 self.2.collect(doc, score);
482 self.3.collect(doc, score);
483 }
484
485 fn harvest(self) -> <Self as SegmentCollector>::Fruit {
486 (
487 self.0.harvest(),
488 self.1.harvest(),
489 self.2.harvest(),
490 self.3.harvest(),
491 )
492 }
493}
494
495impl_downcast!(Fruit);
496
497#[cfg(test)]
498pub(crate) mod tests;