@@ -579,12 +579,14 @@ pub(crate) fn build_index<'tcx>(
579
579
let mut names = Vec :: with_capacity ( self . items . len ( ) ) ;
580
580
let mut types = String :: with_capacity ( self . items . len ( ) ) ;
581
581
let mut full_paths = Vec :: with_capacity ( self . items . len ( ) ) ;
582
- let mut parents = Vec :: with_capacity ( self . items . len ( ) ) ;
582
+ let mut parents = String :: with_capacity ( self . items . len ( ) ) ;
583
+ let mut parents_backref_queue = VecDeque :: new ( ) ;
583
584
let mut functions = String :: with_capacity ( self . items . len ( ) ) ;
584
585
let mut deprecated = Vec :: with_capacity ( self . items . len ( ) ) ;
585
586
586
- let mut backref_queue = VecDeque :: new ( ) ;
587
+ let mut type_backref_queue = VecDeque :: new ( ) ;
587
588
589
+ let mut last_name = None ;
588
590
for ( index, item) in self . items . iter ( ) . enumerate ( ) {
589
591
let n = item. ty as u8 ;
590
592
let c = char:: try_from ( n + b'A' ) . expect ( "item types must fit in ASCII" ) ;
@@ -597,17 +599,39 @@ pub(crate) fn build_index<'tcx>(
597
599
"`{}` is missing idx" ,
598
600
item. name
599
601
) ;
600
- // 0 is a sentinel, everything else is one-indexed
601
- parents. push ( item. parent_idx . map ( |x| x + 1 ) . unwrap_or ( 0 ) ) ;
602
+ assert ! (
603
+ parents_backref_queue. len( ) <= 16 ,
604
+ "the string encoding only supports 16 slots of lookback"
605
+ ) ;
606
+ let parent: i32 = item. parent_idx . map ( |x| x + 1 ) . unwrap_or ( 0 ) . try_into ( ) . unwrap ( ) ;
607
+ if let Some ( idx) = parents_backref_queue. iter ( ) . position ( |p : & i32 | * p == parent) {
608
+ parents. push (
609
+ char:: try_from ( '0' as u32 + u32:: try_from ( idx) . unwrap ( ) )
610
+ . expect ( "last possible value is '?'" ) ,
611
+ ) ;
612
+ } else if parent == 0 {
613
+ write_vlqhex_to_string ( parent, & mut parents) ;
614
+ } else {
615
+ parents_backref_queue. push_front ( parent) ;
616
+ write_vlqhex_to_string ( parent, & mut parents) ;
617
+ if parents_backref_queue. len ( ) > 16 {
618
+ parents_backref_queue. pop_back ( ) ;
619
+ }
620
+ }
602
621
603
- names. push ( item. name . as_str ( ) ) ;
622
+ if Some ( item. name . as_str ( ) ) == last_name {
623
+ names. push ( "" ) ;
624
+ } else {
625
+ names. push ( item. name . as_str ( ) ) ;
626
+ last_name = Some ( item. name . as_str ( ) ) ;
627
+ }
604
628
605
629
if !item. path . is_empty ( ) {
606
630
full_paths. push ( ( index, & item. path ) ) ;
607
631
}
608
632
609
633
match & item. search_type {
610
- Some ( ty) => ty. write_to_string ( & mut functions, & mut backref_queue ) ,
634
+ Some ( ty) => ty. write_to_string ( & mut functions, & mut type_backref_queue ) ,
611
635
None => functions. push ( '`' ) ,
612
636
}
613
637
0 commit comments