]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
utils/cache_gc: use lib/generic/array instead of dynarray
authorOto Šťáva <oto.stava@nic.cz>
Fri, 17 May 2024 11:03:27 +0000 (13:03 +0200)
committerOto Šťáva <oto.stava@nic.cz>
Mon, 20 May 2024 10:18:38 +0000 (12:18 +0200)
This should appease Coverity Scan, and make the garbage collector
consistent with the rest of the Resolver.

contrib/dynarray.h [deleted file]
contrib/dynarray.spdx [deleted file]
utils/cache_gc/kr_cache_gc.c

diff --git a/contrib/dynarray.h b/contrib/dynarray.h
deleted file mode 100644 (file)
index 7cbb686..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*  Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
- *  SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-/*!
- * \brief Simple write-once allocation-optimal dynamic array.
- *
- * Include it into your .c file
- *
- * prefix - identifier prefix, e.g. ptr -> struct ptr_dynarray, ptr_dynarray_add(), ...
- * ntype - data type to be stored. Let it be a number, pointer or small struct
- * initial_capacity - how many data items will be allocated on stack and copied with assignment
- *
- * prefix_dynarray_add() - add a data item
- * prefix_dynarray_fix() - call EVERYTIME the array is copied from some already invalid stack
- * prefix_dynarray_free() - call EVERYTIME you dismiss all copies of the array
- *
- */
-
-#include <stdlib.h>
-#include <assert.h>
-
-#pragma once
-
-#define DYNARRAY_VISIBILITY_STATIC static
-#define DYNARRAY_VISIBILITY_PUBLIC
-#define DYNARRAY_VISIBILITY_LIBRARY __public__
-
-#define dynarray_declare(prefix, ntype, visibility, initial_capacity) \
-       typedef struct prefix ## _dynarray { \
-               ssize_t capacity; \
-               ssize_t size; \
-               ntype *(*arr)(struct prefix ## _dynarray *dynarray); \
-               ntype init[initial_capacity]; \
-               ntype *_arr; \
-       } prefix ## _dynarray_t; \
-       \
-       visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \
-       visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \
-                                               ntype const *to_add); \
-       visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray);
-
-#define dynarray_foreach(prefix, ntype, ptr, array) \
-       for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \
-            ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++)
-
-#define dynarray_define(prefix, ntype, visibility) \
-       \
-       static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \
-       { \
-               if (dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)) { \
-                       free(dynarray->_arr); \
-               } \
-       } \
-       \
-       __attribute__((unused)) \
-       visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \
-       { \
-               assert(dynarray->size <= dynarray->capacity); \
-               return (dynarray->capacity <= sizeof(dynarray->init) / sizeof(*dynarray->init) ? \
-                       dynarray->init : dynarray->_arr); \
-       } \
-       \
-       static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \
-       { \
-               assert(dynarray->capacity == sizeof(dynarray->init) / sizeof(*dynarray->init)); \
-               return dynarray->init; \
-       } \
-       \
-       static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \
-       { \
-               assert(dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)); \
-               return dynarray->_arr; \
-       } \
-       \
-       __attribute__((unused)) \
-       visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \
-                                               ntype const *to_add) \
-       { \
-               if (dynarray->capacity < 0) { \
-                       return; \
-               } \
-               if (dynarray->capacity == 0) { \
-                       dynarray->capacity = sizeof(dynarray->init) / sizeof(*dynarray->init); \
-                       dynarray->arr = prefix ## _dynarray_arr_init__; \
-               } \
-               if (dynarray->size >= dynarray->capacity) { \
-                       ssize_t new_capacity = dynarray->capacity * 2 + 1; \
-                       ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \
-                       if (new_arr == NULL) { \
-                               prefix ## _dynarray_free__(dynarray); \
-                               dynarray->capacity = dynarray->size = -1; \
-                               return; \
-                       } \
-                       if (dynarray->capacity > 0) { \
-                               memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \
-                                      dynarray->capacity * sizeof(ntype)); \
-                       } \
-                       prefix ## _dynarray_free__(dynarray); \
-                       dynarray->_arr = new_arr; \
-                       dynarray->capacity = new_capacity; \
-                       dynarray->arr = prefix ## _dynarray_arr_arr__; \
-               } \
-               prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \
-       } \
-       \
-       __attribute__((unused)) \
-       visibility void prefix ## _dynarray_free(struct prefix ## _dynarray *dynarray) \
-       { \
-               prefix ## _dynarray_free__(dynarray); \
-               memset(dynarray, 0, sizeof(*dynarray)); \
-       }
diff --git a/contrib/dynarray.spdx b/contrib/dynarray.spdx
deleted file mode 100644 (file)
index 02911c9..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-SPDXVersion: SPDX-2.1
-DataLicense: CC0-1.0
-SPDXID: SPDXRef-DOCUMENT
-DocumentName: knotdns-dynarray
-DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-ce6423dd-ac6a-4e78-90c3-5cbdef1e252c
-
-PackageName: knotdns-dynarray
-PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@48c8b4f38cf5f7bf505c79b56adf7580688f6d3d#src/contrib/dynarray.h
-PackageOriginator: Organization: Knot DNS contributors
-PackageLicenseDeclared: GPL-3.0-or-later
index 62465f51ddf717ac6d75af6b71c1bec93b28eab6..4097c80256ebf0f8dd4e96064e2589742b918baa 100644 (file)
@@ -8,20 +8,12 @@
 // libknot includes
 #include <libknot/libknot.h>
 
-// dynarray is inside libknot since 3.1, but it's differently named
-#ifdef knot_dynarray_declare
-       #define dynarray_declare knot_dynarray_declare
-       #define dynarray_define  knot_dynarray_define
-       #define dynarray_foreach knot_dynarray_foreach
-#else
-       #include <contrib/dynarray.h>
-#endif
-
 // resolver includes
 #include <lib/cache/api.h>
 #include <lib/cache/impl.h>
 #include <lib/defines.h>
 #include "lib/cache/cdb_lmdb.h"
+#include "lib/generic/array.h"
 #include "lib/utils.h"
 
 #include "kr_cache_gc.h"
@@ -43,41 +35,40 @@ static knot_db_val_t *dbval_copy(const knot_db_val_t * from)
 }
 
 // section: rrtype list
+typedef array_t(uint16_t) rrtype_array_t;
 
-dynarray_declare(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC, 64)
-    dynarray_define(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC)
-static void rrtypelist_add(rrtype_dynarray_t * arr, uint16_t add_type)
+static void rrtypelist_add(rrtype_array_t *arr, uint16_t add_type)
 {
        bool already_present = false;
-       dynarray_foreach(rrtype, uint16_t, i, *arr) {
-               if (*i == add_type) {
+       for (size_t i = 0; i < arr->len; i++) {
+               if (arr->at[i] == add_type) {
                        already_present = true;
                        break;
                }
        }
        if (!already_present) {
-               rrtype_dynarray_add(arr, &add_type);
+               kr_require(array_push(*arr, add_type) >= 0);
        }
 }
 
-static void rrtypelist_print(rrtype_dynarray_t * arr)
+static void rrtypelist_print(rrtype_array_t *arr)
 {
        char type_s[32] = { 0 };
-       dynarray_foreach(rrtype, uint16_t, i, *arr) {
-               knot_rrtype_to_string(*i, type_s, sizeof(type_s));
+       for (size_t i = 0; i < arr->len; i++) {
+               knot_rrtype_to_string(arr->at[i], type_s, sizeof(type_s));
                printf(" %s", type_s);
        }
        printf("\n");
 }
 
-dynarray_declare(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC, 256)
-    dynarray_define(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC)
-static void entry_dynarray_deep_free(entry_dynarray_t * d)
+typedef array_t(knot_db_val_t *) entry_array_t;
+
+static void entry_array_deep_free(entry_array_t *d)
 {
-       dynarray_foreach(entry, knot_db_val_t *, i, *d) {
-               free(*i);
+       for (size_t i = 0; i < d->len; i++) {
+               free(d->at[i]);
        }
-       entry_dynarray_free(d);
+       array_clear(*d);
 }
 
 typedef struct {
@@ -98,7 +89,7 @@ int cb_compute_categories(const knot_db_val_t * key, gc_record_info_t * info,
 
 typedef struct {
        category_t limit_category;
-       entry_dynarray_t to_delete;
+       entry_array_t to_delete;
        size_t cfg_temp_keys_space;
        size_t used_space;
        size_t oversize_records;
@@ -117,7 +108,7 @@ int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info,
                        ctx->oversize_records++;
                        free(todelete);
                } else {
-                       entry_dynarray_add(&ctx->to_delete, &todelete);
+                       kr_require(array_push(ctx->to_delete, todelete) >= 0);
                        ctx->used_space = used;
                }
        }
@@ -229,13 +220,13 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
        to_del.limit_category = limit_category;
        ret = kr_gc_cache_iter(db, cfg, cb_delete_categories, &to_del);
        if (ret != KNOT_EOK) {
-               entry_dynarray_deep_free(&to_del.to_delete);
+               entry_array_deep_free(&to_del.to_delete);
                kr_cache_gc_free_state(state);
                return ret;
        }
        printf
            ("%zu records to be deleted using %.2lf MBytes of temporary memory, %zu records skipped due to memory limit.\n",
-            to_del.to_delete.size, ((double)to_del.used_space / 1048576.0),
+            to_del.to_delete.len, ((double)to_del.used_space / 1048576.0),
             to_del.oversize_records);
 
        //// 4. execute the planned deletions.
@@ -245,23 +236,24 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
 
        kr_timer_start(&timer_delete);
        kr_timer_start(&timer_rw_txn);
-       rrtype_dynarray_t deleted_rrtypes = { 0 };
+       rrtype_array_t deleted_rrtypes = { 0 };
 
        ret = api->txn_begin(db, &txn, 0);
        if (ret != KNOT_EOK) {
                printf("Error starting R/W DB transaction (%s).\n",
                       knot_strerror(ret));
-               entry_dynarray_deep_free(&to_del.to_delete);
+               entry_array_deep_free(&to_del.to_delete);
                kr_cache_gc_free_state(state);
                return ret;
        }
 
-       dynarray_foreach(entry, knot_db_val_t *, i, to_del.to_delete) {
-               ret = api->del(&txn, *i);
+       for (size_t i = 0; i < to_del.to_delete.len; i++) {
+               knot_db_val_t *val = to_del.to_delete.at[i];
+               ret = api->del(&txn, val);
                switch (ret) {
                case KNOT_EOK:
                        deleted_records++;
-                       const int entry_type = kr_gc_key_consistent(**i);
+                       const int entry_type = kr_gc_key_consistent(*val);
                        if (entry_type >= 0) // some "inconsistent" entries are OK
                                rrtypelist_add(&deleted_rrtypes, entry_type);
                        break;
@@ -270,8 +262,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
                        if (VERBOSE_STATUS) {
                                // kresd normally only inserts (or overwrites),
                                // so it's generally suspicious when a key goes missing.
-                               printf("Record already gone (key len %zu): ", (*i)->len);
-                               debug_printbin((*i)->data, (*i)->len);
+                               printf("Record already gone (key len %zu): ", val->len);
+                               debug_printbin(val->data, val->len);
                                printf("\n");
                        }
                        break;
@@ -319,8 +311,8 @@ finish:
        printf("It took %.0lf msecs, %zu transactions (%s)\n\n",
               kr_timer_elapsed(&timer_delete) * 1000, rw_txn_count, knot_strerror(ret));
 
-       rrtype_dynarray_free(&deleted_rrtypes);
-       entry_dynarray_deep_free(&to_del.to_delete);
+       array_clear(deleted_rrtypes);
+       entry_array_deep_free(&to_del.to_delete);
 
        // OK, let's close it in this case.
        kr_cache_gc_free_state(state);