1use super::{AllDocSet, CountFuture, DocBitset, DocPredicate, DocSet, Query, Scorer, ScorerFuture};
3use crate::segment::SegmentReader;
4use crate::{DocId, Score};
5
6#[derive(Debug, Clone, Copy)]
8pub struct AllQuery;
9
10impl std::fmt::Display for AllQuery {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 f.write_str("All")
13 }
14}
15
16impl Query for AllQuery {
17 fn scorer<'a>(&self, reader: &'a SegmentReader, _limit: usize) -> ScorerFuture<'a> {
18 let scorer = AllScorer::new(reader.num_docs());
19 Box::pin(async move { Ok(Box::new(scorer) as Box<dyn Scorer>) })
20 }
21
22 #[cfg(feature = "sync")]
23 fn scorer_sync<'a>(
24 &self,
25 reader: &'a SegmentReader,
26 _limit: usize,
27 ) -> crate::Result<Box<dyn Scorer + 'a>> {
28 Ok(Box::new(AllScorer::new(reader.num_docs())))
29 }
30
31 fn count_estimate<'a>(&self, reader: &'a SegmentReader) -> CountFuture<'a> {
32 let count = reader.num_docs();
33 Box::pin(async move { Ok(count) })
34 }
35
36 fn is_filter(&self) -> bool {
37 true
38 }
39
40 fn as_doc_predicate<'a>(&self, reader: &'a SegmentReader) -> Option<DocPredicate<'a>> {
41 let count = reader.num_docs();
42 Some(Box::new(move |doc| doc < count))
43 }
44
45 fn as_doc_bitset(&self, reader: &SegmentReader) -> Option<DocBitset> {
46 Some(DocBitset::all(reader.num_docs()))
47 }
48}
49
50struct AllScorer(AllDocSet);
51
52impl AllScorer {
53 fn new(count: u32) -> Self {
54 Self(AllDocSet::new(count))
55 }
56}
57
58impl DocSet for AllScorer {
59 fn doc(&self) -> DocId {
60 self.0.doc()
61 }
62
63 fn advance(&mut self) -> DocId {
64 self.0.advance()
65 }
66
67 fn seek(&mut self, target: DocId) -> DocId {
68 self.0.seek(target)
69 }
70
71 fn size_hint(&self) -> u32 {
72 self.0.size_hint()
73 }
74}
75
76impl Scorer for AllScorer {
77 fn score(&self) -> Score {
78 1.0
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use crate::TERMINATED;
86 #[tokio::test]
87 async fn exclusion_filter_includes_documents_without_metadata_in_every_execution_path() {
88 use crate::query::{BooleanQuery, FilteredQuery, RangeQuery};
89 use crate::{Document, Index, IndexConfig, IndexWriter, RamDirectory, Schema};
90 use std::sync::Arc;
91 let mut schema = Schema::builder();
92 let date = schema.add_i64_field("date", true, false);
93 schema.set_fast(date, true);
94 let dir = RamDirectory::new();
95 let config = IndexConfig::default();
96 let mut writer = IndexWriter::create(dir.clone(), schema.build(), config.clone())
97 .await
98 .unwrap();
99 for date_value in [Some(-1), Some(0), None] {
100 let mut doc = Document::new();
101 if let Some(value) = date_value {
102 doc.add_i64(date, value);
103 }
104 writer.add_document(doc).unwrap();
105 }
106 writer.commit().await.unwrap();
107 let index = Index::open(dir, config).await.unwrap();
108 let searcher = index.reader().await.unwrap().searcher().await.unwrap();
109 let reader = &searcher.segment_readers()[0];
110 let filter =
111 BooleanQuery::new()
112 .must(AllQuery)
113 .must_not(RangeQuery::i64(date, Some(0), Some(0)));
114 let predicate = filter.as_doc_predicate(reader).unwrap();
115 let bits = filter.as_doc_bitset(reader).unwrap();
116 for doc in 0..3 {
117 assert_eq!(predicate(doc), doc != 1);
118 assert_eq!(bits.contains(doc), doc != 1);
119 }
120 let query = FilteredQuery::new(Arc::new(AllQuery), vec![Arc::new(filter)]);
121 let check = |mut scorer: Box<dyn Scorer + '_>| {
122 let mut docs = Vec::new();
123 while scorer.doc() != TERMINATED {
124 docs.push(scorer.doc());
125 scorer.advance();
126 }
127 assert_eq!(docs, [0, 2]);
128 };
129 check(query.scorer(reader, 10).await.unwrap());
130 #[cfg(feature = "sync")]
131 check(
132 query
133 .scorer_sync_with_options(reader, 10, super::super::ScorerOptions::default())
134 .unwrap(),
135 );
136 }
137
138 #[test]
139 fn complete_universe_has_no_tail_documents_and_seek_never_rewinds() {
140 for count in [0, 1, 63, 64, 65, 129] {
141 let bits = DocBitset::all(count);
142 let mut scorer = AllScorer::new(count);
143 for doc in 0..count {
144 assert!(bits.contains(doc));
145 assert_eq!(scorer.doc(), doc);
146 assert_eq!(scorer.score(), 1.0);
147 scorer.advance();
148 }
149 assert_eq!(bits.next_set_bit(count), None);
150 assert_eq!(scorer.doc(), TERMINATED);
151 assert_eq!(scorer.advance(), TERMINATED);
152 assert_eq!(scorer.seek(0), TERMINATED);
153 }
154 let mut scorer = AllScorer::new(10);
155 assert_eq!(scorer.seek(5), 5);
156 assert_eq!(scorer.seek(2), 5);
157 assert_eq!(scorer.advance(), 6);
158 }
159}