From: Michael Tremer Date: Wed, 30 Mar 2022 14:58:36 +0000 (+0000) Subject: database: Allocate subnets list only once X-Git-Tag: 0.9.13~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=065b34965f81995b4e6ec4d41b4ba87a79abf0df;p=location%2Flibloc.git database: Allocate subnets list only once This is a performance improvement when exporting networks flattened. For the subnet search, we allocate an empty list many times which is often not required. This patch changes this behaviour that (if needed) the lists will be allocated and will stay around and cleared if necessary. Signed-off-by: Michael Tremer --- diff --git a/src/database.c b/src/database.c index 8835507..1b34845 100644 --- a/src/database.c +++ b/src/database.c @@ -125,6 +125,7 @@ struct loc_database_enumerator { // For subnet search and bogons struct loc_network_list* stack; + struct loc_network_list* subnets; // For bogons struct in6_addr gap6_start; @@ -984,6 +985,9 @@ static void loc_database_enumerator_free(struct loc_database_enumerator* enumera if (enumerator->stack) loc_network_list_unref(enumerator->stack); + if (enumerator->subnets) + loc_network_list_unref(enumerator->subnets); + free(enumerator); } @@ -1301,12 +1305,13 @@ static int __loc_database_enumerator_next_network_flattened( return 0; struct loc_network* subnet = NULL; - struct loc_network_list* subnets; // Create a list with all subnets - r = loc_network_list_new(enumerator->ctx, &subnets); - if (r) - return r; + if (!enumerator->subnets) { + r = loc_network_list_new(enumerator->ctx, &enumerator->subnets); + if (r) + return r; + } // Search all subnets from the database while (1) { @@ -1314,7 +1319,7 @@ static int __loc_database_enumerator_next_network_flattened( r = __loc_database_enumerator_next_network(enumerator, &subnet, 0); if (r) { loc_network_unref(subnet); - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); return r; } @@ -1325,10 +1330,10 @@ static int __loc_database_enumerator_next_network_flattened( // Collect all subnets in a list if (loc_network_is_subnet(*network, subnet)) { - r = loc_network_list_push(subnets, subnet); + r = loc_network_list_push(enumerator->subnets, subnet); if (r) { loc_network_unref(subnet); - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); return r; } @@ -1341,7 +1346,7 @@ static int __loc_database_enumerator_next_network_flattened( r = loc_network_list_push(enumerator->stack, subnet); if (r) { loc_network_unref(subnet); - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); return r; } @@ -1350,27 +1355,28 @@ static int __loc_database_enumerator_next_network_flattened( break; } - DEBUG(enumerator->ctx, "Found %zu subnet(s)\n", loc_network_list_size(subnets)); + DEBUG(enumerator->ctx, "Found %zu subnet(s)\n", + loc_network_list_size(enumerator->subnets)); // We can abort here if the network has no subnets - if (loc_network_list_empty(subnets)) { - loc_network_list_unref(subnets); + if (loc_network_list_empty(enumerator->subnets)) { + loc_network_list_clear(enumerator->subnets); return 0; } // If the network has any subnets, we will break it into smaller parts // without the subnets. - struct loc_network_list* excluded = loc_network_exclude_list(*network, subnets); + struct loc_network_list* excluded = loc_network_exclude_list(*network, enumerator->subnets); if (!excluded) { - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); return -1; } // Merge subnets onto the stack - r = loc_network_list_merge(enumerator->stack, subnets); + r = loc_network_list_merge(enumerator->stack, enumerator->subnets); if (r) { - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); loc_network_list_unref(excluded); return r; @@ -1379,13 +1385,13 @@ static int __loc_database_enumerator_next_network_flattened( // Push excluded list onto the stack r = loc_network_list_merge(enumerator->stack, excluded); if (r) { - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); loc_network_list_unref(excluded); return r; } - loc_network_list_unref(subnets); + loc_network_list_clear(enumerator->subnets); loc_network_list_unref(excluded); // Drop the network and restart the whole process again to pick the next network