@@ -371,25 +371,50 @@ impl Profile {
371371 . as_nanos ( )
372372 . min ( i64:: MAX as u128 ) as i64 ;
373373
374+ let mut extended_label_sets: Vec < Vec < Label > > = Vec :: with_capacity ( self . label_sets . len ( ) ) ;
375+
376+ for label_set in std:: mem:: take ( & mut self . label_sets ) {
377+ let endpoint_label = self . get_endpoint_for_label_set ( & label_set) ?;
378+ // Leave one space for the timestamp if needed
379+ let mut labels = Vec :: with_capacity (
380+ label_set. len ( ) + 1 + if endpoint_label. is_some ( ) { 1 } else { 0 } ,
381+ ) ;
382+ for l in label_set. iter ( ) {
383+ labels. push ( * self . get_label ( * l) ?) ;
384+ }
385+ if let Some ( endpoint_label) = endpoint_label {
386+ labels. push ( endpoint_label) ;
387+ }
388+ extended_label_sets. push ( labels) ;
389+ }
390+
374391 for ( sample, timestamp, mut values) in std:: mem:: take ( & mut self . observations ) . into_iter ( ) {
375- let labels = self . enrich_sample_labels ( sample , timestamp ) ? ;
392+ let labels = & mut extended_label_sets [ sample . labels . to_raw_id ( ) ] ;
376393 let location_ids: Vec < _ > = self
377394 . get_stacktrace ( sample. stacktrace ) ?
378395 . locations
379396 . iter ( )
380397 . map ( Id :: to_raw_id)
381398 . collect ( ) ;
382399 self . check_location_ids_are_valid ( & location_ids, self . locations . len ( ) ) ?;
383- self . upscaling_rules . upscale_values ( & mut values, & labels) ?;
400+ self . upscaling_rules . upscale_values ( & mut values, labels) ?;
401+
402+ // Use the extra slot in the labels vector to store the timestamp without any reallocs.
403+ if let Some ( ts) = timestamp {
404+ labels. push ( Label :: num ( self . timestamp_key , ts. get ( ) , StringId :: ZERO ) )
405+ }
406+ let pprof_labels: Vec < _ > = labels. iter ( ) . map ( protobuf:: Label :: from) . collect ( ) ;
407+ if timestamp. is_some ( ) {
408+ labels. pop ( ) ;
409+ }
384410
385- let labels: Vec < _ > = labels. into_iter ( ) . map ( protobuf:: Label :: from) . collect ( ) ;
386411 let item = protobuf:: Sample {
387412 location_ids : Record :: from ( location_ids. as_slice ( ) ) ,
388413 values : Record :: from ( values. as_slice ( ) ) ,
389414 // SAFETY: converting &[Label] to &[Field<Label,..>] which is
390415 // safe, because Field is repr(transparent).
391416 labels : unsafe {
392- & * ( labels . as_slice ( ) as * const [ protobuf:: Label ]
417+ & * ( pprof_labels . as_slice ( ) as * const [ protobuf:: Label ]
393418 as * const [ Record < protobuf:: Label , 3 , NO_OPT_ZERO > ] )
394419 } ,
395420 } ;
@@ -679,16 +704,15 @@ impl Profile {
679704 . map ( |v| Label :: str ( self . endpoints . endpoint_label , * v) ) )
680705 }
681706
682- fn get_endpoint_for_labels ( & self , label_set_id : LabelSetId ) -> anyhow:: Result < Option < Label > > {
683- let label = self . get_label_set ( label_set_id ) ? . iter ( ) . find_map ( |id| {
707+ fn get_endpoint_for_label_set ( & self , label_set : & LabelSet ) -> anyhow:: Result < Option < Label > > {
708+ if let Some ( label) = label_set . iter ( ) . find_map ( |id| {
684709 if let Ok ( label) = self . get_label ( * id) {
685710 if label. get_key ( ) == self . endpoints . local_root_span_id_label {
686711 return Some ( label) ;
687712 }
688713 }
689714 None
690- } ) ;
691- if let Some ( label) = label {
715+ } ) {
692716 self . get_endpoint_for_label ( label)
693717 } else {
694718 Ok ( None )
@@ -701,6 +725,7 @@ impl Profile {
701725 . context ( "LabelId to have a valid interned index" )
702726 }
703727
728+ #[ allow( dead_code) ]
704729 fn get_label_set ( & self , id : LabelSetId ) -> anyhow:: Result < & LabelSet > {
705730 self . label_sets
706731 . get_index ( id. to_offset ( ) )
@@ -800,19 +825,6 @@ impl Profile {
800825 profile
801826 }
802827
803- fn enrich_sample_labels (
804- & self ,
805- sample : Sample ,
806- timestamp : Option < Timestamp > ,
807- ) -> anyhow:: Result < Vec < Label > > {
808- self . get_label_set ( sample. labels ) ?
809- . iter ( )
810- . map ( |l| self . get_label ( * l) . copied ( ) )
811- . chain ( self . get_endpoint_for_labels ( sample. labels ) . transpose ( ) )
812- . chain ( timestamp. map ( |ts| Ok ( Label :: num ( self . timestamp_key , ts. get ( ) , StringId :: ZERO ) ) ) )
813- . collect ( )
814- }
815-
816828 #[ cfg( debug_assertions) ]
817829 fn validate_sample_labels ( & mut self , sample : & api:: Sample ) -> anyhow:: Result < ( ) > {
818830 let mut seen: HashMap < & str , & api:: Label > = HashMap :: new ( ) ;
0 commit comments