@@ -96,19 +96,38 @@ static int copy_label_values(struct cmt_metric *metric, char **out)
9696 return i ;
9797}
9898
99- static inline int cat_histogram_values (struct cmt_metric * metric_dst , struct cmt_histogram * histogram ,
100- struct cmt_metric * metric_src )
99+ static inline int cat_histogram_values (struct cmt_metric * metric_dst , struct cmt_histogram * histogram_src ,
100+ struct cmt_metric * metric_src , struct cmt_histogram * histogram_dst )
101101{
102102 int i ;
103+ size_t bucket_count_src ;
104+ size_t bucket_count_dst ;
103105
106+ /* Validate source histogram buckets exist */
107+ if (!metric_src -> hist_buckets ) {
108+ /* Source has no bucket data, nothing to concatenate */
109+ return 0 ;
110+ }
111+
112+ bucket_count_src = histogram_src -> buckets -> count ;
113+ bucket_count_dst = histogram_dst -> buckets -> count ;
114+
115+ /* Validate that source and destination have matching bucket structures */
116+ if (bucket_count_src != bucket_count_dst ) {
117+ /* Histogram bucket structures don't match - cannot concatenate */
118+ return -1 ;
119+ }
120+
121+ /* Allocate destination buckets if needed */
104122 if (!metric_dst -> hist_buckets ) {
105- metric_dst -> hist_buckets = calloc (1 , sizeof (uint64_t ) * (histogram -> buckets -> count + 1 ));
123+ metric_dst -> hist_buckets = calloc (1 , sizeof (uint64_t ) * (bucket_count_dst + 1 ));
106124 if (!metric_dst -> hist_buckets ) {
107125 return -1 ;
108126 }
109127 }
110128
111- for (i = 0 ; i < histogram -> buckets -> count ; i ++ ) {
129+ /* Concatenate bucket values including +Inf bucket at index bucket_count_dst */
130+ for (i = 0 ; i <= bucket_count_dst ; i ++ ) {
112131 /* histogram buckets are always integers, no need to convert them */
113132 metric_dst -> hist_buckets [i ] += metric_src -> hist_buckets [i ];
114133 }
@@ -165,7 +184,8 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
165184 struct cmt_metric * metric_dst ;
166185 struct cmt_metric * metric_src ;
167186 struct cmt_summary * summary ;
168- struct cmt_histogram * histogram ;
187+ struct cmt_histogram * histogram_src ;
188+ struct cmt_histogram * histogram_dst ;
169189
170190 /* Handle static metric (no labels case) */
171191 if (src -> metric_static_set ) {
@@ -176,8 +196,9 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
176196 metric_src = & src -> metric ;
177197
178198 if (src -> type == CMT_HISTOGRAM ) {
179- histogram = (struct cmt_histogram * ) src -> parent ;
180- ret = cat_histogram_values (metric_dst , histogram , metric_src );
199+ histogram_src = (struct cmt_histogram * ) src -> parent ;
200+ histogram_dst = (struct cmt_histogram * ) dst -> parent ;
201+ ret = cat_histogram_values (metric_dst , histogram_src , metric_src , histogram_dst );
181202 if (ret == -1 ) {
182203 return -1 ;
183204 }
@@ -214,8 +235,9 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
214235 }
215236
216237 if (src -> type == CMT_HISTOGRAM ) {
217- histogram = (struct cmt_histogram * ) src -> parent ;
218- ret = cat_histogram_values (metric_dst , histogram , metric_src );
238+ histogram_src = (struct cmt_histogram * ) src -> parent ;
239+ histogram_dst = (struct cmt_histogram * ) dst -> parent ;
240+ ret = cat_histogram_values (metric_dst , histogram_src , metric_src , histogram_dst );
219241 if (ret == -1 ) {
220242 return -1 ;
221243 }
0 commit comments