void * getelt_rbtree ( const RBTREE tree, const void * key){ assert(NULL!=tree); assert(NULL!=key); RBNODE node = search_rbtree(tree,key); if (NULL!=node){ return node->value;} return NULL; }
rt_connection* get_connection(connection_table* ct, uint16_t hid, uint32_t window){ rt_connection *rt = search_rbtree(*ct, &hid); if(rt) return rt; debug(I, "Connection with handler %d not found. Creating it...\n", hid); rt = mkrtconnection(window, hid); rb_tree_insert(ct, rt); return rt; }
/* Need to decide what to do about memory for keys. * Possible memory leak at moment. */ void * removeelt_rbtree (RBTREE tree, const void * key){ RBNODE phantom = NULL; void * retval = NULL; assert(NULL!=tree); assert(NULL!=key); RBNODE delnode = search_rbtree(tree,key); if (NULL==delnode){ return retval;} /* Nothing to delete */ retval = delnode->value; tree->freekey(delnode->key); /* Node has two non-null children. Transform so not case */ if (NULL!=delnode->right && NULL!=delnode->left){ RBNODE leftmost = minnode_rbtree_sub(delnode->right); delnode->key = leftmost->key; delnode->value = leftmost->value; delnode = leftmost; } /* delnode now has at most one child */ enum rbcolour delcol = delnode->colour; RBNODE child = (NULL==delnode->right)?delnode->left:delnode->right; if ( NULL==child){ child = create_rbnode(black); /* "Phantom node" */ phantom = child; } /* Replace node with child */ if (NULL!=delnode->parent){ if (delnode->parent->left==delnode) delnode->parent->left = child; else if (delnode->parent->right==delnode) delnode->parent->right = child; else abort(); } else { tree->root = child; } child->parent = delnode->parent; free(delnode); if(red==delcol){ goto remove_end;} /* Deleted node was black */ if (red==colour_rbnode(child)){ child->colour = black; goto remove_end;} case1: /* Case 1 */ if ( NULL==child->parent){ /* New root */ tree->root = child; goto remove_end; } /* Case 2 */ RBNODE sibling = sibling_rbnode(child); if ( red==colour_rbnode(sibling)){ child->parent->colour = red; sibling->colour = black; if ( child == child->parent->left) rotate_left_rbtree (child->parent,tree); else rotate_right_rbtree(child->parent,tree); } sibling = sibling_rbnode(child); assert(sibling->colour==black); /* Case 3 */ if ( black== child->parent->colour && black==colour_rbnode(sibling->left) && black==colour_rbnode(sibling->right)){ sibling->colour = red; child = child->parent; goto case1; } assert(sibling->colour==black); /* Case 4 */ if ( red == child->parent->colour && black==colour_rbnode(sibling->left) && black==colour_rbnode(sibling->right)){ sibling->colour = red; child->parent->colour = black; goto remove_end; } assert(sibling->colour == black); /* Case 5 */ if ( child==child->parent->left && red==colour_rbnode(sibling->left) && black==colour_rbnode(sibling->right)){ sibling->colour = red; sibling->left->colour = black; rotate_right_rbtree(sibling,tree); } else if ( child==child->parent->right && black==colour_rbnode(sibling->left) && red==colour_rbnode(sibling->right)){ sibling->colour = red; sibling->right->colour = black; rotate_left_rbtree(sibling,tree); } sibling = sibling_rbnode(child); /* Case 6 */ sibling->colour = child->parent->colour; child->parent->colour = black; if ( child == child->parent->left){ sibling->right->colour = black; rotate_left_rbtree(child->parent,tree); } else { sibling->left->colour = black; rotate_right_rbtree(child->parent,tree); } remove_end: /* Delelte phantom node */ if ( phantom ){ if ( NULL!=phantom->parent){ if (phantom->parent->left == phantom) phantom->parent->left = NULL; else if (phantom->parent->right == phantom) phantom->parent->right = NULL; else abort(); } if(tree->root==phantom){tree->root = NULL;} free(phantom); } return retval; }
bool member_rbtree ( const RBTREE tree, const void * key){ RBNODE node = search_rbtree (tree,key); if ( NULL==node) return false; return true; }