@@ -12,6 +12,7 @@ use crate::heed_codec::ByteSliceRefCodec;
12
12
use crate :: search:: criteria:: { resolve_query_tree, CriteriaBuilder , InitialCandidates } ;
13
13
use crate :: search:: facet:: { ascending_facet_sort, descending_facet_sort} ;
14
14
use crate :: search:: query_tree:: Operation ;
15
+ use crate :: search:: CriterionImplementationStrategy ;
15
16
use crate :: { FieldId , Index , Result } ;
16
17
17
18
/// Threshold on the number of candidates that will make
@@ -29,6 +30,7 @@ pub struct AscDesc<'t> {
29
30
allowed_candidates : RoaringBitmap ,
30
31
initial_candidates : InitialCandidates ,
31
32
faceted_candidates : RoaringBitmap ,
33
+ implementation_strategy : CriterionImplementationStrategy ,
32
34
parent : Box < dyn Criterion + ' t > ,
33
35
}
34
36
@@ -38,17 +40,19 @@ impl<'t> AscDesc<'t> {
38
40
rtxn : & ' t heed:: RoTxn ,
39
41
parent : Box < dyn Criterion + ' t > ,
40
42
field_name : String ,
43
+ implementation_strategy : CriterionImplementationStrategy ,
41
44
) -> Result < Self > {
42
- Self :: new ( index, rtxn, parent, field_name, true )
45
+ Self :: new ( index, rtxn, parent, field_name, true , implementation_strategy )
43
46
}
44
47
45
48
pub fn desc (
46
49
index : & ' t Index ,
47
50
rtxn : & ' t heed:: RoTxn ,
48
51
parent : Box < dyn Criterion + ' t > ,
49
52
field_name : String ,
53
+ implementation_strategy : CriterionImplementationStrategy ,
50
54
) -> Result < Self > {
51
- Self :: new ( index, rtxn, parent, field_name, false )
55
+ Self :: new ( index, rtxn, parent, field_name, false , implementation_strategy )
52
56
}
53
57
54
58
fn new (
@@ -57,6 +61,7 @@ impl<'t> AscDesc<'t> {
57
61
parent : Box < dyn Criterion + ' t > ,
58
62
field_name : String ,
59
63
is_ascending : bool ,
64
+ implementation_strategy : CriterionImplementationStrategy ,
60
65
) -> Result < Self > {
61
66
let fields_ids_map = index. fields_ids_map ( rtxn) ?;
62
67
let field_id = fields_ids_map. id ( & field_name) ;
@@ -82,6 +87,7 @@ impl<'t> AscDesc<'t> {
82
87
allowed_candidates : RoaringBitmap :: new ( ) ,
83
88
faceted_candidates,
84
89
initial_candidates : InitialCandidates :: Estimated ( RoaringBitmap :: new ( ) ) ,
90
+ implementation_strategy,
85
91
parent,
86
92
} )
87
93
}
@@ -149,6 +155,7 @@ impl<'t> Criterion for AscDesc<'t> {
149
155
field_id,
150
156
self . is_ascending ,
151
157
candidates & & self . faceted_candidates ,
158
+ self . implementation_strategy ,
152
159
) ?,
153
160
None => Box :: new ( std:: iter:: empty ( ) ) ,
154
161
} ;
@@ -170,6 +177,51 @@ impl<'t> Criterion for AscDesc<'t> {
170
177
}
171
178
}
172
179
180
+ fn facet_ordered_iterative < ' t > (
181
+ index : & ' t Index ,
182
+ rtxn : & ' t heed:: RoTxn ,
183
+ field_id : FieldId ,
184
+ is_ascending : bool ,
185
+ candidates : RoaringBitmap ,
186
+ ) -> Result < Box < dyn Iterator < Item = heed:: Result < RoaringBitmap > > + ' t > > {
187
+ let number_iter = iterative_facet_number_ordered_iter (
188
+ index,
189
+ rtxn,
190
+ field_id,
191
+ is_ascending,
192
+ candidates. clone ( ) ,
193
+ ) ?;
194
+ let string_iter =
195
+ iterative_facet_string_ordered_iter ( index, rtxn, field_id, is_ascending, candidates) ?;
196
+ Ok ( Box :: new ( number_iter. chain ( string_iter) . map ( Ok ) ) as Box < dyn Iterator < Item = _ > > )
197
+ }
198
+
199
+ fn facet_ordered_set_based < ' t > (
200
+ index : & ' t Index ,
201
+ rtxn : & ' t heed:: RoTxn ,
202
+ field_id : FieldId ,
203
+ is_ascending : bool ,
204
+ candidates : RoaringBitmap ,
205
+ ) -> Result < Box < dyn Iterator < Item = heed:: Result < RoaringBitmap > > + ' t > > {
206
+ let make_iter = if is_ascending { ascending_facet_sort } else { descending_facet_sort } ;
207
+
208
+ let number_iter = make_iter (
209
+ rtxn,
210
+ index. facet_id_f64_docids . remap_key_type :: < FacetGroupKeyCodec < ByteSliceRefCodec > > ( ) ,
211
+ field_id,
212
+ candidates. clone ( ) ,
213
+ ) ?;
214
+
215
+ let string_iter = make_iter (
216
+ rtxn,
217
+ index. facet_id_string_docids . remap_key_type :: < FacetGroupKeyCodec < ByteSliceRefCodec > > ( ) ,
218
+ field_id,
219
+ candidates,
220
+ ) ?;
221
+
222
+ Ok ( Box :: new ( number_iter. chain ( string_iter) ) )
223
+ }
224
+
173
225
/// Returns an iterator over groups of the given candidates in ascending or descending order.
174
226
///
175
227
/// It will either use an iterative or a recursive method on the whole facet database depending
@@ -180,36 +232,22 @@ fn facet_ordered<'t>(
180
232
field_id : FieldId ,
181
233
is_ascending : bool ,
182
234
candidates : RoaringBitmap ,
235
+ implementation_strategy : CriterionImplementationStrategy ,
183
236
) -> Result < Box < dyn Iterator < Item = heed:: Result < RoaringBitmap > > + ' t > > {
184
- if candidates. len ( ) <= CANDIDATES_THRESHOLD {
185
- let number_iter = iterative_facet_number_ordered_iter (
186
- index,
187
- rtxn,
188
- field_id,
189
- is_ascending,
190
- candidates. clone ( ) ,
191
- ) ?;
192
- let string_iter =
193
- iterative_facet_string_ordered_iter ( index, rtxn, field_id, is_ascending, candidates) ?;
194
- Ok ( Box :: new ( number_iter. chain ( string_iter) . map ( Ok ) ) as Box < dyn Iterator < Item = _ > > )
195
- } else {
196
- let make_iter = if is_ascending { ascending_facet_sort } else { descending_facet_sort } ;
197
-
198
- let number_iter = make_iter (
199
- rtxn,
200
- index. facet_id_f64_docids . remap_key_type :: < FacetGroupKeyCodec < ByteSliceRefCodec > > ( ) ,
201
- field_id,
202
- candidates. clone ( ) ,
203
- ) ?;
204
-
205
- let string_iter = make_iter (
206
- rtxn,
207
- index. facet_id_string_docids . remap_key_type :: < FacetGroupKeyCodec < ByteSliceRefCodec > > ( ) ,
208
- field_id,
209
- candidates,
210
- ) ?;
211
-
212
- Ok ( Box :: new ( number_iter. chain ( string_iter) ) )
237
+ match implementation_strategy {
238
+ CriterionImplementationStrategy :: OnlyIterative => {
239
+ facet_ordered_iterative ( index, rtxn, field_id, is_ascending, candidates)
240
+ }
241
+ CriterionImplementationStrategy :: OnlySetBased => {
242
+ facet_ordered_set_based ( index, rtxn, field_id, is_ascending, candidates)
243
+ }
244
+ CriterionImplementationStrategy :: Dynamic => {
245
+ if candidates. len ( ) <= CANDIDATES_THRESHOLD {
246
+ facet_ordered_iterative ( index, rtxn, field_id, is_ascending, candidates)
247
+ } else {
248
+ facet_ordered_set_based ( index, rtxn, field_id, is_ascending, candidates)
249
+ }
250
+ }
213
251
}
214
252
}
215
253
0 commit comments