@@ -20,10 +20,10 @@ use tracing::debug;
2020
2121use super :: super :: RetrievalContext ;
2222use super :: super :: types:: { NavigationDecision , NavigationStep , SearchPath } ;
23- use crate :: retrieval:: pilot:: { PilotDecisionCache , score_candidates, score_candidates_detailed} ;
2423use super :: { SearchConfig , SearchResult , SearchTree } ;
2524use crate :: document:: { DocumentTree , NodeId } ;
2625use crate :: retrieval:: pilot:: { Pilot , SearchState } ;
26+ use crate :: retrieval:: pilot:: { PilotDecisionCache , score_candidates, score_candidates_detailed} ;
2727
2828/// Maximum entries in the fallback stack relative to beam width.
2929const FALLBACK_STACK_MULTIPLIER : usize = 3 ;
@@ -91,7 +91,11 @@ impl BeamSearch {
9191 if let Some ( min_idx) = fallback_stack
9292 . iter ( )
9393 . enumerate ( )
94- . min_by ( |( _, a) , ( _, b) | a. score . partial_cmp ( & b. score ) . unwrap_or ( std:: cmp:: Ordering :: Equal ) )
94+ . min_by ( |( _, a) , ( _, b) | {
95+ a. score
96+ . partial_cmp ( & b. score )
97+ . unwrap_or ( std:: cmp:: Ordering :: Equal )
98+ } )
9599 . map ( |( i, _) | i)
96100 {
97101 if entry. score > fallback_stack[ min_idx] . score {
@@ -114,7 +118,11 @@ impl BeamSearch {
114118 let max_idx = fallback_stack
115119 . iter ( )
116120 . enumerate ( )
117- . max_by ( |( _, a) , ( _, b) | a. score . partial_cmp ( & b. score ) . unwrap_or ( std:: cmp:: Ordering :: Equal ) )
121+ . max_by ( |( _, a) , ( _, b) | {
122+ a. score
123+ . partial_cmp ( & b. score )
124+ . unwrap_or ( std:: cmp:: Ordering :: Equal )
125+ } )
118126 . map ( |( i, _) | i) ?;
119127 Some ( fallback_stack. swap_remove ( max_idx) )
120128 }
@@ -287,11 +295,8 @@ impl BeamSearch {
287295 . unwrap_or ( std:: cmp:: Ordering :: Equal )
288296 } ) ;
289297
290- let mut current_beam: Vec < SearchPath > = sorted_initial
291- . iter ( )
292- . take ( beam_width)
293- . cloned ( )
294- . collect ( ) ;
298+ let mut current_beam: Vec < SearchPath > =
299+ sorted_initial. iter ( ) . take ( beam_width) . cloned ( ) . collect ( ) ;
295300
296301 // Remaining candidates go to fallback stack
297302 for path in sorted_initial. iter ( ) . skip ( beam_width) {
@@ -421,16 +426,14 @@ impl BeamSearch {
421426
422427 // Keep top beam_width in the beam, shelve the rest
423428 let mut beam_candidates = next_beam;
424- let overflow: Vec < SearchPath > = beam_candidates. split_off ( beam_width. min ( beam_candidates. len ( ) ) ) ;
429+ let overflow: Vec < SearchPath > =
430+ beam_candidates. split_off ( beam_width. min ( beam_candidates. len ( ) ) ) ;
425431
426432 for path in overflow {
427433 let score = path. score ;
428434 Self :: push_fallback (
429435 & mut fallback_stack,
430- FallbackEntry {
431- path,
432- score,
433- } ,
436+ FallbackEntry { path, score } ,
434437 config. min_score ,
435438 config. fallback_score_ratio ,
436439 max_fallback_size,
@@ -566,18 +569,33 @@ mod tests {
566569
567570 BeamSearch :: push_fallback (
568571 & mut stack,
569- FallbackEntry { path : SearchPath :: from_node ( id0, 0.3 ) , score : 0.3 } ,
570- 0.1 , 0.5 , 100 ,
572+ FallbackEntry {
573+ path : SearchPath :: from_node ( id0, 0.3 ) ,
574+ score : 0.3 ,
575+ } ,
576+ 0.1 ,
577+ 0.5 ,
578+ 100 ,
571579 ) ;
572580 BeamSearch :: push_fallback (
573581 & mut stack,
574- FallbackEntry { path : SearchPath :: from_node ( id1, 0.7 ) , score : 0.7 } ,
575- 0.1 , 0.5 , 100 ,
582+ FallbackEntry {
583+ path : SearchPath :: from_node ( id1, 0.7 ) ,
584+ score : 0.7 ,
585+ } ,
586+ 0.1 ,
587+ 0.5 ,
588+ 100 ,
576589 ) ;
577590 BeamSearch :: push_fallback (
578591 & mut stack,
579- FallbackEntry { path : SearchPath :: from_node ( id2, 0.5 ) , score : 0.5 } ,
580- 0.1 , 0.5 , 100 ,
592+ FallbackEntry {
593+ path : SearchPath :: from_node ( id2, 0.5 ) ,
594+ score : 0.5 ,
595+ } ,
596+ 0.1 ,
597+ 0.5 ,
598+ 100 ,
581599 ) ;
582600
583601 assert_eq ! ( stack. len( ) , 3 ) ;
@@ -603,16 +621,26 @@ mod tests {
603621 // Score 0.01 with threshold 0.1 * 0.5 = 0.05 → should be rejected
604622 BeamSearch :: push_fallback (
605623 & mut stack,
606- FallbackEntry { path : SearchPath :: from_node ( id0, 0.01 ) , score : 0.01 } ,
607- 0.1 , 0.5 , 100 ,
624+ FallbackEntry {
625+ path : SearchPath :: from_node ( id0, 0.01 ) ,
626+ score : 0.01 ,
627+ } ,
628+ 0.1 ,
629+ 0.5 ,
630+ 100 ,
608631 ) ;
609632 assert_eq ! ( stack. len( ) , 0 , "Score below threshold should be rejected" ) ;
610633
611634 // Score 0.06 with threshold 0.05 → should be accepted
612635 BeamSearch :: push_fallback (
613636 & mut stack,
614- FallbackEntry { path : SearchPath :: from_node ( id1, 0.06 ) , score : 0.06 } ,
615- 0.1 , 0.5 , 100 ,
637+ FallbackEntry {
638+ path : SearchPath :: from_node ( id1, 0.06 ) ,
639+ score : 0.06 ,
640+ } ,
641+ 0.1 ,
642+ 0.5 ,
643+ 100 ,
616644 ) ;
617645 assert_eq ! ( stack. len( ) , 1 , "Score above threshold should be accepted" ) ;
618646 }
@@ -628,21 +656,36 @@ mod tests {
628656 // Fill to capacity (max_size=2)
629657 BeamSearch :: push_fallback (
630658 & mut stack,
631- FallbackEntry { path : SearchPath :: from_node ( id0, 0.3 ) , score : 0.3 } ,
632- 0.1 , 0.5 , 2 ,
659+ FallbackEntry {
660+ path : SearchPath :: from_node ( id0, 0.3 ) ,
661+ score : 0.3 ,
662+ } ,
663+ 0.1 ,
664+ 0.5 ,
665+ 2 ,
633666 ) ;
634667 BeamSearch :: push_fallback (
635668 & mut stack,
636- FallbackEntry { path : SearchPath :: from_node ( id1, 0.5 ) , score : 0.5 } ,
637- 0.1 , 0.5 , 2 ,
669+ FallbackEntry {
670+ path : SearchPath :: from_node ( id1, 0.5 ) ,
671+ score : 0.5 ,
672+ } ,
673+ 0.1 ,
674+ 0.5 ,
675+ 2 ,
638676 ) ;
639677 assert_eq ! ( stack. len( ) , 2 ) ;
640678
641679 // Push a higher-score entry → should evict the lowest (0.3)
642680 BeamSearch :: push_fallback (
643681 & mut stack,
644- FallbackEntry { path : SearchPath :: from_node ( id2, 0.8 ) , score : 0.8 } ,
645- 0.1 , 0.5 , 2 ,
682+ FallbackEntry {
683+ path : SearchPath :: from_node ( id2, 0.8 ) ,
684+ score : 0.8 ,
685+ } ,
686+ 0.1 ,
687+ 0.5 ,
688+ 2 ,
646689 ) ;
647690 assert_eq ! ( stack. len( ) , 2 ) ;
648691
0 commit comments