int Node_Delete (root_t* tree, tree_t* node) { TREE_CHECK (tree); NODE_CHECK (node); if (node->left) { TEC (Node_Delete (tree, node->left), node->left); } if (node->right) { TEC (Node_Delete (tree, node->right), node->right); } if (node->parent->left == node) node->parent->left = NULL; if (node->parent->right == node) node->parent->right = NULL; Tree_Update_Sizes (tree, node->parent, -1); TEC (Node_Destruct (node), node); TREE_CHECK (tree); return TREE_OK; }
static void test_add(void) { struct kz_lookup_ipv6_node *root = NULL; /* construct an empty tree */ TREE_NEW(root); TREE_CHECK(root, "0|::/0\n"); /* postfix insertion */ TREE_ADD(root, "ffff::", 15); TREE_ADD(root, "ffff:ffff::", 31); TREE_CHECK(root, "0|::/0\n" " 1|ffff::/15\n" " 2|ffff:ffff::/31\n"); TREE_NEW(root); TREE_ADD(root, "::", 15); TREE_ADD(root, "::", 31); TREE_CHECK(root, "0|::/0\n" " 1|::/15\n" " 2|::/31\n"); /* inserting shorter prefix */ TREE_NEW(root); TREE_ADD(root, "ffff:ffff::", 31); TREE_ADD(root, "ffff::", 15); TREE_CHECK(root, "0|::/0\n" " 1|ffff::/15\n" " 2|ffff:ffff::/31\n"); TREE_NEW(root); TREE_ADD(root, "::", 31); TREE_ADD(root, "::", 15); TREE_CHECK(root, "0|::/0\n" " 1|::/15\n" " 2|::/31\n"); /* same prefix length, but different prefix */ TREE_NEW(root); TREE_ADD(root, "ffff::", 16); TREE_ADD(root, "f0ff::", 16); TREE_CHECK(root, "0|::/0\n" " 1|f0ff::/4\n" " 2|f0ff::/16\n" " 2|ffff::/16\n"); TREE_NEW(root); TREE_ADD(root, "00ff::", 16); TREE_ADD(root, "0fff::", 16); TREE_CHECK(root, "0|::/0\n" " 1|fff::/4\n" " 2|ff::/16\n" " 2|fff::/16\n"); /* adding a node already present */ TREE_NEW(root); TREE_ADD(root, "fe80::", 10); TREE_ADD(root, "fe80::", 10); TREE_ADD(root, "fe8f::", 10); TREE_CHECK(root, "0|::/0\n" " 1|fe80::/10\n"); ipv6_destroy(root); }
int Node_Add_Right (root_t* tree, tree_t* node, tree_t* child) { TREE_CHECK (tree); NODE_CHECK (node); NODE_CHECK (child); if (node->right == NULL) { node->right = child; node->right->parent = node; TEC (Tree_Update_Sizes (tree, node, child->size), node); } TREE_CHECK (tree); NODE_CHECK (node); return TREE_OK; }
int Tree_Print (FILE* outstream, root_t* tree) { ASSERT (outstream); TREE_CHECK (tree); int ret = Node_Print (outstream, tree->root); fprintf (outstream, "\n\n"); return (ret == NODE_OK)? TREE_OK : TREE_ERR; }
static void test_print(void) { struct kz_lookup_ipv6_node *root = ipv6_node_new(); TREE_CHECK(root, "0|::/0\n"); TREE_ADD(root, "::", 32); TREE_ADD(root, "::", 64); TREE_ADD(root, "ffff::", 16); TREE_ADD(root, "ffff:ff00::", 32); TREE_ADD(root, "ffff:f000::", 32); TREE_CHECK(root, "0|::/0\n" " 1|::/32\n" " 2|::/64\n" " 1|ffff::/16\n" " 2|ffff:f000::/20\n" " 3|ffff:f000::/32\n" " 3|ffff:ff00::/32\n"); ipv6_destroy(root); }
int Node_Add_Left (root_t* tree, tree_t* node, tree_t* child) { TREE_CHECK (tree); NODE_CHECK (node); NODE_CHECK (child); if (node->left == NULL) { node->left = child; node->left->parent = node; TEC (Tree_Update_Sizes (tree, node, child->size), node); } Tree_Dump (stdout, tree); TREE_CHECK (tree); NODE_CHECK (node); return TREE_OK; }
int Tree_Construct (root_t** new_tree) { ASSERT (new_tree); *new_tree = (root_t*) calloc (1, sizeof (new_tree)); (*new_tree)->size = 1; ISERR (Node_Construct (&(*new_tree)->root), (*new_tree)->root); TREE_CHECK (*new_tree); return TREE_OK; }
int Tree_Print_Dot (FILE* outstream, root_t* tree) { ASSERT (outstream); TREE_CHECK (tree); fprintf (outstream, "digraph my_little_graph\n"); fprintf (outstream, "{\n"); int ret = Node_Print_Dot (outstream, tree->root); ASSERT (ret); fprintf (outstream, "}\n"); return TREE_OK; }
int Tree_Destruct (root_t* tree) { TREE_CHECK (tree); if (tree->root->left) TEC (Node_Delete (tree, tree->root->left), tree); if (tree->root->right) TEC (Node_Delete (tree, tree->root->right), tree); ISERR (Node_Destruct (tree->root), tree); tree->size = Poison; free (tree); return TREE_OK; }