1use std::num::NonZeroU32;
2
3use async_recursion::async_recursion;
4use futures::future;
5use idx_binary::{AvltrieeIter, AvltrieeSearch};
6
7use crate::{Condition, CustomSort, Data, FieldName, Order, RowSet, Search};
8
9use super::{Field, Number, Term};
10
11impl<'a> Search<'a> {
12 pub async fn result(&self) -> RowSet {
13 if self.conditions.len() > 0 {
14 self.data.result(&self.conditions).await
15 } else {
16 self.data.all()
17 }
18 }
19
20 pub async fn result_with_sort<C: CustomSort>(&self, orders: Vec<Order<C>>) -> Vec<NonZeroU32> {
21 self.data.sort(&self.result().await, &orders)
22 }
23}
24
25impl Data {
26 #[async_recursion(?Send)]
28 pub async fn result_condition(&self, condition: &Condition) -> RowSet {
29 match condition {
30 Condition::Activity(condition) => {
31 if let Some(ref index) = self.activity {
32 let activity = *condition as u8;
33 index.iter_by(&activity).collect()
34 } else {
35 RowSet::default()
36 }
37 }
38 Condition::Term(condition) => self.result_term(condition),
39 Condition::Field(field_name, condition) => self.result_field(field_name, condition),
40 Condition::Row(condition) => self.result_row(condition),
41 Condition::LastUpdated(condition) => self.result_last_updated(condition),
42 Condition::Uuid(uuid) => self.result_uuid(uuid),
43 Condition::Narrow(conditions) => self.result(conditions).await,
44 Condition::Wide(conditions) => {
45 future::join_all(conditions.into_iter().map(|c| self.result_condition(c)))
46 .await
47 .into_iter()
48 .flatten()
49 .collect()
50 }
51 }
52 }
53
54 #[async_recursion(?Send)]
55 async fn result(&self, conditions: &Vec<Condition>) -> RowSet {
56 let (mut rows, _index, fs) =
57 future::select_all(conditions.into_iter().map(|c| self.result_condition(c))).await;
58 for r in future::join_all(fs).await.into_iter() {
59 rows.retain(|v| r.contains(v));
60 }
61 rows
62 }
63
64 fn result_last_updated(&self, condition: &Number) -> RowSet {
65 if let Some(ref f) = self.last_updated {
66 match condition {
67 Number::Min(min) => {
68 let min = *min as u64;
69 f.iter_from(&min).collect()
70 }
71 Number::Max(max) => {
72 let max = *max as u64;
73 f.iter_to(&max).collect()
74 }
75 Number::Range(range) => f
76 .iter_range(&(*range.start() as u64), &(*range.end() as u64))
77 .collect(),
78 Number::In(rows) => rows
79 .into_iter()
80 .map(|i| f.iter_by(&(*i as u64)))
81 .flatten()
82 .collect(),
83 }
84 } else {
85 unreachable!();
86 }
87 }
88
89 fn result_uuid(&self, uuids: &[u128]) -> RowSet {
90 if let Some(ref index) = self.uuid {
91 uuids
92 .into_iter()
93 .map(|uuid| index.iter_by(&uuid))
94 .flatten()
95 .collect()
96 } else {
97 unreachable!();
98 }
99 }
100 fn result_term(&self, condition: &Term) -> RowSet {
101 match condition {
102 Term::In(base) => {
103 if let Some(ref term_begin) = self.term_begin {
104 if let Some(ref term_end) = self.term_end {
105 return term_begin
106 .iter_to(base)
107 .filter_map(|row| {
108 let end = term_end.value(row).unwrap_or(&0);
109 (*end == 0 || end > base).then_some(row)
110 })
111 .collect();
112 } else {
113 unreachable!();
114 }
115 } else {
116 unreachable!();
117 }
118 }
119 Term::Future(base) => {
120 if let Some(ref index) = self.term_begin {
121 return index.iter_from(&base).collect();
122 } else {
123 unreachable!();
124 }
125 }
126 Term::Past(base) => {
127 if let Some(ref index) = self.term_end {
128 return index.iter_range(&1, &base).collect();
129 } else {
130 unreachable!();
131 }
132 }
133 }
134 }
135
136 fn result_row(&self, condition: &Number) -> RowSet {
137 match condition {
138 Number::Min(row) => {
139 let row = *row;
140 self.serial
141 .iter()
142 .filter_map(|i| (i.get() as isize >= row).then_some(i))
143 .collect()
144 }
145 Number::Max(row) => {
146 let row = *row;
147 self.serial
148 .iter()
149 .filter_map(|i| (i.get() as isize <= row).then_some(i))
150 .collect()
151 }
152 Number::Range(range) => range
153 .clone()
154 .filter_map(|i| {
155 (i > 0
156 && self
157 .serial
158 .node(unsafe { NonZeroU32::new_unchecked(i as u32) })
159 .is_some())
160 .then_some(unsafe { NonZeroU32::new_unchecked(i as u32) })
161 })
162 .collect(),
163 Number::In(rows) => rows
164 .into_iter()
165 .filter_map(|i| {
166 let i = *i;
167 (i > 0
168 && self
169 .serial
170 .node(unsafe { NonZeroU32::new_unchecked(i as u32) })
171 .is_some())
172 .then_some(unsafe { NonZeroU32::new_unchecked(i as u32) })
173 })
174 .collect(),
175 }
176 }
177
178 pub fn result_field(&self, name: &FieldName, condition: &Field) -> RowSet {
179 if let Some(field) = self.fields.get(name) {
180 match condition {
181 Field::Match(v) => AvltrieeIter::by(field, v).collect(),
182 Field::Min(min) => AvltrieeIter::from_asc(field, min).collect(),
183 Field::Max(max) => AvltrieeIter::to_asc(field, &max).collect(),
184 Field::Range(min, max) => AvltrieeIter::range_asc(field, &min, &max).collect(),
185 Field::Forward(cont) => Self::result_field_sub(field, cont, Self::forward),
186 Field::Partial(cont) => Self::result_field_sub(field, cont, Self::partial),
187 Field::Backward(cont) => Self::result_field_sub(field, cont, Self::backward),
188 Field::ValueForward(cont) => {
189 Self::result_field_sub(field, cont, Self::value_forward)
190 }
191 Field::ValuePartial(cont) => {
192 Self::result_field_sub(field, cont, Self::value_partial)
193 }
194 Field::ValueBackward(cont) => {
195 Self::result_field_sub(field, cont, Self::value_backward)
196 }
197 }
198 } else {
199 RowSet::default()
200 }
201 }
202
203 fn result_field_sub(
204 field: &crate::Field,
205 cont: &str,
206 func: fn(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool),
207 ) -> RowSet {
208 field
209 .as_ref()
210 .iter()
211 .map(|row| func(row, field, cont))
212 .filter_map(|(v, b)| b.then_some(v))
213 .collect()
214 }
215
216 fn forward(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
217 (
218 row,
219 field
220 .value(row)
221 .map_or(false, |bytes| bytes.starts_with(cont.as_bytes())),
222 )
223 }
224
225 fn partial(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
226 (
227 row,
228 field.value(row).map_or(false, |bytes| {
229 let len = cont.len();
230 len <= bytes.len() && {
231 let cont_bytes = cont.as_bytes();
232 bytes
233 .windows(len)
234 .position(|window| window == cont_bytes)
235 .is_some()
236 }
237 }),
238 )
239 }
240
241 fn backward(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
242 (
243 row,
244 field
245 .value(row)
246 .map_or(false, |bytes| bytes.ends_with(cont.as_bytes())),
247 )
248 }
249
250 fn value_forward(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
251 (
252 row,
253 field
254 .value(row)
255 .map_or(false, |bytes| cont.as_bytes().starts_with(bytes)),
256 )
257 }
258
259 fn value_partial(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
260 (
261 row,
262 field.value(row).map_or(false, |bytes| {
263 cont.as_bytes()
264 .windows(bytes.len())
265 .position(|window| window == bytes)
266 .is_some()
267 }),
268 )
269 }
270
271 fn value_backward(row: NonZeroU32, field: &crate::Field, cont: &str) -> (NonZeroU32, bool) {
272 (
273 row,
274 field
275 .value(row)
276 .map_or(false, |bytes| cont.as_bytes().ends_with(bytes)),
277 )
278 }
279}