diff options
Diffstat (limited to 'src/libknot/zone/node.c')
-rw-r--r-- | src/libknot/zone/node.c | 343 |
1 files changed, 185 insertions, 158 deletions
diff --git a/src/libknot/zone/node.c b/src/libknot/zone/node.c index eca4abc..5ebdb0e 100644 --- a/src/libknot/zone/node.c +++ b/src/libknot/zone/node.c @@ -25,7 +25,6 @@ #include "zone/node.h" #include "rrset.h" #include "common/skip-list.h" -#include "common/tree.h" #include "util/debug.h" /*----------------------------------------------------------------------------*/ @@ -127,28 +126,6 @@ static inline uint8_t knot_node_flags_get_empty(uint8_t flags) } /*----------------------------------------------------------------------------*/ -/*! - * \brief Compares the two keys as RR types. - * - * \note This function may be used in data structures requiring generic - * comparation function. - * - * \param key1 First RR type. - * \param key2 Second RR type. - * - * \retval 0 if \a key1 is equal to \a key2. - * \retval < 0 if \a key1 is lower than \a key2. - * \retval > 0 if \a key1 is higher than \a key2. - */ -static int compare_rrset_types(void *rr1, void *rr2) -{ - knot_rrset_t *rrset1 = (knot_rrset_t *)rr1; - knot_rrset_t *rrset2 = (knot_rrset_t *)rr2; - return ((rrset1->type > rrset2->type) ? 1 : - (rrset1->type == rrset2->type) ? 0 : -1); -} - -/*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ @@ -165,58 +142,69 @@ knot_node_t *knot_node_new(knot_dname_t *owner, knot_node_t *parent, knot_dname_retain(owner); ret->owner = owner; knot_node_set_parent(ret, parent); - ret->rrset_tree = gen_tree_new(compare_rrset_types); + ret->rrset_tree = NULL; ret->flags = flags; - + assert(ret->children == 0); return ret; } -/*----------------------------------------------------------------------------*/ -/*! \todo Consider replacing rrset_merge() with rrset_merge_no_dupl(). Currently - * this function is never called with merge=1, so it's not a problem, - * but it may be in the future. - */ -int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset, - int merge) + +int knot_node_add_rrset_no_merge(knot_node_t *node, knot_rrset_t *rrset) { if (node == NULL) { return KNOT_EINVAL; } - int ret = 0; + size_t nlen = (node->rrset_count + 1) * sizeof(knot_rrset_t*); + void *p = realloc(node->rrset_tree, nlen); + if (p == NULL) { + return KNOT_ENOMEM; + } + node->rrset_tree = p; + node->rrset_tree[node->rrset_count] = rrset; + ++node->rrset_count; + return KNOT_EOK; +} - if ((ret = (gen_tree_add(node->rrset_tree, rrset, - (merge) ? knot_rrset_merge : NULL))) < 0) { - dbg_node("Failed to add rrset to node->rrset_tree.\n"); - return KNOT_ERROR; +int knot_node_add_rrset_replace(knot_node_t *node, knot_rrset_t *rrset) +{ + if (node == NULL) { + return KNOT_EINVAL; } - if (ret >= 0) { - node->rrset_count += (ret > 0 ? 0 : 1); - return ret; - } else { - return KNOT_ERROR; + for (uint16_t i = 0; i < node->rrset_count; ++i) { + if (node->rrset_tree[i]->type == rrset->type) { + node->rrset_tree[i] = rrset; + } } + + return knot_node_add_rrset_no_merge(node, rrset); } -int knot_node_add_rrset_no_dupl(knot_node_t *node, knot_rrset_t *rrset) +int knot_node_add_rrset(knot_node_t *node, knot_rrset_t *rrset) { - int ret = 0; - - if ((ret = (gen_tree_add(node->rrset_tree, rrset, - knot_rrset_merge_no_dupl))) < 0) { - dbg_node("Failed to add rrset to node->rrset_tree.\n"); - return KNOT_ERROR; + if (node == NULL) { + return KNOT_EINVAL; } - if (ret >= 0) { - node->rrset_count += (ret > 0 ? 0 : 1); - return ret; - } else { - return KNOT_ERROR; + for (uint16_t i = 0; i < node->rrset_count; ++i) { + if (node->rrset_tree[i]->type == rrset->type) { + int merged, deleted_rrs; + int ret = knot_rrset_merge_no_dupl(node->rrset_tree[i], + rrset, &merged, &deleted_rrs); + if (ret != KNOT_EOK) { + return ret; + } else if (merged || deleted_rrs) { + return 1; + } else { + return 0; + } + } } + + return knot_node_add_rrset_no_merge(node, rrset); } /*----------------------------------------------------------------------------*/ @@ -224,14 +212,7 @@ int knot_node_add_rrset_no_dupl(knot_node_t *node, knot_rrset_t *rrset) const knot_rrset_t *knot_node_rrset(const knot_node_t *node, uint16_t type) { - if (node == NULL) { - return NULL; - } - - assert(node->rrset_tree != NULL); - knot_rrset_t rrset; - rrset.type = type; - return (const knot_rrset_t *)gen_tree_find(node->rrset_tree, &rrset); + return knot_node_get_rrset(node, type); } /*----------------------------------------------------------------------------*/ @@ -242,9 +223,14 @@ knot_rrset_t *knot_node_get_rrset(const knot_node_t *node, uint16_t type) return NULL; } - knot_rrset_t rrset; - rrset.type = type; - return (knot_rrset_t *)gen_tree_find(node->rrset_tree, &rrset); + knot_rrset_t **rrs = node->rrset_tree; + for (uint16_t i = 0; i < node->rrset_count; ++i) { + if (rrs[i]->type == type) { + return rrs[i]; + } + } + + return NULL; } /*----------------------------------------------------------------------------*/ @@ -255,15 +241,24 @@ knot_rrset_t *knot_node_remove_rrset(knot_node_t *node, uint16_t type) return NULL; } - knot_rrset_t dummy_rrset; - dummy_rrset.type = type; - knot_rrset_t *rrset = - (knot_rrset_t *)gen_tree_find(node->rrset_tree, &dummy_rrset); - if (rrset != NULL) { - gen_tree_remove(node->rrset_tree, rrset); - node->rrset_count--; + uint16_t i = 0; + knot_rrset_t *ret = NULL; + knot_rrset_t **rrs = node->rrset_tree; + for (; i < node->rrset_count && ret == NULL; ++i) { + if (rrs[i]->type == type) { + ret = rrs[i]; + memmove(rrs + i, rrs + i + 1, (node->rrset_count - i - 1) * sizeof(knot_rrset_t *)); + --node->rrset_count; + } } - return rrset; + + /*!< \todo I've added this to fix a leak, but probably this wasn't the cause. Remove once tests are availabe. */ + void *tmp = realloc(node->rrset_tree, + node->rrset_count * sizeof(knot_rrset_t *)); + assert(tmp || node->rrset_count == 0); //Realloc to smaller memory, if it fails, something is really odd. + node->rrset_tree = tmp; + + return ret; } /*----------------------------------------------------------------------------*/ @@ -275,9 +270,7 @@ void knot_node_remove_all_rrsets(knot_node_t *node) } // remove RRSets but do not delete them - gen_tree_clear(node->rrset_tree); node->rrset_count = 0; - } /*----------------------------------------------------------------------------*/ @@ -301,40 +294,19 @@ struct knot_node_save_rrset_arg { /*----------------------------------------------------------------------------*/ -static void save_rrset_to_array(void *node, void *data) -{ - struct knot_node_save_rrset_arg *args = - (struct knot_node_save_rrset_arg *)data; - knot_rrset_t *rrset = (knot_rrset_t *)node; - - if (args->count > args->max_count) { - ++args->count; - return; - } - - args->array[args->count++] = rrset; -} - -/*----------------------------------------------------------------------------*/ - knot_rrset_t **knot_node_get_rrsets(const knot_node_t *node) { if (node == NULL || node->rrset_count == 0) { return NULL; } - knot_rrset_t **rrsets = (knot_rrset_t **)malloc( - node->rrset_count * sizeof(knot_rrset_t *)); - CHECK_ALLOC_LOG(rrsets, NULL); - struct knot_node_save_rrset_arg args; - args.array = rrsets; - args.count = 0; - args.max_count = node->rrset_count; - gen_tree_apply_inorder(node->rrset_tree, save_rrset_to_array, &args); - - assert(args.count == node->rrset_count); + size_t rrlen = node->rrset_count * sizeof(knot_rrset_t*); + knot_rrset_t **cpy = malloc(rrlen); + if (cpy != NULL) { + memcpy(cpy, node->rrset_tree, rrlen); + } - return rrsets; + return cpy; } /*----------------------------------------------------------------------------*/ @@ -348,31 +320,21 @@ const knot_rrset_t **knot_node_rrsets(const knot_node_t *node) return (const knot_rrset_t **)knot_node_get_rrsets(node); } -/*----------------------------------------------------------------------------*/ - -static void count_rrsets(void *node, void *data) -{ - assert(node != NULL); - assert(data != NULL); - - int *count = (int *)data; - ++(*count); -} - -/*----------------------------------------------------------------------------*/ - -int knot_node_count_rrsets(const knot_node_t *node) +knot_rrset_t **knot_node_get_rrsets_no_copy(const knot_node_t *node) { if (node == NULL) { - return KNOT_EINVAL; + return NULL; } - int count = 0; - gen_tree_apply_inorder(node->rrset_tree, count_rrsets, (void *)&count); + return node->rrset_tree; +} - return count; +const knot_rrset_t **knot_node_rrsets_no_copy(const knot_node_t *node) +{ + return (const knot_rrset_t **)knot_node_get_rrsets_no_copy(node); } + /*----------------------------------------------------------------------------*/ const knot_node_t *knot_node_parent(const knot_node_t *node) @@ -409,7 +371,7 @@ void knot_node_set_parent(knot_node_t *node, knot_node_t *parent) } // set the parent node->parent = parent; - + // increase the count of children of the new parent if (parent != NULL) { ++parent->children; @@ -445,7 +407,7 @@ knot_node_t *knot_node_get_previous(const knot_node_t *node) if (node == NULL) { return NULL; } - + return node->prev; } @@ -467,7 +429,7 @@ knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node) if (node == NULL) { return NULL; } - + return node->nsec3_node; } @@ -491,9 +453,6 @@ void knot_node_set_nsec3_node(knot_node_t *node, knot_node_t *nsec3_node) } node->nsec3_node = nsec3_node; - if (nsec3_node != NULL) { - nsec3_node->nsec3_referer = node; - } } /*----------------------------------------------------------------------------*/ @@ -638,8 +597,6 @@ void knot_node_update_refs(knot_node_t *node) knot_node_update_ref(&node->wildcard_child); // reference to NSEC3 node knot_node_update_ref(&node->nsec3_node); - // reference to NSEC3 referrer - knot_node_update_ref(&node->nsec3_referer); } /*----------------------------------------------------------------------------*/ @@ -725,29 +682,16 @@ void knot_node_set_empty(knot_node_t *node) /*----------------------------------------------------------------------------*/ -static void knot_node_free_rrsets_from_tree(void *item, void *data) -{ - if (item == NULL) { - return; - } - - knot_rrset_t *rrset = (knot_rrset_t *)(item); - knot_rrset_deep_free(&rrset, 0, 1, *((int *)data)); -} - -/*----------------------------------------------------------------------------*/ - void knot_node_free_rrsets(knot_node_t *node, int free_rdata_dnames) { if (node == NULL) { return; } - char *name = knot_dname_to_str(node->owner); - free(name); - - gen_tree_destroy(&node->rrset_tree, knot_node_free_rrsets_from_tree, - (void *)&free_rdata_dnames); + knot_rrset_t **rrs = node->rrset_tree; + for (uint16_t i = 0; i < node->rrset_count; ++i) { + knot_rrset_deep_free(&(rrs[i]), 1, free_rdata_dnames); + } } /*----------------------------------------------------------------------------*/ @@ -757,12 +701,14 @@ void knot_node_free(knot_node_t **node) if (node == NULL || *node == NULL) { return; } - + dbg_node_detail("Freeing node: %p\n", *node); if ((*node)->rrset_tree != NULL) { dbg_node_detail("Freeing RRSets.\n"); - gen_tree_destroy(&(*node)->rrset_tree, NULL, NULL); + free((*node)->rrset_tree); + (*node)->rrset_tree = NULL; + (*node)->rrset_count = 0; } // set owner's node pointer to NULL, but only if the 'node' does @@ -772,7 +718,6 @@ void knot_node_free(knot_node_t **node) knot_dname_set_node((*node)->owner, NULL); } - dbg_node_detail("Releasing owner.\n"); knot_dname_release((*node)->owner); free(*node); @@ -804,25 +749,107 @@ int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to) return KNOT_ENOMEM; } - // set the parent by hand, so that the children count is not affected - (*to)->parent = from->parent; - - /* Free old rrset_tree, as it will be replaced by shallow copy. */ - gen_tree_destroy(&(*to)->rrset_tree, 0, 0); - - // copy references - // do not use the API function to set parent, so that children count + // copy references + // do not use the API function to set parent, so that children count // is not changed memcpy(*to, from, sizeof(knot_node_t)); // copy RRSets - (*to)->rrset_tree = gen_tree_shallow_copy(from->rrset_tree); - + size_t rrlen = sizeof(knot_rrset_t*) * from->rrset_count; + (*to)->rrset_tree = malloc(rrlen); if ((*to)->rrset_tree == NULL) { free(*to); *to = NULL; return KNOT_ENOMEM; } + memcpy((*to)->rrset_tree, from->rrset_tree, rrlen); return KNOT_EOK; } + +//const knot_node_t *knot_node_current(const knot_node_t *node) +//{ +// if (node == NULL || node->zone == NULL +// || knot_zone_contents(node->zone) == NULL) { +// return node; +// } + +// int new_gen = knot_node_zone_gen_is_new(node); +// int old_gen = knot_node_zone_gen_is_old(node); +//// short ver = knot_node_zone_generation(node); + +// if (old_gen && knot_node_is_new(node)) { +// return NULL; +// } else if (new_gen && knot_node_is_old(node)) { +// assert(node->new_node != NULL); +// return node->new_node; +// } +// return node; +//} + +///*----------------------------------------------------------------------------*/ + +//knot_node_t *knot_node_get_current(knot_node_t *node) +//{ +// if (node == NULL || node->zone == NULL +// || knot_zone_contents(node->zone) == NULL) { +// return node; +// } + +// int new_gen = knot_node_zone_gen_is_new(node); +// int old_gen = knot_node_zone_gen_is_old(node); +//// short ver = knot_node_zone_generation(node); + +// if (old_gen && knot_node_is_new(node)) { +// return NULL; +// } else if (new_gen && knot_node_is_old(node)) { +// assert(node->new_node != NULL); +// return node->new_node; +// } + +// assert((old_gen && knot_node_is_old(node)) +// || (new_gen && knot_node_is_new(node)) +// || (!old_gen && !new_gen)); + +// return node; +//} + +//int knot_node_is_new(const knot_node_t *node) +//{ +// return knot_node_flags_get_new(node->flags); +//} + +///*----------------------------------------------------------------------------*/ + +//int knot_node_is_old(const knot_node_t *node) +//{ +// return knot_node_flags_get_old(node->flags); +//} + +///*----------------------------------------------------------------------------*/ + +//void knot_node_set_new(knot_node_t *node) +//{ +// knot_node_flags_set_new(&node->flags); +//} + +///*----------------------------------------------------------------------------*/ + +//void knot_node_set_old(knot_node_t *node) +//{ +// knot_node_flags_set_old(&node->flags); +//} + +///*----------------------------------------------------------------------------*/ + +//void knot_node_clear_new(knot_node_t *node) +//{ +// knot_node_flags_clear_new(&node->flags); +//} + +///*----------------------------------------------------------------------------*/ + +//void knot_node_clear_old(knot_node_t *node) +//{ +// knot_node_flags_clear_old(&node->flags); +//} |