Commit 5b07a33a authored by Dominik Taborsky's avatar Dominik Taborsky

contents/tree: cleanup, move and improve removing an empty node

parent d9a8a828
......@@ -60,38 +60,6 @@ static int free_additional(zone_node_t **node, void *data)
return KNOT_EOK;
}
/* ------------------------- Empty node cleanup ----------------------------- */
/*! \brief Clears wildcard child if set in parent node. */
static void fix_wildcard_child(zone_node_t *node, const knot_dname_t *owner)
{
if ((node->flags & NODE_FLAGS_WILDCARD_CHILD)
&& knot_dname_is_wildcard(owner)) {
node->flags &= ~NODE_FLAGS_WILDCARD_CHILD;
}
}
/*! \todo move this to new zone API - zone should do this automatically. */
/*! \brief Deletes possibly empty node and all its empty parents recursively. */
static void delete_empty_node(zone_tree_t *tree, zone_node_t *node)
{
if (node->rrset_count == 0 && node->children == 0) {
zone_node_t *parent_node = node->parent;
if (parent_node) {
fix_wildcard_child(parent_node, node->owner);
parent_node->children--;
// Recurse using the parent node
delete_empty_node(tree, parent_node);
}
// Delete node
zone_node_t *removed_node = NULL;
zone_tree_remove(tree, node->owner, &removed_node);
UNUSED(removed_node);
node_free(&node, NULL);
}
}
/* -------------------- Changeset application helpers ----------------------- */
/*! \brief Replaces rdataset of given type with a copy. */
......@@ -229,7 +197,7 @@ static int remove_rr(apply_ctx_t *ctx, zone_tree_t *tree, zone_node_t *node,
node_remove_rdataset(node, rr->type);
// If node is empty now, delete it from zone tree.
if (node->rrset_count == 0) {
delete_empty_node(tree, node);
zone_tree_delete_empty_node(tree, node);
}
}
......
......@@ -168,7 +168,7 @@ static bool need_to_insert(zone_contents_t *counterpart, const knot_rrset_t *rr)
// Remove empty node.
zone_tree_t *t = knot_rrset_is_nsec3rel(rr) ?
counterpart->nsec3_nodes : counterpart->nodes;
zone_contents_delete_empty_node(counterpart, t, node);
zone_tree_delete_empty_node(t, node);
}
}
......
......@@ -659,12 +659,6 @@ static zone_node_t *get_previous(const zone_contents_t *zone,
return prev;
}
static bool contents_has_children(const zone_contents_t *zone, const knot_dname_t *owner)
{
zone_node_t *parent = get_node(zone, owner);
return parent->children > 0;
}
// Public API
int zone_contents_add_rr(zone_contents_t *z, const knot_rrset_t *rr,
......@@ -700,32 +694,6 @@ zone_node_t *zone_contents_get_node_for_rr(zone_contents_t *zone, const knot_rrs
}
}
int zone_contents_delete_empty_node(zone_contents_t *contents, zone_tree_t *tree, zone_node_t *node)
{
if (!contents || !tree || !node) {
return KNOT_EINVAL;
}
if (node->rrset_count == 0 && !contents_has_children(contents, node->owner)) {
zone_node_t *parent_node = node->parent;
if (parent_node && parent_node != contents->apex) {
// Recurse using the parent node, do not delete possibly empty parent.
int ret = zone_contents_delete_empty_node(contents, tree, parent_node);
if (ret != KNOT_EOK) {
return ret;
}
}
// Delete node
zone_node_t *removed_node = NULL;
zone_tree_remove(tree, node->owner, &removed_node);
UNUSED(removed_node);
node_free(&node, NULL);
}
return KNOT_EOK;
}
const zone_node_t *zone_contents_find_node(const zone_contents_t *zone, const knot_dname_t *name)
{
return get_node(zone, name);
......
......@@ -77,17 +77,6 @@ int zone_contents_add_rr(zone_contents_t *z, const knot_rrset_t *rr, zone_node_t
*/
zone_node_t *zone_contents_get_node_for_rr(zone_contents_t *zone, const knot_rrset_t *rrset);
/*!
* \brief Delete a node that has no RRSets and no children.
*
* \param contents Contents to delete from.
* \param tree The tree to remove from.
* \param node The node to remove.
*
* \return KNOT_E*.
*/
int zone_contents_delete_empty_node(zone_contents_t *contents, zone_tree_t *tree, zone_node_t *node);
/*!
* \brief Tries to find a node with the specified name in the zone.
*
......
......@@ -213,6 +213,45 @@ int zone_tree_remove(zone_tree_t *tree,
return KNOT_EOK;
}
/*! \brief Clears wildcard child if set in parent node. */
static void fix_wildcard_child(zone_node_t *node, const knot_dname_t *owner)
{
if ((node->flags & NODE_FLAGS_WILDCARD_CHILD)
&& knot_dname_is_wildcard(owner)) {
node->flags &= ~NODE_FLAGS_WILDCARD_CHILD;
}
}
int zone_tree_delete_empty_node(zone_tree_t *tree, zone_node_t *node)
{
if (!tree || !node) {
return KNOT_EINVAL;
}
if (node->rrset_count == 0 && node->children == 0) {
zone_node_t *parent_node = node->parent;
if (parent_node) {
parent_node->children--;
fix_wildcard_child(parent_node, node->owner);
if (parent_node->parent != NULL) { /* Is not apex */
// Recurse using the parent node, do not delete possibly empty parent.
int ret = zone_tree_delete_empty_node(tree, parent_node);
if (ret != KNOT_EOK) {
return ret;
}
}
}
// Delete node
zone_node_t *removed_node = NULL;
zone_tree_remove(tree, node->owner, &removed_node);
UNUSED(removed_node);
node_free(&node, NULL);
}
return KNOT_EOK;
}
int zone_tree_apply_inorder(zone_tree_t *tree,
zone_tree_apply_cb_t function,
void *data)
......
......@@ -164,6 +164,16 @@ int zone_tree_remove(zone_tree_t *tree,
const knot_dname_t *owner,
zone_node_t **removed);
/*!
* \brief Delete a node that has no RRSets and no children.
*
* \param tree The tree to remove from.
* \param node The node to remove.
*
* \return KNOT_E*.
*/
int zone_tree_delete_empty_node(zone_tree_t *tree, zone_node_t *node);
/*!
* \brief Applies the given function to each node in the zone.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment