]> git.ipfire.org Git - oddments/collecty.git/commitdiff
metrics: Only require one allocation
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 22 Oct 2025 20:28:01 +0000 (20:28 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 22 Oct 2025 20:28:01 +0000 (20:28 +0000)
Since we know how many metrics we might expect from the beginning we can
realise the metrics as a variable array and only have one allocation.

Since this application is having a lot of allocations, this would quite
save a bit of memory fragmentation and load on the allocator.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/metrics.c

index e61ff682e74dd24b97ba2e40a4cce0bde33eedd0..79e9016b1f90cf45f6e5632b650528e4cfb0d17b 100644 (file)
@@ -65,8 +65,8 @@ struct td_metrics {
        struct timeval t;
 
        // Metrics
-       td_metric* metrics;
        unsigned int num_metrics;
+       td_metric metrics[];
 };
 
 static int td_metrics_valid_object(td_metrics* self, const char* object) {
@@ -113,17 +113,19 @@ static void td_metrics_free(td_metrics* self) {
                td_source_unref(self->source);
        if (self->ctx)
                td_ctx_unref(self->ctx);
-       if (self->metrics)
-               free(self->metrics);
        free(self);
 }
 
 int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, const char* object) {
+       unsigned int num_metrics = 0;
        td_metrics* self = NULL;
        int r;
 
+       // Fetch how many data sources there are
+       num_metrics = td_source_num_data_sources(source);
+
        // Allocate some memory
-       self = calloc(1, sizeof(*self));
+       self = calloc(1, sizeof(*self) + (num_metrics * sizeof(*self->metrics)));
        if (!self)
                return -errno;
 
@@ -150,6 +152,9 @@ int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, cons
                }
        }
 
+       // Store the number of data sources
+       self->num_metrics = num_metrics;
+
        // Fetch the current time
        r = gettimeofday(&self->t, NULL);
        if (r < 0) {
@@ -157,24 +162,6 @@ int td_metrics_create(td_metrics** metrics, td_ctx* ctx, td_source* source, cons
                goto ERROR;
        }
 
-       // Fetch the number of data sources
-       self->num_metrics = td_source_num_data_sources(self->source);
-
-       // Fail if there are no data sources
-       if (!self->num_metrics) {
-               ERROR(self->ctx, "Source %s has no data sources\n", td_source_name(self->source));
-               r = -EINVAL;
-               goto ERROR;
-       }
-
-       // Allocate space for the metrics
-       self->metrics = calloc(self->num_metrics, sizeof(*self->metrics));
-       if (!self->metrics) {
-               ERROR(self->ctx, "Failed to allocate %u metric(s): %m\n", self->num_metrics);
-               r = -errno;
-               goto ERROR;
-       }
-
        // Return the pointer
        *metrics = self;
        return 0;