11use std:: collections:: BTreeMap ;
2+ use std:: fmt:: Display ;
23use std:: fs:: File ;
34use std:: io:: { stdin, BufRead , BufReader , Cursor , Read , Write } ;
45use std:: path:: PathBuf ;
@@ -349,6 +350,29 @@ fn documents_from_csv(reader: impl Read) -> Result<Vec<u8>> {
349350 documents. into_inner ( ) . map_err ( Into :: into)
350351}
351352
353+ #[ derive( Debug , Clone , Copy ) ]
354+ struct SearchStrategyOption ( CriterionImplementationStrategy ) ;
355+ impl FromStr for SearchStrategyOption {
356+ type Err = String ;
357+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
358+ match s. to_lowercase ( ) . as_str ( ) {
359+ "dynamic" => Ok ( SearchStrategyOption ( CriterionImplementationStrategy :: Dynamic ) ) ,
360+ "set" => Ok ( SearchStrategyOption ( CriterionImplementationStrategy :: OnlySetBased ) ) ,
361+ "iterative" => Ok ( SearchStrategyOption ( CriterionImplementationStrategy :: OnlyIterative ) ) ,
362+ _ => Err ( "could not parse {s} as a criterion implementation strategy, available options are `dynamic`, `set`, and `iterative`" . to_owned ( ) ) ,
363+ }
364+ }
365+ }
366+ impl Display for SearchStrategyOption {
367+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
368+ match self . 0 {
369+ CriterionImplementationStrategy :: OnlyIterative => Display :: fmt ( "iterative" , f) ,
370+ CriterionImplementationStrategy :: OnlySetBased => Display :: fmt ( "set" , f) ,
371+ CriterionImplementationStrategy :: Dynamic => Display :: fmt ( "dynamic" , f) ,
372+ }
373+ }
374+ }
375+
352376#[ derive( Debug , StructOpt ) ]
353377struct Search {
354378 query : Option < String > ,
@@ -360,6 +384,8 @@ struct Search {
360384 limit : Option < usize > ,
361385 #[ structopt( short, long, conflicts_with = "query" ) ]
362386 interactive : bool ,
387+ #[ structopt( short, long) ]
388+ strategy : Option < SearchStrategyOption > ,
363389}
364390
365391impl Performer for Search {
@@ -379,13 +405,15 @@ impl Performer for Search {
379405 & self . filter ,
380406 & self . offset ,
381407 & self . limit ,
408+ & self . strategy ,
382409 ) ?;
383410
384411 let time = now. elapsed ( ) ;
385412
386413 let hits = serde_json:: to_string_pretty ( & jsons) ?;
387414
388415 println ! ( "{}" , hits) ;
416+
389417 eprintln ! ( "found {} results in {:.02?}" , jsons. len( ) , time) ;
390418 }
391419 _ => break ,
@@ -399,6 +427,7 @@ impl Performer for Search {
399427 & self . filter ,
400428 & self . offset ,
401429 & self . limit ,
430+ & self . strategy ,
402431 ) ?;
403432
404433 let time = now. elapsed ( ) ;
@@ -420,6 +449,7 @@ impl Search {
420449 filter : & Option < String > ,
421450 offset : & Option < usize > ,
422451 limit : & Option < usize > ,
452+ strategy : & Option < SearchStrategyOption > ,
423453 ) -> Result < Vec < Object > > {
424454 let txn = index. read_txn ( ) ?;
425455 let mut search = index. search ( & txn) ;
@@ -441,7 +471,10 @@ impl Search {
441471 if let Some ( limit) = limit {
442472 search. limit ( * limit) ;
443473 }
444- search. criterion_implementation_strategy ( CriterionImplementationStrategy :: OnlyIterative ) ;
474+ if let Some ( strategy) = strategy {
475+ search. criterion_implementation_strategy ( strategy. 0 ) ;
476+ }
477+
445478 let result = search. execute ( ) ?;
446479
447480 let fields_ids_map = index. fields_ids_map ( & txn) ?;
0 commit comments