@@ -6,7 +6,7 @@ use std::{
66} ;
77
88use hashbrown:: HashMap ;
9- use rayon:: iter:: { IntoParallelRefIterator , ParallelIterator } ;
9+ use rayon:: iter:: { IntoParallelIterator , IntoParallelRefIterator , ParallelIterator } ;
1010use rustc_hash:: FxHashSet ;
1111
1212use crate :: {
@@ -417,10 +417,28 @@ impl<'a> SpanRef<'a> {
417417
418418 fn search_index ( & self ) -> & HashMap < String , Vec < SpanIndex > > {
419419 self . extra ( ) . search_index . get_or_init ( || {
420- let mut index: HashMap < String , Vec < SpanIndex > > = HashMap :: default ( ) ;
421- let mut queue = VecDeque :: with_capacity ( 8 ) ;
422- queue. push_back ( * self ) ;
423- while let Some ( span) = queue. pop_front ( ) {
420+ let mut all_spans = Vec :: new ( ) ;
421+ all_spans. push ( self . index ) ;
422+ let mut i = 0 ;
423+ while i < all_spans. len ( ) {
424+ let index = all_spans[ i] ;
425+ let span = SpanRef {
426+ span : & self . store . spans [ index] ,
427+ store : self . store ,
428+ index,
429+ } ;
430+ for child in span. children ( ) {
431+ all_spans. push ( child. index ) ;
432+ }
433+ i += 1 ;
434+ }
435+
436+ enum SpanOrMap < ' a > {
437+ Span ( SpanRef < ' a > ) ,
438+ Map ( HashMap < String , Vec < SpanIndex > > ) ,
439+ }
440+
441+ fn add_span_to_map < ' a > ( index : & mut HashMap < String , Vec < SpanIndex > > , span : SpanRef < ' a > ) {
424442 if !span. is_root ( ) {
425443 let ( cat, name) = span. nice_name ( ) ;
426444 if !cat. is_empty ( ) {
@@ -453,11 +471,47 @@ impl<'a> SpanRef<'a> {
453471 . or_insert_with ( || ( name. to_string ( ) , vec ! [ span. index( ) ] ) ) ;
454472 }
455473 }
456- for child in span. children ( ) {
457- queue. push_back ( child) ;
474+ }
475+
476+ let result = all_spans
477+ . into_par_iter ( )
478+ . map ( |index| {
479+ SpanOrMap :: Span ( SpanRef {
480+ span : & self . store . spans [ index] ,
481+ store : self . store ,
482+ index,
483+ } )
484+ } )
485+ . reduce (
486+ || SpanOrMap :: Map ( HashMap :: default ( ) ) ,
487+ |a, b| {
488+ let mut map = match a {
489+ SpanOrMap :: Span ( span) => {
490+ let mut map = HashMap :: default ( ) ;
491+ add_span_to_map ( & mut map, span) ;
492+ map
493+ }
494+ SpanOrMap :: Map ( map) => map,
495+ } ;
496+ match b {
497+ SpanOrMap :: Span ( span) => {
498+ add_span_to_map ( & mut map, span) ;
499+ }
500+ SpanOrMap :: Map ( other_map) => {
501+ map. extend ( other_map) ;
502+ }
503+ }
504+ SpanOrMap :: Map ( map)
505+ } ,
506+ ) ;
507+ match result {
508+ SpanOrMap :: Span ( span) => {
509+ let mut map = HashMap :: default ( ) ;
510+ add_span_to_map ( & mut map, span) ;
511+ map
458512 }
513+ SpanOrMap :: Map ( map) => map,
459514 }
460- index
461515 } )
462516 }
463517}
0 commit comments