@@ -15,20 +15,37 @@ use std::hash::BuildHasherDefault;
1515/// `reset_and_return_previous()`.
1616type FxBuildHasher = BuildHasherDefault < rustc_hash:: FxHasher > ;
1717
18- pub ( crate ) struct HeapLiveState {
19- pub tracked : HashMap < u64 , TrackedAlloc , FxBuildHasher > ,
20- pub max_tracked : usize ,
21- pub excluded_labels : Vec < Box < str > > ,
18+ /// Indices into the sample values array for reading/writing heap-live fields.
19+ struct ValueIndices {
2220 /// Index of alloc-size in the sample values array (to read allocation size).
23- alloc_size_idx : usize ,
21+ alloc_size : usize ,
2422 /// Index of heap-live-samples in the sample values array (to write 1).
25- heap_live_samples_idx : usize ,
23+ heap_live_samples : usize ,
2624 /// Index of heap-live-size in the sample values array (to write the size).
27- heap_live_size_idx : usize ,
25+ heap_live_size : usize ,
2826 /// Total number of values per sample.
2927 num_values : usize ,
3028}
3129
30+ impl ValueIndices {
31+ /// Build a heap-live values vector: all zeros except heap-live-samples=1
32+ /// and heap-live-size=alloc_size (read from the original sample).
33+ fn build_values ( & self , sample_values : & [ i64 ] ) -> Vec < i64 > {
34+ let alloc_size = sample_values. get ( self . alloc_size ) . copied ( ) . unwrap_or ( 0 ) ;
35+ let mut values = vec ! [ 0i64 ; self . num_values] ;
36+ values[ self . heap_live_samples ] = 1 ;
37+ values[ self . heap_live_size ] = alloc_size;
38+ values
39+ }
40+ }
41+
42+ pub ( crate ) struct HeapLiveState {
43+ pub tracked : HashMap < u64 , TrackedAlloc , FxBuildHasher > ,
44+ pub max_tracked : usize ,
45+ pub excluded_labels : Vec < Box < str > > ,
46+ indices : ValueIndices ,
47+ }
48+
3249/// A single tracked live allocation with owned frame/label/values data.
3350pub ( crate ) struct TrackedAlloc {
3451 pub frames : Vec < OwnedFrame > ,
@@ -49,10 +66,12 @@ impl HeapLiveState {
4966 tracked : HashMap :: with_capacity_and_hasher ( max_tracked, FxBuildHasher :: default ( ) ) ,
5067 max_tracked,
5168 excluded_labels : excluded_labels. iter ( ) . map ( |s| Box :: from ( * s) ) . collect ( ) ,
52- alloc_size_idx,
53- heap_live_samples_idx,
54- heap_live_size_idx,
55- num_values,
69+ indices : ValueIndices {
70+ alloc_size : alloc_size_idx,
71+ heap_live_samples : heap_live_samples_idx,
72+ heap_live_size : heap_live_size_idx,
73+ num_values,
74+ } ,
5675 }
5776 }
5877
@@ -64,14 +83,7 @@ impl HeapLiveState {
6483 if self . tracked . len ( ) >= self . max_tracked {
6584 return false ;
6685 }
67- let alloc = TrackedAlloc :: from_api_sample (
68- sample,
69- & self . excluded_labels ,
70- self . alloc_size_idx ,
71- self . heap_live_samples_idx ,
72- self . heap_live_size_idx ,
73- self . num_values ,
74- ) ;
86+ let alloc = TrackedAlloc :: from_api_sample ( sample, & self . excluded_labels , & self . indices ) ;
7587 self . tracked . insert ( ptr, alloc) ;
7688 true
7789 }
@@ -92,10 +104,7 @@ impl HeapLiveState {
92104 sample,
93105 storage,
94106 & self . excluded_labels ,
95- self . alloc_size_idx ,
96- self . heap_live_samples_idx ,
97- self . heap_live_size_idx ,
98- self . num_values ,
107+ & self . indices ,
99108 ) ?;
100109 self . tracked . insert ( ptr, alloc) ;
101110 Ok ( true )
@@ -107,14 +116,15 @@ impl HeapLiveState {
107116 }
108117}
109118
119+ fn is_excluded ( excluded_labels : & [ Box < str > ] , key : & str ) -> bool {
120+ excluded_labels. iter ( ) . any ( |ex| ex. as_ref ( ) == key)
121+ }
122+
110123impl TrackedAlloc {
111124 fn from_api_sample (
112125 sample : & api:: Sample ,
113126 excluded_labels : & [ Box < str > ] ,
114- alloc_size_idx : usize ,
115- heap_live_samples_idx : usize ,
116- heap_live_size_idx : usize ,
117- num_values : usize ,
127+ indices : & ValueIndices ,
118128 ) -> Self {
119129 let frames = sample
120130 . locations
@@ -129,7 +139,7 @@ impl TrackedAlloc {
129139 let labels = sample
130140 . labels
131141 . iter ( )
132- . filter ( |l| !excluded_labels . iter ( ) . any ( |ex| ex . as_ref ( ) == l. key ) )
142+ . filter ( |l| !is_excluded ( excluded_labels , l. key ) )
133143 . map ( |l| OwnedLabel {
134144 key : l. key . into ( ) ,
135145 str_value : l. str . into ( ) ,
@@ -138,29 +148,18 @@ impl TrackedAlloc {
138148 } )
139149 . collect ( ) ;
140150
141- // Construct heap-live-only values: all zeros except the heap-live
142- // fields. The allocation size is read from the original sample's
143- // alloc-size slot.
144- let alloc_size = sample. values . get ( alloc_size_idx) . copied ( ) . unwrap_or ( 0 ) ;
145- let mut values = vec ! [ 0i64 ; num_values] ;
146- values[ heap_live_samples_idx] = 1 ;
147- values[ heap_live_size_idx] = alloc_size;
148-
149151 TrackedAlloc {
150152 frames,
151153 labels,
152- values,
154+ values : indices . build_values ( sample . values ) ,
153155 }
154156 }
155157
156158 fn from_string_id_sample (
157159 sample : & api:: StringIdSample ,
158160 storage : & ManagedStringStorage ,
159161 excluded_labels : & [ Box < str > ] ,
160- alloc_size_idx : usize ,
161- heap_live_samples_idx : usize ,
162- heap_live_size_idx : usize ,
163- num_values : usize ,
162+ indices : & ValueIndices ,
164163 ) -> anyhow:: Result < Self > {
165164 let frames = sample
166165 . locations
@@ -174,37 +173,24 @@ impl TrackedAlloc {
174173 } )
175174 . collect :: < Result < Vec < _ > , _ > > ( ) ?;
176175
177- let labels = sample
178- . labels
179- . iter ( )
180- . map ( |l| -> anyhow:: Result < OwnedLabel > {
181- Ok ( OwnedLabel {
182- key : resolve_managed_string ( storage, l. key ) ?,
183- str_value : resolve_managed_string ( storage, l. str ) ?,
184- num : l. num ,
185- num_unit : resolve_managed_string ( storage, l. num_unit ) ?,
186- } )
187- } )
188- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
189-
190- let labels = labels
191- . into_iter ( )
192- . filter ( |l| {
193- !excluded_labels
194- . iter ( )
195- . any ( |ex| ex. as_ref ( ) == l. key . as_ref ( ) )
196- } )
197- . collect ( ) ;
198-
199- let alloc_size = sample. values . get ( alloc_size_idx) . copied ( ) . unwrap_or ( 0 ) ;
200- let mut values = vec ! [ 0i64 ; num_values] ;
201- values[ heap_live_samples_idx] = 1 ;
202- values[ heap_live_size_idx] = alloc_size;
176+ let mut labels = Vec :: with_capacity ( sample. labels . len ( ) ) ;
177+ for l in & sample. labels {
178+ let key = resolve_managed_string ( storage, l. key ) ?;
179+ if is_excluded ( excluded_labels, & key) {
180+ continue ;
181+ }
182+ labels. push ( OwnedLabel {
183+ key,
184+ str_value : resolve_managed_string ( storage, l. str ) ?,
185+ num : l. num ,
186+ num_unit : resolve_managed_string ( storage, l. num_unit ) ?,
187+ } ) ;
188+ }
203189
204190 Ok ( TrackedAlloc {
205191 frames,
206192 labels,
207- values,
193+ values : indices . build_values ( sample . values ) ,
208194 } )
209195 }
210196}
0 commit comments