@@ -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,36 @@ 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 ! ( parents_backref_queue. len( ) <= 16 ) ;
603
+ let parent: i32 = item. parent_idx . map ( |x| x + 1 ) . unwrap_or ( 0 ) . try_into ( ) . unwrap ( ) ;
604
+ if let Some ( idx) = parents_backref_queue. iter ( ) . position ( |p : & i32 | * p == parent) {
605
+ parents. push (
606
+ char:: try_from ( '0' as u32 + u32:: try_from ( idx) . unwrap ( ) )
607
+ . expect ( "last possible value is '?'" ) ,
608
+ ) ;
609
+ } else if parent == 0 {
610
+ write_vlqhex_to_string ( parent, & mut parents) ;
611
+ } else {
612
+ parents_backref_queue. push_front ( parent) ;
613
+ write_vlqhex_to_string ( parent, & mut parents) ;
614
+ if parents_backref_queue. len ( ) > 16 {
615
+ parents_backref_queue. pop_back ( ) ;
616
+ }
617
+ }
602
618
603
- names. push ( item. name . as_str ( ) ) ;
619
+ if Some ( item. name . as_str ( ) ) == last_name {
620
+ names. push ( "" ) ;
621
+ } else {
622
+ names. push ( item. name . as_str ( ) ) ;
623
+ last_name = Some ( item. name . as_str ( ) ) ;
624
+ }
604
625
605
626
if !item. path . is_empty ( ) {
606
627
full_paths. push ( ( index, & item. path ) ) ;
607
628
}
608
629
609
630
match & item. search_type {
610
- Some ( ty) => ty. write_to_string ( & mut functions, & mut backref_queue ) ,
631
+ Some ( ty) => ty. write_to_string ( & mut functions, & mut type_backref_queue ) ,
611
632
None => functions. push ( '`' ) ,
612
633
}
613
634
0 commit comments