@@ -371,25 +371,50 @@ impl Profile {
371
371
. as_nanos ( )
372
372
. min ( i64:: MAX as u128 ) as i64 ;
373
373
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
+
374
391
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 ( ) ] ;
376
393
let location_ids: Vec < _ > = self
377
394
. get_stacktrace ( sample. stacktrace ) ?
378
395
. locations
379
396
. iter ( )
380
397
. map ( Id :: to_raw_id)
381
398
. collect ( ) ;
382
399
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
+ }
384
410
385
- let labels: Vec < _ > = labels. into_iter ( ) . map ( protobuf:: Label :: from) . collect ( ) ;
386
411
let item = protobuf:: Sample {
387
412
location_ids : Record :: from ( location_ids. as_slice ( ) ) ,
388
413
values : Record :: from ( values. as_slice ( ) ) ,
389
414
// SAFETY: converting &[Label] to &[Field<Label,..>] which is
390
415
// safe, because Field is repr(transparent).
391
416
labels : unsafe {
392
- & * ( labels . as_slice ( ) as * const [ protobuf:: Label ]
417
+ & * ( pprof_labels . as_slice ( ) as * const [ protobuf:: Label ]
393
418
as * const [ Record < protobuf:: Label , 3 , NO_OPT_ZERO > ] )
394
419
} ,
395
420
} ;
@@ -679,16 +704,15 @@ impl Profile {
679
704
. map ( |v| Label :: str ( self . endpoints . endpoint_label , * v) ) )
680
705
}
681
706
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| {
684
709
if let Ok ( label) = self . get_label ( * id) {
685
710
if label. get_key ( ) == self . endpoints . local_root_span_id_label {
686
711
return Some ( label) ;
687
712
}
688
713
}
689
714
None
690
- } ) ;
691
- if let Some ( label) = label {
715
+ } ) {
692
716
self . get_endpoint_for_label ( label)
693
717
} else {
694
718
Ok ( None )
@@ -701,6 +725,7 @@ impl Profile {
701
725
. context ( "LabelId to have a valid interned index" )
702
726
}
703
727
728
+ #[ allow( dead_code) ]
704
729
fn get_label_set ( & self , id : LabelSetId ) -> anyhow:: Result < & LabelSet > {
705
730
self . label_sets
706
731
. get_index ( id. to_offset ( ) )
@@ -800,19 +825,6 @@ impl Profile {
800
825
profile
801
826
}
802
827
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
-
816
828
#[ cfg( debug_assertions) ]
817
829
fn validate_sample_labels ( & mut self , sample : & api:: Sample ) -> anyhow:: Result < ( ) > {
818
830
let mut seen: HashMap < & str , & api:: Label > = HashMap :: new ( ) ;
0 commit comments