@@ -96,9 +96,66 @@ static int copy_label_values(struct cmt_metric *metric, char **out)
9696 return i ;
9797}
9898
99- int cmt_cat_copy_map (struct cmt_opts * opts , struct cmt_map * dst , struct cmt_map * src )
99+ static inline int cat_histogram_values (struct cmt_metric * metric_dst , struct cmt_histogram * histogram ,
100+ struct cmt_metric * metric_src )
100101{
101102 int i ;
103+
104+ if (!metric_dst -> hist_buckets ) {
105+ metric_dst -> hist_buckets = calloc (1 , sizeof (uint64_t ) * (histogram -> buckets -> count + 1 ));
106+ if (!metric_dst -> hist_buckets ) {
107+ return -1 ;
108+ }
109+ }
110+
111+ for (i = 0 ; i < histogram -> buckets -> count ; i ++ ) {
112+ /* histogram buckets are always integers, no need to convert them */
113+ metric_dst -> hist_buckets [i ] += metric_src -> hist_buckets [i ];
114+ }
115+
116+ /* histogram count */
117+ metric_dst -> hist_count = cmt_math_sum_native_uint64_as_d64 (metric_dst -> hist_count ,
118+ metric_src -> hist_count );
119+
120+ /* histoggram sum */
121+ metric_dst -> hist_sum = cmt_math_sum_native_uint64_as_d64 (metric_dst -> hist_sum ,
122+ metric_src -> hist_sum );
123+
124+ return 0 ;
125+ }
126+
127+ /*
128+ * For summaries we don't support manual updates through the API, on concatenation we just
129+ * keep the last values reported.
130+ */
131+ static inline int cat_summary_values (struct cmt_metric * metric_dst , struct cmt_summary * summary ,
132+ struct cmt_metric * metric_src )
133+ {
134+ int i ;
135+
136+ if (!metric_dst -> sum_quantiles ) {
137+ metric_dst -> sum_quantiles = calloc (1 , sizeof (uint64_t ) * (summary -> quantiles_count ));
138+ if (!metric_dst -> sum_quantiles ) {
139+ return -1 ;
140+ }
141+ }
142+
143+ for (i = 0 ; i < summary -> quantiles_count ; i ++ ) {
144+ /* summary quantiles are always integers, no need to convert them */
145+ metric_dst -> sum_quantiles [i ] = metric_src -> sum_quantiles [i ];
146+ }
147+
148+ metric_dst -> sum_quantiles_count = metric_src -> sum_quantiles_count ;
149+ metric_dst -> sum_quantiles_set = metric_src -> sum_quantiles_set ;
150+
151+ metric_dst -> sum_count = metric_src -> sum_count ;
152+ metric_dst -> sum_sum = metric_src -> sum_sum ;
153+
154+ return 0 ;
155+ }
156+
157+ int cmt_cat_copy_map (struct cmt_opts * opts , struct cmt_map * dst , struct cmt_map * src )
158+ {
102159 int c ;
103160 int ret ;
104161 uint64_t ts ;
@@ -107,6 +164,7 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
107164 struct cfl_list * head ;
108165 struct cmt_metric * metric_dst ;
109166 struct cmt_metric * metric_src ;
167+ struct cmt_summary * summary ;
110168 struct cmt_histogram * histogram ;
111169
112170 /* Handle static metric (no labels case) */
@@ -119,33 +177,17 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
119177
120178 if (src -> type == CMT_HISTOGRAM ) {
121179 histogram = (struct cmt_histogram * ) src -> parent ;
122-
123- if (!metric_dst -> hist_buckets ) {
124- metric_dst -> hist_buckets = calloc (1 , sizeof (uint64_t ) * (histogram -> buckets -> count + 1 ));
125- if (!metric_dst -> hist_buckets ) {
126- return -1 ;
127- }
128- }
129- for (i = 0 ; i < histogram -> buckets -> count ; i ++ ) {
130- metric_dst -> hist_buckets [i ] = metric_src -> hist_buckets [i ];
180+ ret = cat_histogram_values (metric_dst , histogram , metric_src );
181+ if (ret == -1 ) {
182+ return -1 ;
131183 }
132- metric_dst -> hist_count = metric_src -> hist_count ;
133- metric_dst -> hist_sum = metric_src -> hist_sum ;
134184 }
135185 else if (src -> type == CMT_SUMMARY ) {
136- metric_dst -> sum_quantiles_count = metric_src -> sum_quantiles_count ;
137- metric_dst -> sum_quantiles_set = metric_src -> sum_quantiles_set ;
138- if (!metric_dst -> sum_quantiles ) {
139- metric_dst -> sum_quantiles = calloc (1 , sizeof (uint64_t ) * (metric_src -> sum_quantiles_count ));
140- if (!metric_dst -> sum_quantiles ) {
141- return -1 ;
142- }
143- }
144- for (i = 0 ; i < metric_src -> sum_quantiles_count ; i ++ ) {
145- metric_dst -> sum_quantiles [i ] = metric_src -> sum_quantiles [i ];
186+ summary = (struct cmt_summary * ) src -> parent ;
187+ ret = cat_summary_values (metric_dst , summary , metric_src );
188+ if (ret == -1 ) {
189+ return -1 ;
146190 }
147- metric_dst -> sum_count = metric_src -> sum_count ;
148- metric_dst -> sum_sum = metric_src -> sum_sum ;
149191 }
150192
151193 ts = cmt_metric_get_timestamp (metric_src );
@@ -173,34 +215,17 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
173215
174216 if (src -> type == CMT_HISTOGRAM ) {
175217 histogram = (struct cmt_histogram * ) src -> parent ;
176-
177- if (!metric_dst -> hist_buckets ) {
178- metric_dst -> hist_buckets = calloc (1 , sizeof (uint64_t ) * (histogram -> buckets -> count + 1 ));
179- if (!metric_dst -> hist_buckets ) {
180- return -1 ;
181- }
182- }
183-
184- for (i = 0 ; i < histogram -> buckets -> count ; i ++ ) {
185- metric_dst -> hist_buckets [i ] = metric_src -> hist_buckets [i ];
218+ ret = cat_histogram_values (metric_dst , histogram , metric_src );
219+ if (ret == -1 ) {
220+ return -1 ;
186221 }
187- metric_dst -> hist_count = metric_src -> hist_count ;
188- metric_dst -> hist_sum = metric_src -> hist_sum ;
189222 }
190223 else if (src -> type == CMT_SUMMARY ) {
191- metric_dst -> sum_quantiles_count = metric_src -> sum_quantiles_count ;
192- metric_dst -> sum_quantiles_set = metric_src -> sum_quantiles_set ;
193- if (!metric_dst -> sum_quantiles ) {
194- metric_dst -> sum_quantiles = calloc (1 , sizeof (uint64_t ) * (metric_src -> sum_quantiles_count ));
195- if (!metric_dst -> sum_quantiles ) {
196- return -1 ;
197- }
224+ summary = (struct cmt_summary * ) src -> parent ;
225+ ret = cat_summary_values (metric_dst , summary , metric_src );
226+ if (ret == -1 ) {
227+ return -1 ;
198228 }
199- for (i = 0 ; i < metric_src -> sum_quantiles_count ; i ++ ) {
200- metric_dst -> sum_quantiles [i ] = metric_src -> sum_quantiles [i ];
201- }
202- metric_dst -> sum_count = metric_src -> sum_count ;
203- metric_dst -> sum_sum = metric_src -> sum_sum ;
204229 }
205230
206231 ts = cmt_metric_get_timestamp (metric_src );
@@ -213,6 +238,88 @@ int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map
213238
214239}
215240
241+ static inline int cmt_opts_compare (struct cmt_opts * a , struct cmt_opts * b )
242+ {
243+ int ret ;
244+
245+ ret = strcmp (a -> ns , a -> ns );
246+ if (ret != 0 ) {
247+ return ret ;
248+ }
249+
250+ ret = strcmp (a -> subsystem , b -> subsystem );
251+ if (ret != 0 ) {
252+ return ret ;
253+ }
254+
255+ ret = strcmp (a -> name , b -> name );
256+ if (ret != 0 ) {
257+ return ret ;
258+ }
259+
260+ return strcmp (a -> description , b -> description );
261+ }
262+
263+ static struct cmt_counter * counter_lookup (struct cmt * cmt , struct cmt_opts * opts )
264+ {
265+ struct cmt_counter * counter ;
266+ struct cfl_list * head ;
267+
268+ cfl_list_foreach (head , & cmt -> counters ) {
269+ counter = cfl_list_entry (head , struct cmt_counter , _head );
270+ if (cmt_opts_compare (& counter -> opts , opts ) == 0 ) {
271+ return counter ;
272+ }
273+ }
274+
275+ return NULL ;
276+ }
277+
278+ static struct cmt_gauge * gauge_lookup (struct cmt * cmt , struct cmt_opts * opts )
279+ {
280+ struct cmt_gauge * gauge ;
281+ struct cfl_list * head ;
282+
283+ cfl_list_foreach (head , & cmt -> gauges ) {
284+ gauge = cfl_list_entry (head , struct cmt_gauge , _head );
285+ if (cmt_opts_compare (& gauge -> opts , opts ) == 0 ) {
286+ return gauge ;
287+ }
288+ }
289+
290+ return NULL ;
291+ }
292+
293+ static struct cmt_untyped * untyped_lookup (struct cmt * cmt , struct cmt_opts * opts )
294+ {
295+ struct cmt_untyped * untyped ;
296+ struct cfl_list * head ;
297+
298+ cfl_list_foreach (head , & cmt -> untypeds ) {
299+ untyped = cfl_list_entry (head , struct cmt_untyped , _head );
300+ if (cmt_opts_compare (& untyped -> opts , opts ) == 0 ) {
301+ return untyped ;
302+ }
303+ }
304+
305+ return NULL ;
306+ }
307+
308+ static struct cmt_histogram * histogram_lookup (struct cmt * cmt , struct cmt_opts * opts )
309+ {
310+ struct cmt_histogram * histogram ;
311+ struct cfl_list * head ;
312+
313+ cfl_list_foreach (head , & cmt -> histograms ) {
314+ histogram = cfl_list_entry (head , struct cmt_histogram , _head );
315+ if (cmt_opts_compare (& histogram -> opts , opts ) == 0 ) {
316+ return histogram ;
317+ }
318+ }
319+
320+ return NULL ;
321+ }
322+
216323int cmt_cat_counter (struct cmt * cmt , struct cmt_counter * counter ,
217324 struct cmt_map * filtered_map )
218325{
@@ -230,11 +337,14 @@ int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter,
230337 return -1 ;
231338 }
232339
233- /* create counter */
234- c = cmt_counter_create (cmt ,
235- opts -> ns , opts -> subsystem ,
236- opts -> name , opts -> description ,
237- map -> label_count , labels );
340+ c = counter_lookup (cmt , opts );
341+ if (!c ) {
342+ /* create counter */
343+ c = cmt_counter_create (cmt ,
344+ opts -> ns , opts -> subsystem ,
345+ opts -> name , opts -> description ,
346+ map -> label_count , labels );
347+ }
238348
239349 free (labels );
240350 if (!c ) {
@@ -274,11 +384,15 @@ int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge,
274384 return -1 ;
275385 }
276386
277- /* create counter */
278- g = cmt_gauge_create (cmt ,
279- opts -> ns , opts -> subsystem ,
280- opts -> name , opts -> description ,
281- map -> label_count , labels );
387+ g = gauge_lookup (cmt , opts );
388+ if (!g ) {
389+ /* create counter */
390+ g = cmt_gauge_create (cmt ,
391+ opts -> ns , opts -> subsystem ,
392+ opts -> name , opts -> description ,
393+ map -> label_count , labels );
394+ }
395+
282396 free (labels );
283397 if (!g ) {
284398 return -1 ;
@@ -317,11 +431,15 @@ int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped,
317431 return -1 ;
318432 }
319433
320- /* create counter */
321- u = cmt_untyped_create (cmt ,
322- opts -> ns , opts -> subsystem ,
323- opts -> name , opts -> description ,
324- map -> label_count , labels );
434+ u = untyped_lookup (cmt , opts );
435+ if (!u ) {
436+ /* create counter */
437+ u = cmt_untyped_create (cmt ,
438+ opts -> ns , opts -> subsystem ,
439+ opts -> name , opts -> description ,
440+ map -> label_count , labels );
441+ }
442+
325443 free (labels );
326444 if (!u ) {
327445 return -1 ;
@@ -362,16 +480,19 @@ int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram,
362480 return -1 ;
363481 }
364482
365- buckets_count = histogram -> buckets -> count ;
366- buckets = cmt_histogram_buckets_create_size (histogram -> buckets -> upper_bounds ,
367- buckets_count );
483+ hist = histogram_lookup (cmt , opts );
484+ if (!hist ) {
485+ buckets_count = histogram -> buckets -> count ;
486+ buckets = cmt_histogram_buckets_create_size (histogram -> buckets -> upper_bounds ,
487+ buckets_count );
368488
369- /* create histogram */
370- hist = cmt_histogram_create (cmt ,
371- opts -> ns , opts -> subsystem ,
372- opts -> name , opts -> description ,
373- buckets ,
374- map -> label_count , labels );
489+ /* create histogram */
490+ hist = cmt_histogram_create (cmt ,
491+ opts -> ns , opts -> subsystem ,
492+ opts -> name , opts -> description ,
493+ buckets ,
494+ map -> label_count , labels );
495+ }
375496 free (labels );
376497
377498 if (!hist ) {
0 commit comments