]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove pruning tree code
authorMatthijs Mekking <matthijs@isc.org>
Mon, 19 Feb 2024 10:45:05 +0000 (11:45 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 6 Mar 2024 09:49:02 +0000 (10:49 +0100)
Since qp-tries does not store interior nodes, we can remove all code
related to pruning the tree.

lib/dns/qpdb.c
lib/dns/qpdb_p.h

index 7925045fd97ff528c9e870c462e9393dfbfb507c..eaba8055afec99ef631f568a47b37e7bc9db9cc6 100644 (file)
@@ -207,8 +207,6 @@ qp_triename(void *uctx, char *buf, size_t size) {
        snprintf(buf, size, "qpdb-lite");
 }
 
-static void
-prune_tree(void *arg);
 static void
 free_gluetable(struct cds_wfs_stack *glue_stack);
 
@@ -1128,27 +1126,6 @@ dns__qpdb_newref(dns_qpdb_t *qpdb, dns_qpdata_t *node,
        }
 }
 
-/*%
- * The tree lock must be held for the result to be valid.
- */
-static bool
-is_leaf(dns_qpdata_t *node) {
-       return (node->parent != NULL && node->parent->down == node &&
-               node->left == NULL && node->right == NULL);
-}
-
-static void
-send_to_prune_tree(dns_qpdb_t *qpdb, dns_qpdata_t *node,
-                  isc_rwlocktype_t nlocktype DNS__DB_FLARG) {
-       qpdb_prune_t *prune = isc_mem_get(qpdb->common.mctx, sizeof(*prune));
-       *prune = (qpdb_prune_t){ .node = node };
-
-       dns_db_attach((dns_db_t *)qpdb, &prune->db);
-       dns__qpdb_newref(qpdb, node, nlocktype DNS__DB_FLARG_PASS);
-
-       isc_async_run(qpdb->loop, prune_tree, prune);
-}
-
 /*%
  * Clean up dead nodes.  These are nodes which have no references, and
  * have no data.  They are dead but we could not or chose not to delete
@@ -1179,24 +1156,8 @@ cleanup_dead_nodes(dns_qpdb_t *qpdb, int bucketnum DNS__DB_FLARG) {
                        continue;
                }
 
-               if (is_leaf(node) && qpdb->loop != NULL) {
-                       send_to_prune_tree(
-                               qpdb, node,
-                               isc_rwlocktype_write DNS__DB_FLARG_PASS);
-               } else if (node->down == NULL && node->data == NULL) {
-                       /*
-                        * Not a interior node and not needing to be
-                        * reactivated.
-                        */
-                       delete_node(qpdb, node);
-               } else if (node->data == NULL) {
-                       /*
-                        * A interior node without data. Leave linked to
-                        * to be cleaned up when node->down becomes NULL.
-                        */
-                       ISC_LIST_APPEND(qpdb->deadnodes[bucketnum], node,
-                                       deadlink);
-               }
+               delete_node(qpdb, node);
+
                node = ISC_LIST_HEAD(qpdb->deadnodes[bucketnum]);
                count--;
        }
@@ -1284,14 +1245,16 @@ dns__qpdb_decref(dns_qpdb_t *qpdb, dns_qpdata_t *node, uint32_t least_serial,
 
        REQUIRE(*nlocktypep != isc_rwlocktype_none);
 
+       UNUSED(pruning);
+
        nodelock = &qpdb->node_locks[bucket];
 
-#define KEEP_NODE(n, r, l)                                  \
-       ((n)->data != NULL || ((l) && (n)->down != NULL) || \
-        (n) == (r)->origin_node || (n) == (r)->nsec3_origin_node)
+#define KEEP_NODE(n, r)                                  \
+       ((n)->data != NULL || (n) == (r)->origin_node || \
+        (n) == (r)->nsec3_origin_node)
 
        /* Handle easy and typical case first. */
-       if (!node->dirty && KEEP_NODE(node, qpdb, locked)) {
+       if (!node->dirty && KEEP_NODE(node, qpdb)) {
                refs = isc_refcount_decrement(&node->erefs);
 
 #if DNS_DB_NODETRACE
@@ -1397,7 +1360,7 @@ dns__qpdb_decref(dns_qpdb_t *qpdb, dns_qpdata_t *node, uint32_t least_serial,
        UNUSED(refs);
 #endif
 
-       if (KEEP_NODE(node, qpdb, (locked || write_locked))) {
+       if (KEEP_NODE(node, qpdb)) {
                goto restore_locks;
        }
 
@@ -1405,31 +1368,9 @@ dns__qpdb_decref(dns_qpdb_t *qpdb, dns_qpdata_t *node, uint32_t least_serial,
 
        if (write_locked) {
                /*
-                * If this node is the only one in the level it's in, deleting
-                * this node may recursively make its parent the only node in
-                * the parent level; if so, and if no one is currently using
-                * the parent node, this is almost the only opportunity to
-                * clean it up.  But the recursive cleanup is not that trivial
-                * since the child and parent may be in different lock buckets,
-                * which would cause a lock order reversal problem.  To avoid
-                * the trouble, we'll dispatch a separate event for batch
-                * cleaning.  We need to check whether we're deleting the node
-                * as a result of pruning to avoid infinite dispatching.
-                * Note: pruning happens only when a loop has been set for the
-                * qpdb.  If the user of the qpdb chooses not to set a loop,
-                * it's their responsibility to purge stale leaves (e.g. by
-                * periodic walk-through).
+                * We can now delete the node.
                 */
-
-               if (!pruning && is_leaf(node) && qpdb->loop != NULL) {
-                       send_to_prune_tree(qpdb, node,
-                                          *nlocktypep DNS__DB_FLARG_PASS);
-                       no_reference = false;
-               } else {
-                       /*  We can now delete the node. */
-
-                       delete_node(qpdb, node);
-               }
+               delete_node(qpdb, node);
        } else {
                INSIST(node->data == NULL);
                if (!ISC_LINK_LINKED(node, deadlink)) {
@@ -1450,46 +1391,6 @@ restore_locks:
        return (no_reference);
 }
 
-/*
- * Prune the tree by cleaning up single leaves.  A single execution of this
- * function cleans up a single node; if the parent of the latter becomes a
- * single leaf on its own level as a result, the parent is then also sent to
- * this function.
- */
-static void
-prune_tree(void *arg) {
-       qpdb_prune_t *prune = (qpdb_prune_t *)arg;
-       dns_qpdb_t *qpdb = (dns_qpdb_t *)prune->db;
-       dns_qpdata_t *node = prune->node;
-       dns_qpdata_t *parent = NULL;
-       unsigned int locknum = node->locknum;
-       isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
-       isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
-
-       isc_mem_put(qpdb->common.mctx, prune, sizeof(*prune));
-
-       TREE_WRLOCK(&qpdb->tree_lock, &tlocktype);
-
-       parent = node->parent;
-
-       NODE_WRLOCK(&qpdb->node_locks[locknum].lock, &nlocktype);
-       dns__qpdb_decref(qpdb, node, 0, &nlocktype, &tlocktype, true,
-                        true DNS__DB_FILELINE);
-       NODE_UNLOCK(&qpdb->node_locks[locknum].lock, &nlocktype);
-
-       if (parent != NULL && is_leaf(parent)) {
-               NODE_WRLOCK(&qpdb->node_locks[parent->locknum].lock,
-                           &nlocktype);
-               send_to_prune_tree(qpdb, parent, nlocktype);
-               NODE_UNLOCK(&qpdb->node_locks[parent->locknum].lock,
-                           &nlocktype);
-       }
-
-       TREE_UNLOCK(&qpdb->tree_lock, &tlocktype);
-
-       dns_db_detach((dns_db_t **)&qpdb);
-}
-
 static void
 make_least_version(dns_qpdb_t *qpdb, dns_qpdb_version_t *version,
                   qpdb_changedlist_t *cleanup_list) {
index 4239419cbe3efa39f50bb9e568f2b4bb7d267118..23c38243e10a4ed831a572306b04871cf1c322e7 100644 (file)
@@ -86,18 +86,9 @@ struct dns_qpdata {
        /*@}*/
 
        /*%
-        * These are needed for hashing. The 'uppernode' points to the
-        * node's superdomain node in the parent subtree, so that it can
-        * be reached from a child that was found by a hash lookup.
+        * This is needed for hashing.
         */
        unsigned int hashval;
-       dns_qpdata_t *uppernode;
-       dns_qpdata_t *hashnext;
-
-       dns_qpdata_t *parent;
-       dns_qpdata_t *left;
-       dns_qpdata_t *right;
-       dns_qpdata_t *down;
 
        dns_fixedname_t fn;
        dns_name_t *name;