Memory tidy-up

- pack the cfgmgr type enum, so it likely takes 1 byte rather than 4
  bytes

- when putting a string in LMDB, let's allocate only the size of type +
  strlen(string) + 1, instead of the size of the whole cfgmgr_val_t +
  strlen(string) + 1. It needs a special threatment when reading, but
  probably worth it considering cfgmgr_val_t is not tiny (and will
  likely grows up)
This commit is contained in:
Colin Vidal
2025-02-24 10:35:39 +01:00
parent 349103f89c
commit 80e7c8bcb1
2 changed files with 21 additions and 9 deletions
+20 -8
View File
@@ -599,10 +599,15 @@ isc__cfgmgr_getval(const char *name, isc_cfgmgr_val_t *value) {
goto out;
}
memcpy(value, dbval.mv_data, sizeof(*value));
if (value->type == ISC_CFGMGR_STRING) {
value->string = ((char *)dbval.mv_data) + sizeof(value->type);
const isc_cfgmgr_type_t strtype = ISC_CFGMGR_STRING;
if (memcmp(dbval.mv_data, &strtype, sizeof(strtype)) == 0) {
value->type = strtype;
value->string = (char *)dbval.mv_data + sizeof(strtype);
} else {
REQUIRE(sizeof(*value) == dbval.mv_size);
memmove(value, dbval.mv_data, sizeof(*value));
}
INSIST(value->type != ISC_CFGMGR_UNDEFINED);
out:
@@ -652,12 +657,19 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) {
goto out;
}
/*
* String is a specific case as it needs an allocation, so the size is
* just the size of the type and the string length + 1. For the other
* cases, in order to keep the flow unconditional and simple there is a
* slight memory waste, i.e. storing a uint32_t will take the size of
* isc_cfgmgr_val_t.
*/
if (value->type == ISC_CFGMGR_STRING) {
dbval.mv_size = sizeof(*value) + strlen(value->string) + 1;
dbval.mv_size = sizeof(value->type) + strlen(value->string) + 1;
dbval.mv_data = isc_mem_allocate(isc__cfgmgr_mctx,
dbval.mv_size);
memcpy(dbval.mv_data, value, sizeof(value->type));
strcpy(((char *)dbval.mv_data) + sizeof(value->type),
memmove(dbval.mv_data, value, sizeof(value->type));
strcpy((char *)dbval.mv_data + sizeof(value->type),
value->string);
} else {
dbval = (MDB_val){ .mv_size = sizeof(*value),
@@ -671,8 +683,8 @@ isc__cfgmgr_setval(const char *name, const isc_cfgmgr_val_t *value, bool list) {
if (list == false) {
/*
* Can't use MDB_NOOVERWRITE as it would override the
* data if the key/value already exists. Making a
* value copy ahead just in case is likely more
* data if the key/value already exists so it wouldn't work with
* list. Making a value copy ahead just in case is likely more
* expensive than an extra lookup
*/
if (mdb_cursor_get(isc__cfgmgr_ctx.cursor, &dbkey, NULL,
+1 -1
View File
@@ -26,7 +26,7 @@ typedef enum isc_cfgmgr_type {
ISC_CFGMGR_NONE,
ISC_CFGMGR_SOCKADDR,
ISC_CFGMGR_UINT32
} isc_cfgmgr_type_t;
} __attribute__ ((__packed__)) isc_cfgmgr_type_t;
/*
* Generic value holding the actual value and type value for