Skip to content
Snippets Groups Projects
Commit b16c17f9 authored by Jan Kadlec's avatar Jan Kadlec
Browse files

More changes in node and tree.

Zonedb mofified - it compiles, will test it tommorow.
parent d269ffb8
Branches
Tags
No related merge requests found
......@@ -98,6 +98,20 @@ void *gen_tree_find(general_tree_t *tree,
}
}
int gen_tree_find_less_or_equal(general_tree_t *tree,
void *what,
void **found)
{
struct general_tree_node *f, *prev;
struct general_tree_node tree_node;
tree_node.data = what;
int exact_match =
MOD_TREE_FIND_LESS_EQUAL(tree->tree, general_tree_node, avl,
&tree_node, &f, &prev);
*found = (exact_match > 0) ? f->data : NULL;
return exact_match;
}
void gen_tree_apply_inorder(general_tree_t *tree,
void (*app_func)
(void *node, void *data), void *data)
......@@ -106,3 +120,12 @@ void gen_tree_apply_inorder(general_tree_t *tree,
app_func, data);
}
void gen_tree_destroy(general_tree_t **tree,
void (*dest_func)(void *node, void *data), void *data)
{
MOD_TREE_DESTROY((*tree)->tree, general_tree_node, avl, dest_func,
gen_rem_func, data);
free(*tree);
*tree = NULL;
}
......@@ -44,6 +44,10 @@ void gen_tree_apply_inorder(general_tree_t *tree,
void *data);
void gen_tree_destroy(general_tree_t **tree,
void (*dest_func)(void *node, void *data));
void (*dest_func)(void *node, void *data), void *data);
int gen_tree_find_less_or_equal(general_tree_t *tree,
void *what,
void **found);
#endif // _KNOT_COMMON_GENERAL_TREE_H_
......@@ -227,6 +227,19 @@
function(self, data); \
} \
} \
\
void MOD_TREE_DESTROY_ALL_##node##_##field \
(struct node *self, void (*function)(struct node *node, void *data), void(*dest)(struct node *node), void *data) \
{ \
if (self) \
{ \
MOD_TREE_POST_ORDER_APPLY_ALL_##node##_##field(self->field.avl_left, function, data); \
MOD_TREE_POST_ORDER_APPLY_ALL_##node##_##field(self->field.avl_right, function, data); \
if (function != NULL) \
function(self->data, data); \
dest(self); \
} \
} \
\
void MOD_TREE_REVERSE_APPLY_POST_ALL_##node##_##field \
(struct node *self, void (*function)(struct node *node, void *data), void *data) \
......@@ -263,6 +276,9 @@
#define MOD_TREE_POST_ORDER_APPLY(head, node, field, function, data) \
MOD_TREE_POST_ORDER_APPLY_ALL_##node##_##field((head)->th_root, function, data)
#define MOD_TREE_DESTROY(head, node, field, function, dest, data) \
MOD_TREE_DESTROY_ALL_##node##_##field((head)->th_root, function, dest, data)
#define MOD_TREE_REVERSE_APPLY_POST(head, node, field, function, data) \
MOD_TREE_REVERSE_APPLY_POST_ALL_##node##_##field((head)->th_root, function, data)
......
......@@ -723,81 +723,73 @@ void dnslib_node_clear_old(dnslib_node_t *node)
void dnslib_node_free_rrsets(dnslib_node_t *node, int free_rdata_dnames)
{
// const skip_node_t *skip_node =
// (skip_node_t *)skip_first(node->rrsets);
// if (skip_node != NULL) {
// dnslib_rrset_deep_free((dnslib_rrset_t **)(&skip_node->value), 0,
// 1, free_rdata_dnames);
// while ((skip_node = skip_next(skip_node)) != NULL) {
// dnslib_rrset_deep_free((dnslib_rrset_t **)
// (&skip_node->value), 0,
// 1, free_rdata_dnames);
// }
// }
dnslib_rrset_t **rrsets = dnslib_node_get_rrsets(node);
for (int i = 0; i < node->rrset_count; i++) {
dnslib_rrset_deep_free(&(rrsets[i]), 0, 1, free_rdata_dnames);
}
// skip_destroy_list(&node->rrsets, NULL, NULL);
// node->rrsets = NULL;
gen_tree_destroy(&node->rrset_tree, NULL, NULL);
assert(node->rrset_tree == NULL);
}
/*----------------------------------------------------------------------------*/
void dnslib_node_free(dnslib_node_t **node, int free_owner, int fix_refs)
{
// debug_dnslib_node("Freeing node.\n");
// if ((*node)->rrsets != NULL) {
// debug_dnslib_node("Freeing RRSets.\n");
// skip_destroy_list(&(*node)->rrsets, NULL, NULL);
// }
// if (free_owner) {
// debug_dnslib_node("Freeing owner.\n");
// dnslib_dname_free(&(*node)->owner);
// }
debug_dnslib_node("Freeing node.\n");
if ((*node)->rrset_tree != NULL) {
debug_dnslib_node("Freeing RRSets.\n");
gen_tree_destroy(&(*node)->rrset_tree, NULL, NULL);
}
if (free_owner) {
debug_dnslib_node("Freeing owner.\n");
dnslib_dname_free(&(*node)->owner);
}
// check nodes referencing this node and fix the references
// // check nodes referencing this node and fix the references
// if (fix_refs) {
// // previous node
// debug_dnslib_node("Checking previous.\n");
// if ((*node)->prev && (*node)->prev->next == (*node)) {
// (*node)->prev->next = (*node)->next;
// }
// debug_dnslib_node("Checking next.\n");
// if ((*node)->next && (*node)->next->prev == (*node)) {
// (*node)->next->prev = (*node)->prev;
// }
// // NSEC3 node
// debug_dnslib_node("Checking NSEC3.\n");
// if ((*node)->nsec3_node
// && (*node)->nsec3_node->nsec3_referer == (*node)) {
// (*node)->nsec3_node->nsec3_referer = NULL;
// }
// debug_dnslib_node("Checking NSEC3 ref.\n");
// if ((*node)->nsec3_referer
// && (*node)->nsec3_referer->nsec3_node == (*node)) {
// (*node)->nsec3_referer->nsec3_node = NULL;
// }
// // wildcard child node
// debug_dnslib_node("Checking parent's wildcard child.\n");
// if ((*node)->parent
// && (*node)->parent->wildcard_child == (*node)) {
// (*node)->parent->wildcard_child = NULL;
// }
if (fix_refs) {
// previous node
debug_dnslib_node("Checking previous.\n");
if ((*node)->prev && (*node)->prev->next == (*node)) {
(*node)->prev->next = (*node)->next;
}
debug_dnslib_node("Checking next.\n");
if ((*node)->next && (*node)->next->prev == (*node)) {
(*node)->next->prev = (*node)->prev;
}
// NSEC3 node
debug_dnslib_node("Checking NSEC3.\n");
if ((*node)->nsec3_node
&& (*node)->nsec3_node->nsec3_referer == (*node)) {
(*node)->nsec3_node->nsec3_referer = NULL;
}
debug_dnslib_node("Checking NSEC3 ref.\n");
if ((*node)->nsec3_referer
&& (*node)->nsec3_referer->nsec3_node == (*node)) {
(*node)->nsec3_referer->nsec3_node = NULL;
}
// wildcard child node
debug_dnslib_node("Checking parent's wildcard child.\n");
if ((*node)->parent
&& (*node)->parent->wildcard_child == (*node)) {
(*node)->parent->wildcard_child = NULL;
}
// // fix parent's children count
// if ((*node)->parent) {
// --(*node)->parent->children;
// }
// }
// fix parent's children count
if ((*node)->parent) {
--(*node)->parent->children;
}
}
// free(*node);
// *node = NULL;
free(*node);
*node = NULL;
// debug_dnslib_node("Done.\n");
debug_dnslib_node("Done.\n");
}
/*----------------------------------------------------------------------------*/
......
......@@ -11,7 +11,7 @@
#include "dnslib/node.h"
#include "dnslib/error.h"
#include "dnslib/debug.h"
#include "common/skip-list.h"
#include "common/general-tree.h"
/*----------------------------------------------------------------------------*/
/* Non-API functions */
......@@ -28,16 +28,16 @@
* \retval < 0 if \a d1 is before \a d2 in canonical order.
* \retval > 0 if \a d1 is after \a d2 in canonical order.
*/
static int dnslib_zonedb_compare_zone_names(void *d1, void *d2)
static int dnslib_zonedb_compare_zone_names(void *p1, void *p2)
{
const dnslib_dname_t *dname1 = (const dnslib_dname_t *)d1;
const dnslib_dname_t *dname2 = (const dnslib_dname_t *)d2;
const dnslib_zone_t *zone1 = (const dnslib_zone_t *)p1;
const dnslib_zone_t *zone2 = (const dnslib_zone_t *)p2;
int ret = dnslib_dname_compare(dname1, dname2);
int ret = dnslib_dname_compare(zone1->name, zone2->name);
DEBUG_DNSLIB_ZONEDB(
char *name1 = dnslib_dname_to_str(dname1);
char *name2 = dnslib_dname_to_str(dname2);
char *name1 = dnslib_dname_to_str(zone1->name);
char *name2 = dnslib_dname_to_str(zone2->name);
debug_dnslib_zonedb("Compared names %s and %s, result: %d.\n",
name1, name2, ret);
free(name1);
......@@ -74,8 +74,9 @@ dnslib_zonedb_t *dnslib_zonedb_new()
(dnslib_zonedb_t *)malloc(sizeof(dnslib_zonedb_t));
CHECK_ALLOC_LOG(db, NULL);
db->zones = skip_create_list(dnslib_zonedb_compare_zone_names);
if (db->zones == NULL) {
db->zone_tree = gen_tree_new(dnslib_zonedb_compare_zone_names,
NULL);
if (db->zone_tree == NULL) {
free(db);
return NULL;
}
......@@ -102,8 +103,8 @@ DEBUG_DNSLIB_ZONEDB(
return ret;
}
ret = skip_insert(db->zones, zone->name, zone, NULL);
assert(ret == 0 || ret == 1 || ret == -1);
ret = gen_tree_add(db->zone_tree, zone);
return (ret != 0) ? DNSLIB_EZONEIN : DNSLIB_EOK;
}
......@@ -112,16 +113,18 @@ DEBUG_DNSLIB_ZONEDB(
int dnslib_zonedb_remove_zone(dnslib_zonedb_t *db, dnslib_dname_t *zone_name,
int destroy_zone)
{
dnslib_zone_t dummy_zone;
dummy_zone.name = zone_name;
// add some lock to avoid multiple removals
dnslib_zone_t *z = (dnslib_zone_t *)skip_find(db->zones, zone_name);
dnslib_zone_t *z = (dnslib_zone_t *)gen_tree_find(db->zone_tree,
&dummy_zone);
if (z == NULL) {
return DNSLIB_ENOZONE;
}
// remove the zone from the skip list, but do not destroy it
int ret = skip_remove(db->zones, zone_name, NULL, NULL);
assert(ret == 0);
gen_tree_remove(db->zone_tree, &dummy_zone);
if (destroy_zone) {
// properly destroy the zone and all its contents
......@@ -180,7 +183,9 @@ int dnslib_zonedb_remove_zone(dnslib_zonedb_t *db, dnslib_dname_t *zone_name,
dnslib_zone_t *dnslib_zonedb_find_zone(const dnslib_zonedb_t *db,
const dnslib_dname_t *zone_name)
{
return (dnslib_zone_t *)skip_find(db->zones, (void *)zone_name);
dnslib_zone_t dummy_zone;
dummy_zone.name = zone_name;
return (dnslib_zone_t *)gen_tree_find(db->zone_tree, &dummy_zone);
}
/*----------------------------------------------------------------------------*/
......@@ -192,7 +197,15 @@ const dnslib_zone_t *dnslib_zonedb_find_zone_for_name(dnslib_zonedb_t *db,
return NULL;
}
dnslib_zone_t *zone = skip_find_less_or_equal(db->zones, (void *)dname);
dnslib_zone_t dummy_zone;
dummy_zone.name = dname;
void *found = NULL;
int exact_match = gen_tree_find_less_or_equal(db->zone_tree,
&dummy_zone,
&found);
UNUSED(exact_match);
dnslib_zone_t *zone = (found) ? (dnslib_zone_t *)found : NULL;
DEBUG_DNSLIB_ZONEDB(
char *name = dnslib_dname_to_str(dname);
......@@ -216,8 +229,9 @@ dnslib_zonedb_t *dnslib_zonedb_copy(const dnslib_zonedb_t *db)
(dnslib_zonedb_t *)malloc(sizeof(dnslib_zonedb_t));
CHECK_ALLOC_LOG(db_new, NULL);
db_new->zones = skip_copy_list(db->zones);
if (db_new->zones == NULL) {
/*!< \todo copy the tree. */
// db_new->zones = skip_copy_list(db->zones);
if (db_new->zone_tree == NULL) {
free(db_new);
return NULL;
}
......@@ -229,56 +243,66 @@ dnslib_zonedb_t *dnslib_zonedb_copy(const dnslib_zonedb_t *db)
void dnslib_zonedb_free(dnslib_zonedb_t **db)
{
skip_destroy_list(&(*db)->zones, NULL, NULL);
gen_tree_destroy(&((*db)->zone_tree), NULL ,NULL);
free(*db);
*db = NULL;
}
/*----------------------------------------------------------------------------*/
static void delete_zone_from_db(void *node, void *data)
{
UNUSED(data);
dnslib_zone_t *zone = (dnslib_zone_t *)node;
assert(zone);
synchronize_rcu();
dnslib_zone_deep_free(&zone, 0);
}
void dnslib_zonedb_deep_free(dnslib_zonedb_t **db)
{
debug_dnslib_zonedb("Deleting zone db (%p).\n", *db);
debug_dnslib_zonedb("Is it empty (%p)? %s\n",
(*db)->zones, skip_is_empty((*db)->zones) ? "yes" : "no");
const skip_node_t *zn = skip_first((*db)->zones);
// debug_dnslib_zonedb("Is it empty (%p)? %s\n",
// (*db)->zones, skip_is_empty((*db)->zones) ? "yes" : "no");
dnslib_zone_t *zone = NULL;
DEBUG_DNSLIB_ZONEDB(
int i = 1;
char *name = NULL;
while (zn != NULL) {
debug_dnslib_zonedb("%d. zone: %p, key: %p\n", i, zn->value,
zn->key);
assert(zn->key == ((dnslib_zone_t *)zn->value)->apex->owner);
name = dnslib_dname_to_str((dnslib_dname_t *)zn->key);
debug_dnslib_zonedb(" zone name: %s\n", name);
free(name);
zn = skip_next(zn);
}
// int i = 1;
// char *name = NULL;
// while (zn != NULL) {
// debug_dnslib_zonedb("%d. zone: %p, key: %p\n", i, zn->value,
// zn->key);
// assert(zn->key == ((dnslib_zone_t *)zn->value)->apex->owner);
// name = dnslib_dname_to_str((dnslib_dname_t *)zn->key);
// debug_dnslib_zonedb(" zone name: %s\n", name);
// free(name);
// zn = skip_next(zn);
// }
zn = skip_first((*db)->zones);
// zn = skip_first((*db)->zones);
);
while (zn != NULL) {
zone = (dnslib_zone_t *)zn->value;
assert(zone != NULL);
// while (zn != NULL) {
// zone = (dnslib_zone_t *)zn->value;
// assert(zone != NULL);
// remove the zone from the database
skip_remove((*db)->zones, zn->key, NULL, NULL);
// wait for all readers to finish
synchronize_rcu();
// destroy the zone
dnslib_zone_deep_free(&zone, 0);
// // remove the zone from the database
// skip_remove((*db)->zones, zn->key, NULL, NULL);
// // wait for all readers to finish
// synchronize_rcu;
// // destroy the zone
// dnslib_zone_deep_free(&zone, 0);
zn = skip_first((*db)->zones);
}
// zn = skip_first((*db)->zones);
// }
assert(skip_is_empty((*db)->zones));
// assert(skip_is_empty((*db)->zones));
skip_destroy_list(&(*db)->zones, NULL, NULL);
// skip_destroy_list(&(*db)->zones, NULL, NULL);
gen_tree_destroy(&((*db)->zone_tree), delete_zone_from_db, NULL);
assert((*db)->zone_tree == NULL);
free(*db);
*db = NULL;
}
......
......@@ -15,7 +15,7 @@
#ifndef _KNOT_DNSLIB_ZONEDB_H_
#define _KNOT_DNSLIB_ZONEDB_H_
#include "common/skip-list.h"
#include "common/general-tree.h"
#include "dnslib/zone.h"
#include "dnslib/node.h"
#include "dnslib/dname.h"
......@@ -24,7 +24,7 @@
* \brief Zone database structure. Contains all zones managed by the server.
*/
struct dnslib_zonedb {
skip_list_t *zones; /*!< Skip-list of zones. */
general_tree_t *zone_tree; /*!< AVL tree of zones. */
};
typedef struct dnslib_zonedb dnslib_zonedb_t;
......
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