]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
optimization: adjusting: mesure zone size incrementally for updates
authorLibor Peltan <libor.peltan@nic.cz>
Fri, 10 May 2019 15:11:49 +0000 (17:11 +0200)
committerLibor Peltan <libor.peltan@nic.cz>
Wed, 15 May 2019 08:33:21 +0000 (10:33 +0200)
src/knot/dnssec/zone-events.c
src/knot/zone/adjust.c
src/knot/zone/adjust.h
src/knot/zone/contents.c
src/knot/zone/node.c
tests/knot/test_zone-update.c

index 40490f8880c8a28f625c83081842d22ac0ff58fc..8f47d14a21911c8fe65b6a2d8a515ff57d152031 100644 (file)
@@ -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;
        }
index a3b2d31da897691b97af60a57a2ad899696afb2d..676c582150c51bb22ba0ea4abaf1b82def7ae83a 100644 (file)
 #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(
index d9a2e1f8ac74a6aad2c3243046f061284980f87e..eea15bf4f7f69b09c389311c1705c559e9264767 100644 (file)
@@ -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.
index 915110da58c768322bb97b10bd4ca6c739f35334..c50081036340172c315bf48bec029022ae62846a 100644 (file)
@@ -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;
index 474c6b75aa9d1520400286401df967ab3092ddbc..9ad65f59e1e187da978d39b295086ff75ac1a2cc 100644 (file)
@@ -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);
+               }
        }
 }
 
index 288a11ca65939d7b5b688f4fa23a646458b60b86..28781cd8dd87d055a4baa721e088934251b9809a 100644 (file)
@@ -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[])