From 9cb4b60e79aacda0d08a63bd1cc7b09414597c19 Mon Sep 17 00:00:00 2001 From: "cebka@cebka-laptop" Date: Mon, 21 Apr 2008 20:48:30 +0400 Subject: [PATCH] * Fix memory allocating/deallocating in radix code --- cfg_file.c | 4 ++-- radix.c | 56 +++++++++++++++++++++++++++++++++++++++--------------- radix.h | 3 +-- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/cfg_file.c b/cfg_file.c index 971e302..9d7d5e3 100644 --- a/cfg_file.c +++ b/cfg_file.c @@ -538,10 +538,10 @@ free_config (struct config_file *cfg) free (addr_cur); } - radix32tree_delete (cfg->grey_whitelist_tree, 0, 0); + radix_tree_free (cfg->grey_whitelist_tree); free (cfg->grey_whitelist_tree); - radix32tree_delete (cfg->spamd_whitelist, 0, 0); + radix_tree_free (cfg->spamd_whitelist); free (cfg->spamd_whitelist); if (cfg->spamd_reject_message) { diff --git a/radix.c b/radix.c index e3b4ad8..2bba2fa 100644 --- a/radix.c +++ b/radix.c @@ -4,7 +4,6 @@ static void *radix_alloc(radix_tree_t *tree); - radix_tree_t * radix_tree_create() { @@ -15,7 +14,6 @@ radix_tree_create() return NULL; } - tree->start = NULL; tree->size = 0; tree->root = radix_alloc(tree); @@ -43,7 +41,7 @@ radix32tree_insert(radix_tree_t *tree, uint32_t key, uint32_t mask, node = tree->root; next = tree->root; - + /* Find a place in trie to insert */ while (bit & mask) { if (key & bit) { next = node->right; @@ -68,7 +66,7 @@ radix32tree_insert(radix_tree_t *tree, uint32_t key, uint32_t mask, node->value = value; return 0; } - + /* Inserting value in trie creating all path components */ while (bit & mask) { next = radix_alloc(tree); if (next == NULL) { @@ -195,22 +193,50 @@ radix_alloc(radix_tree_t *tree) { char *p; - if (tree->size < sizeof(radix_node_t)) { - tree->start = malloc(sizeof(radix_node_t)); - if (tree->start == NULL) { - return NULL; - } + p = malloc(sizeof(radix_node_t)); - tree->size = sizeof(radix_node_t); - } - - p = tree->start; - tree->start += sizeof(radix_node_t); - tree->size -= sizeof(radix_node_t); + tree->size += sizeof(radix_node_t); return p; } +void +radix_tree_free(radix_tree_t *tree) +{ + radix_node_t *node, *tmp; + + node = tree->root; + + for (;;) { + /* Traverse to the end of trie */ + while (node->left || node->right) { + if (node->left) { + node = node->left; + } + else { + node = node->right; + } + } + /* Found leaf node, free it */ + if (node->parent->right == node) { + node->parent->right = NULL; + + } else { + node->parent->left = NULL; + } + + tmp = node; + /* Go up */ + node = node->parent; + free (tmp); + + /* We are at the trie root and we have no more leaves, end of algorithm */ + if (!node->left && !node->right && !node->parent) { + free (node); + break; + } + } +} /* * vi:ts=4 */ diff --git a/radix.h b/radix.h index 68b05b5..bcf4b49 100644 --- a/radix.h +++ b/radix.h @@ -23,7 +23,6 @@ struct radix_node_s { typedef struct { radix_node_t *root; - char *start; size_t size; } radix_tree_t; @@ -34,6 +33,6 @@ int radix32tree_insert(radix_tree_t *tree, int radix32tree_delete(radix_tree_t *tree, uint32_t key, uint32_t mask); unsigned char radix32tree_find(radix_tree_t *tree, uint32_t key); - +void radix_tree_free(radix_tree_t *tree); #endif