From 065b34965f81995b4e6ec4d41b4ba87a79abf0df Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Wed, 30 Mar 2022 14:58:36 +0000 Subject: [PATCH] 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 --- src/database.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) 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 -- 2.39.5