@@ -12,6 +12,7 @@ use crate::heed_codec::ByteSliceRefCodec;
1212use  crate :: search:: criteria:: { resolve_query_tree,  CriteriaBuilder ,  InitialCandidates } ; 
1313use  crate :: search:: facet:: { ascending_facet_sort,  descending_facet_sort} ; 
1414use  crate :: search:: query_tree:: Operation ; 
15+ use  crate :: search:: CriterionImplementationStrategy ; 
1516use  crate :: { FieldId ,  Index ,  Result } ; 
1617
1718/// Threshold on the number of candidates that will make 
@@ -29,6 +30,7 @@ pub struct AscDesc<'t> {
2930    allowed_candidates :  RoaringBitmap , 
3031    initial_candidates :  InitialCandidates , 
3132    faceted_candidates :  RoaringBitmap , 
33+     implementation_strategy :  CriterionImplementationStrategy , 
3234    parent :  Box < dyn  Criterion  + ' t > , 
3335} 
3436
@@ -38,17 +40,19 @@ impl<'t> AscDesc<'t> {
3840        rtxn :  & ' t  heed:: RoTxn , 
3941        parent :  Box < dyn  Criterion  + ' t > , 
4042        field_name :  String , 
43+         implementation_strategy :  CriterionImplementationStrategy , 
4144    )  -> Result < Self >  { 
42-         Self :: new ( index,  rtxn,  parent,  field_name,  true ) 
45+         Self :: new ( index,  rtxn,  parent,  field_name,  true ,  implementation_strategy ) 
4346    } 
4447
4548    pub  fn  desc ( 
4649        index :  & ' t  Index , 
4750        rtxn :  & ' t  heed:: RoTxn , 
4851        parent :  Box < dyn  Criterion  + ' t > , 
4952        field_name :  String , 
53+         implementation_strategy :  CriterionImplementationStrategy , 
5054    )  -> Result < Self >  { 
51-         Self :: new ( index,  rtxn,  parent,  field_name,  false ) 
55+         Self :: new ( index,  rtxn,  parent,  field_name,  false ,  implementation_strategy ) 
5256    } 
5357
5458    fn  new ( 
@@ -57,6 +61,7 @@ impl<'t> AscDesc<'t> {
5761        parent :  Box < dyn  Criterion  + ' t > , 
5862        field_name :  String , 
5963        is_ascending :  bool , 
64+         implementation_strategy :  CriterionImplementationStrategy , 
6065    )  -> Result < Self >  { 
6166        let  fields_ids_map = index. fields_ids_map ( rtxn) ?; 
6267        let  field_id = fields_ids_map. id ( & field_name) ; 
@@ -82,6 +87,7 @@ impl<'t> AscDesc<'t> {
8287            allowed_candidates :  RoaringBitmap :: new ( ) , 
8388            faceted_candidates, 
8489            initial_candidates :  InitialCandidates :: Estimated ( RoaringBitmap :: new ( ) ) , 
90+             implementation_strategy, 
8591            parent, 
8692        } ) 
8793    } 
@@ -149,6 +155,7 @@ impl<'t> Criterion for AscDesc<'t> {
149155                                field_id, 
150156                                self . is_ascending , 
151157                                candidates &  & self . faceted_candidates , 
158+                                 self . implementation_strategy , 
152159                            ) ?, 
153160                            None  => Box :: new ( std:: iter:: empty ( ) ) , 
154161                        } ; 
@@ -170,6 +177,51 @@ impl<'t> Criterion for AscDesc<'t> {
170177    } 
171178} 
172179
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+ 
173225/// Returns an iterator over groups of the given candidates in ascending or descending order. 
174226/// 
175227/// It will either use an iterative or a recursive method on the whole facet database depending 
@@ -180,36 +232,22 @@ fn facet_ordered<'t>(
180232    field_id :  FieldId , 
181233    is_ascending :  bool , 
182234    candidates :  RoaringBitmap , 
235+     implementation_strategy :  CriterionImplementationStrategy , 
183236)  -> 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+         } 
213251    } 
214252} 
215253
0 commit comments