From: Libor Peltan Date: Fri, 10 May 2019 15:11:49 +0000 (+0200) Subject: optimization: adjusting: mesure zone size incrementally for updates X-Git-Tag: v2.9.0~269^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cee9549febe433647f052fe88f9aed66effd2e59;p=thirdparty%2Fknot-dns.git optimization: adjusting: mesure zone size incrementally for updates --- diff --git a/src/knot/dnssec/zone-events.c b/src/knot/dnssec/zone-events.c index 40490f8880..8f47d14a21 100644 --- a/src/knot/dnssec/zone-events.c +++ b/src/knot/dnssec/zone-events.c @@ -258,7 +258,7 @@ int knot_dnssec_sign_update(zone_update_t *update, zone_sign_reschedule_t *resch goto done; } - result = zone_adjust_update(update, adjust_cb_flags, NULL); + result = zone_adjust_update(update, adjust_cb_flags, NULL, false); if (result != KNOT_EOK) { goto done; } diff --git a/src/knot/zone/adjust.c b/src/knot/zone/adjust.c index a3b2d31da8..676c582150 100644 --- a/src/knot/zone/adjust.c +++ b/src/knot/zone/adjust.c @@ -22,6 +22,12 @@ #include "knot/dnssec/zone-nsec.h" #include "knot/zone/adds_tree.h" +typedef enum { + ADJUST_MEASURE_SIZE_NONE = 0, + ADJUST_MEASURE_SIZE_NORM = 1, + ADJUST_MEASURE_SIZE_DIFF = -1, +} adjust_measure_size_t; + int adjust_cb_flags(zone_node_t *node, const zone_contents_t *zone) { zone_node_t *parent = node_parent(node); @@ -271,10 +277,11 @@ typedef struct { const zone_contents_t *zone; zone_node_t *previous_node; size_t zone_size; + size_t counter_size; uint32_t zone_max_ttl; adjust_cb_t adjust_cb; bool adjust_prevs; - bool measure_size; + adjust_measure_size_t measure_size; } zone_adjust_arg_t; static int adjust_single(zone_node_t *node, void *data) @@ -282,12 +289,15 @@ static int adjust_single(zone_node_t *node, void *data) assert(node != NULL); assert(data != NULL); + zone_adjust_arg_t *args = (zone_adjust_arg_t *)data; + if (args->measure_size == ADJUST_MEASURE_SIZE_DIFF) { + node_size(binode_counterpart(node), &args->counter_size); + } + if ((node->flags & NODE_FLAGS_DELETED)) { return KNOT_EOK; } - zone_adjust_arg_t *args = (zone_adjust_arg_t *)data; - // remember first node if (args->first_node == NULL) { args->first_node = node; @@ -306,24 +316,25 @@ static int adjust_single(zone_node_t *node, void *data) if (args->measure_size) { node_size(node, &args->zone_size); } + node_max_ttl(node, &args->zone_max_ttl); return args->adjust_cb(node, args->zone); } static int zone_adjust_tree(zone_tree_t *tree, const zone_contents_t *zone, adjust_cb_t adjust_cb, - size_t *tree_size, uint32_t *tree_max_ttl, bool adjust_prevs, bool measure_size) + ssize_t *tree_size, uint32_t *tree_max_ttl, bool adjust_prevs, + adjust_measure_size_t measure_size) { if (zone_tree_is_empty(tree)) { return KNOT_EOK; } - zone_adjust_arg_t arg = { - .zone = zone, - .adjust_cb = adjust_cb, - .adjust_prevs = adjust_prevs, - .measure_size = measure_size, - }; + zone_adjust_arg_t arg = { 0 }; + arg.zone = zone; + arg.adjust_cb = adjust_cb; + arg.adjust_prevs = adjust_prevs; + arg.measure_size = measure_size; int ret = zone_tree_apply(tree, adjust_single, &arg); if (ret != KNOT_EOK) { @@ -335,7 +346,7 @@ static int zone_adjust_tree(zone_tree_t *tree, const zone_contents_t *zone, adju } if (tree_size != NULL) { - *tree_size = arg.zone_size; + *tree_size = arg.zone_size - arg.counter_size; } if (tree_max_ttl != NULL) { *tree_max_ttl = arg.zone_max_ttl; @@ -354,30 +365,39 @@ int zone_adjust_contents(zone_contents_t *zone, adjust_cb_t nodes_cb, adjust_cb_ } zone->dnssec = node_rrtype_is_signed(zone->apex, KNOT_RRTYPE_SOA); - size_t nodes_size = 0, nsec3_size = 0; + ssize_t nodes_size = 0, nsec3_size = 0; uint32_t nodes_max_ttl = 0, nsec3_max_ttl = 0; + adjust_measure_size_t ms = (measure_size && nsec3_cb != NULL ? ADJUST_MEASURE_SIZE_NORM : ADJUST_MEASURE_SIZE_NONE); if (nsec3_cb != NULL) { - ret = zone_adjust_tree(zone->nsec3_nodes, zone, nsec3_cb, &nsec3_size, &nsec3_max_ttl, true, measure_size && (nodes_cb != NULL)); + ret = zone_adjust_tree(zone->nsec3_nodes, zone, nsec3_cb, &nsec3_size, &nsec3_max_ttl, true, ms); } if (ret == KNOT_EOK && nodes_cb != NULL) { - ret = zone_adjust_tree(zone->nodes, zone, nodes_cb, &nodes_size, &nodes_max_ttl, true, measure_size); + ret = zone_adjust_tree(zone->nodes, zone, nodes_cb, &nodes_size, &nodes_max_ttl, true, ms); } if (ret == KNOT_EOK && nodes_cb != NULL && nsec3_cb != NULL) { - zone->size = nodes_size + nsec3_size; + if (measure_size) { + zone->size = nodes_size + nsec3_size; + } zone->max_ttl = MAX(nodes_max_ttl, nsec3_max_ttl); } return ret; } -int zone_adjust_update(zone_update_t *update, adjust_cb_t nodes_cb, adjust_cb_t nsec3_cb) +int zone_adjust_update(zone_update_t *update, adjust_cb_t nodes_cb, adjust_cb_t nsec3_cb, bool measure_size) { int ret = KNOT_EOK; + adjust_measure_size_t ms = (measure_size && nsec3_cb != NULL ? ADJUST_MEASURE_SIZE_DIFF : ADJUST_MEASURE_SIZE_NONE); + ssize_t nodes_size = 0, nsec3_size = 0; + if (nsec3_cb != NULL) { - ret = zone_adjust_tree(update->a_ctx->nsec3_ptrs, update->new_cont, nsec3_cb, NULL, NULL, false, false); + ret = zone_adjust_tree(update->a_ctx->nsec3_ptrs, update->new_cont, nsec3_cb, &nsec3_size, NULL, false, ms); } if (ret == KNOT_EOK && nodes_cb != NULL) { - ret = zone_adjust_tree(update->a_ctx->node_ptrs, update->new_cont, nodes_cb, NULL, NULL, false, false); + ret = zone_adjust_tree(update->a_ctx->node_ptrs, update->new_cont, nodes_cb, &nodes_size, NULL, false, ms); + } + if (ret == KNOT_EOK && measure_size && nodes_cb != NULL && nsec3_cb != NULL) { + update->new_cont->size += nodes_size + nsec3_size; } return ret; } @@ -404,12 +424,12 @@ static int adjust_additionals_cb(zone_node_t *node, void *ctx) int zone_adjust_incremental_update(zone_update_t *update) { - int ret = zone_adjust_contents(update->new_cont, adjust_cb_flags, adjust_cb_nsec3_flags, true); + int ret = zone_adjust_contents(update->new_cont, adjust_cb_flags, adjust_cb_nsec3_flags, false); if (ret == KNOT_EOK) { ret = zone_adjust_contents(update->new_cont, adjust_cb_point_to_nsec3, NULL, false); } if (ret == KNOT_EOK) { - ret = zone_adjust_update(update, adjust_cb_wildcard_nsec3, NULL); + ret = zone_adjust_update(update, adjust_cb_wildcard_nsec3, adjust_cb_void, true); } if (ret == KNOT_EOK) { ret = additionals_tree_update_from_binodes( diff --git a/src/knot/zone/adjust.h b/src/knot/zone/adjust.h index d9a2e1f8ac..eea15bf4f7 100644 --- a/src/knot/zone/adjust.h +++ b/src/knot/zone/adjust.h @@ -66,6 +66,7 @@ int adjust_cb_void(zone_node_t *node, const zone_contents_t *zone); * \param zone Zone to be adjusted. * \param nodes_cb Callback for NORMAL nodes. * \param nsec3_cb Callback for NSEC3 nodes. + * \param measure_size While adjusting, count the size of the zone and store it to contents. * * \return KNOT_E* */ @@ -81,10 +82,11 @@ int zone_adjust_contents(zone_contents_t *zone, adjust_cb_t nodes_cb, adjust_cb_ * \param update Zone update being finalized. * \param nodes_cb Callback for NORMAL nodes. * \param nsec3_cb Callback for NSEC3 nodes. + * \param measure_size While adjusting, count the size of the zone and store it to contents. * * \return KNOT_E* */ -int zone_adjust_update(zone_update_t *update, adjust_cb_t nodes_cb, adjust_cb_t nsec3_cb); +int zone_adjust_update(zone_update_t *update, adjust_cb_t nodes_cb, adjust_cb_t nsec3_cb, bool measure_size); /*! * \brief Do a general-purpose full update. diff --git a/src/knot/zone/contents.c b/src/knot/zone/contents.c index 915110da58..c500810363 100644 --- a/src/knot/zone/contents.c +++ b/src/knot/zone/contents.c @@ -497,6 +497,7 @@ int zone_contents_shallow_copy(const zone_contents_t *from, zone_contents_t **to contents->nsec3_nodes = NULL; } contents->adds_tree = from->adds_tree; + contents->size = from->size; *to = contents; return KNOT_EOK; diff --git a/src/knot/zone/node.c b/src/knot/zone/node.c index 474c6b75aa..9ad65f59e1 100644 --- a/src/knot/zone/node.c +++ b/src/knot/zone/node.c @@ -393,10 +393,12 @@ bool node_bitmap_equal(const zone_node_t *a, const zone_node_t *b) void node_size(const zone_node_t *node, size_t *size) { - int rrset_count = node->rrset_count; - for (int i = 0; i < rrset_count; i++) { - knot_rrset_t rrset = node_rrset_at(node, i); - *size += knot_rrset_size(&rrset); + if (node != NULL) { + int rrset_count = node->rrset_count; + for (int i = 0; i < rrset_count; i++) { + knot_rrset_t rrset = node_rrset_at(node, i); + *size += knot_rrset_size(&rrset); + } } } diff --git a/tests/knot/test_zone-update.c b/tests/knot/test_zone-update.c index 288a11ca65..28781cd8dd 100644 --- a/tests/knot/test_zone-update.c +++ b/tests/knot/test_zone-update.c @@ -24,6 +24,7 @@ #include "contrib/macros.h" #include "contrib/getline.h" #include "knot/updates/zone-update.h" +#include "knot/zone/adjust.h" #include "knot/zone/node.h" #include "libzscanner/scanner.h" #include "knot/server/server.h" @@ -331,6 +332,13 @@ void test_incremental(zone_t *zone, zs_scanner_t *sc) test_zone_unified(zone); knot_rdataset_clear(&rrset.rrs, NULL); + + size_t zone_size1 = zone->contents->size; + ret = zone_adjust_full(zone->contents); + ok(ret == KNOT_EOK, "zone adjust full shall work"); + size_t zone_size2 = zone->contents->size; + ok(zone_size1 == zone_size2, "zone size measured the same by incremental and full way (%zu, %zu)", zone_size1, zone_size2); + // TODO test more things after re-adjust, search for non-unified bi-nodes } int main(int argc, char *argv[])