diff --git a/avl.h b/avl.h new file mode 100644 index 0000000..d7cb1bb --- /dev/null +++ b/avl.h @@ -0,0 +1,439 @@ +/* + * Vanitygen, vanity bitcoin address generator + * Copyright (C) 2011 + * + * Vanitygen is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * Vanitygen is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Vanitygen. If not, see . + */ + +#if !defined (__VG_AVL_H__) +#define __VG_AVL_H__ + +#include + +/* + * AVL tree implementation + */ + +typedef enum { CENT = 1, LEFT = 0, RIGHT = 2 } avl_balance_t; + +typedef struct _avl_item_s { + struct _avl_item_s *ai_left, *ai_right, *ai_up; + avl_balance_t ai_balance; +#ifndef NDEBUG + int ai_indexed; +#endif +} avl_item_t; + +typedef struct _avl_root_s { + avl_item_t *ar_root; +} avl_root_t; + +static INLINE void +avl_root_init(avl_root_t *rootp) +{ + rootp->ar_root = NULL; +} + +static INLINE int +avl_root_empty(avl_root_t *rootp) +{ + return (rootp->ar_root == NULL) ? 1 : 0; +} + +static INLINE void +avl_item_init(avl_item_t *itemp) +{ + itemp->ai_left = NULL; + itemp->ai_right = NULL; + itemp->ai_up = NULL; + itemp->ai_balance = CENT; +#ifndef NDEBUG + itemp->ai_indexed = 0; +#endif +} + +#define container_of(ptr, type, member) \ + (((type*) (((unsigned char *)ptr) - \ + (size_t)&(((type *)((unsigned char *)0))->member)))) + +#define avl_item_entry(ptr, type, member) \ + container_of(ptr, type, member) + + + +static INLINE void +_avl_rotate_ll(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *tmp; + tmp = itemp->ai_left; + itemp->ai_left = tmp->ai_right; + if (itemp->ai_left) + itemp->ai_left->ai_up = itemp; + tmp->ai_right = itemp; + + if (itemp->ai_up) { + if (itemp->ai_up->ai_left == itemp) { + itemp->ai_up->ai_left = tmp; + } else { + assert(itemp->ai_up->ai_right == itemp); + itemp->ai_up->ai_right = tmp; + } + } else { + rootp->ar_root = tmp; + } + tmp->ai_up = itemp->ai_up; + itemp->ai_up = tmp; +} + +static INLINE void +_avl_rotate_lr(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *rcp, *rlcp; + rcp = itemp->ai_left; + rlcp = rcp->ai_right; + if (itemp->ai_up) { + if (itemp == itemp->ai_up->ai_left) { + itemp->ai_up->ai_left = rlcp; + } else { + assert(itemp == itemp->ai_up->ai_right); + itemp->ai_up->ai_right = rlcp; + } + } else { + rootp->ar_root = rlcp; + } + rlcp->ai_up = itemp->ai_up; + rcp->ai_right = rlcp->ai_left; + if (rcp->ai_right) + rcp->ai_right->ai_up = rcp; + itemp->ai_left = rlcp->ai_right; + if (itemp->ai_left) + itemp->ai_left->ai_up = itemp; + rlcp->ai_left = rcp; + rlcp->ai_right = itemp; + rcp->ai_up = rlcp; + itemp->ai_up = rlcp; +} + +static INLINE void +_avl_rotate_rr(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *tmp; + tmp = itemp->ai_right; + itemp->ai_right = tmp->ai_left; + if (itemp->ai_right) + itemp->ai_right->ai_up = itemp; + tmp->ai_left = itemp; + + if (itemp->ai_up) { + if (itemp->ai_up->ai_right == itemp) { + itemp->ai_up->ai_right = tmp; + } else { + assert(itemp->ai_up->ai_left == itemp); + itemp->ai_up->ai_left = tmp; + } + } else { + rootp->ar_root = tmp; + } + tmp->ai_up = itemp->ai_up; + itemp->ai_up = tmp; +} + +static INLINE void +_avl_rotate_rl(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *rcp, *rlcp; + rcp = itemp->ai_right; + rlcp = rcp->ai_left; + if (itemp->ai_up) { + if (itemp == itemp->ai_up->ai_right) { + itemp->ai_up->ai_right = rlcp; + } else { + assert(itemp == itemp->ai_up->ai_left); + itemp->ai_up->ai_left = rlcp; + } + } else { + rootp->ar_root = rlcp; + } + rlcp->ai_up = itemp->ai_up; + rcp->ai_left = rlcp->ai_right; + if (rcp->ai_left) + rcp->ai_left->ai_up = rcp; + itemp->ai_right = rlcp->ai_left; + if (itemp->ai_right) + itemp->ai_right->ai_up = itemp; + rlcp->ai_right = rcp; + rlcp->ai_left = itemp; + rcp->ai_up = rlcp; + itemp->ai_up = rlcp; +} + +static void +avl_delete_fix(avl_root_t *rootp, avl_item_t *itemp, avl_item_t *parentp) +{ + avl_item_t *childp; + + if ((parentp->ai_left == NULL) && + (parentp->ai_right == NULL)) { + assert(itemp == NULL); + parentp->ai_balance = CENT; + itemp = parentp; + parentp = itemp->ai_up; + } + + while (parentp) { + if (itemp == parentp->ai_right) { + itemp = parentp->ai_left; + if (parentp->ai_balance == LEFT) { + /* Parent was left-heavy, now worse */ + if (itemp->ai_balance == LEFT) { + /* If left child is also + * left-heavy, LL fixes it. */ + _avl_rotate_ll(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + parentp = itemp; + } else if (itemp->ai_balance == CENT) { + _avl_rotate_ll(rootp, parentp); + itemp->ai_balance = RIGHT; + parentp->ai_balance = LEFT; + break; + } else { + childp = itemp->ai_right; + _avl_rotate_lr(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + if (childp->ai_balance == RIGHT) + itemp->ai_balance = LEFT; + if (childp->ai_balance == LEFT) + parentp->ai_balance = RIGHT; + childp->ai_balance = CENT; + parentp = childp; + } + } else if (parentp->ai_balance == CENT) { + parentp->ai_balance = LEFT; + break; + } else { + parentp->ai_balance = CENT; + } + + } else { + itemp = parentp->ai_right; + if (parentp->ai_balance == RIGHT) { + if (itemp->ai_balance == RIGHT) { + _avl_rotate_rr(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + parentp = itemp; + } else if (itemp->ai_balance == CENT) { + _avl_rotate_rr(rootp, parentp); + itemp->ai_balance = LEFT; + parentp->ai_balance = RIGHT; + break; + } else { + childp = itemp->ai_left; + _avl_rotate_rl(rootp, parentp); + + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + if (childp->ai_balance == RIGHT) + parentp->ai_balance = LEFT; + if (childp->ai_balance == LEFT) + itemp->ai_balance = RIGHT; + childp->ai_balance = CENT; + parentp = childp; + } + } else if (parentp->ai_balance == CENT) { + parentp->ai_balance = RIGHT; + break; + } else { + parentp->ai_balance = CENT; + } + } + + itemp = parentp; + parentp = itemp->ai_up; + } +} + +static void +avl_insert_fix(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *childp, *parentp = itemp->ai_up; + itemp->ai_left = itemp->ai_right = NULL; +#ifndef NDEBUG + assert(!itemp->ai_indexed); + itemp->ai_indexed = 1; +#endif + while (parentp) { + if (itemp == parentp->ai_left) { + if (parentp->ai_balance == LEFT) { + /* Parent was left-heavy, now worse */ + if (itemp->ai_balance == LEFT) { + /* If left child is also + * left-heavy, LL fixes it. */ + _avl_rotate_ll(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + break; + } else { + assert(itemp->ai_balance != CENT); + childp = itemp->ai_right; + _avl_rotate_lr(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + if (childp->ai_balance == RIGHT) + itemp->ai_balance = LEFT; + if (childp->ai_balance == LEFT) + parentp->ai_balance = RIGHT; + childp->ai_balance = CENT; + break; + } + } else if (parentp->ai_balance == CENT) { + parentp->ai_balance = LEFT; + } else { + parentp->ai_balance = CENT; + return; + } + } else { + if (parentp->ai_balance == RIGHT) { + if (itemp->ai_balance == RIGHT) { + _avl_rotate_rr(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + break; + } else { + assert(itemp->ai_balance != CENT); + childp = itemp->ai_left; + _avl_rotate_rl(rootp, parentp); + itemp->ai_balance = CENT; + parentp->ai_balance = CENT; + if (childp->ai_balance == RIGHT) + parentp->ai_balance = LEFT; + if (childp->ai_balance == LEFT) + itemp->ai_balance = RIGHT; + childp->ai_balance = CENT; + break; + } + } else if (parentp->ai_balance == CENT) { + parentp->ai_balance = RIGHT; + } else { + parentp->ai_balance = CENT; + break; + } + } + + itemp = parentp; + parentp = itemp->ai_up; + } +} + +static INLINE avl_item_t * +avl_first(avl_root_t *rootp) +{ + avl_item_t *itemp = rootp->ar_root; + if (itemp) { + while (itemp->ai_left) + itemp = itemp->ai_left; + } + return itemp; +} + +static INLINE avl_item_t * +avl_next(avl_item_t *itemp) +{ + if (itemp->ai_right) { + itemp = itemp->ai_right; + while (itemp->ai_left) + itemp = itemp->ai_left; + return itemp; + } + + while (itemp->ai_up && (itemp == itemp->ai_up->ai_right)) + itemp = itemp->ai_up; + + if (!itemp->ai_up) + return NULL; + + return itemp->ai_up; +} + +static void +avl_remove(avl_root_t *rootp, avl_item_t *itemp) +{ + avl_item_t *relocp, *replacep, *parentp = NULL; +#ifndef NDEBUG + assert(itemp->ai_indexed); + itemp->ai_indexed = 0; +#endif + /* If the item is directly replaceable, do it. */ + if ((itemp->ai_left == NULL) || (itemp->ai_right == NULL)) { + parentp = itemp->ai_up; + replacep = itemp->ai_left; + if (replacep == NULL) + replacep = itemp->ai_right; + if (replacep != NULL) + replacep->ai_up = parentp; + if (parentp == NULL) { + rootp->ar_root = replacep; + } else { + if (itemp == parentp->ai_left) + parentp->ai_left = replacep; + else + parentp->ai_right = replacep; + + avl_delete_fix(rootp, replacep, parentp); + } + return; + } + + /* + * Otherwise we do an indirect replacement with + * the item's leftmost right descendant. + */ + relocp = avl_next(itemp); + assert(relocp); + assert(relocp->ai_up != NULL); + assert(relocp->ai_left == NULL); + replacep = relocp->ai_right; + relocp->ai_left = itemp->ai_left; + if (relocp->ai_left != NULL) + relocp->ai_left->ai_up = relocp; + if (itemp->ai_up == NULL) + rootp->ar_root = relocp; + else { + if (itemp == itemp->ai_up->ai_left) + itemp->ai_up->ai_left = relocp; + else + itemp->ai_up->ai_right = relocp; + } + if (relocp == relocp->ai_up->ai_left) { + assert(relocp->ai_up != itemp); + relocp->ai_up->ai_left = replacep; + parentp = relocp->ai_up; + if (replacep != NULL) + replacep->ai_up = relocp->ai_up; + relocp->ai_right = itemp->ai_right; + } else { + assert(relocp->ai_up == itemp); + relocp->ai_right = replacep; + parentp = relocp; + } + if (relocp->ai_right != NULL) + relocp->ai_right->ai_up = relocp; + relocp->ai_up = itemp->ai_up; + relocp->ai_balance = itemp->ai_balance; + avl_delete_fix(rootp, replacep, parentp); +} + +#endif /* !defined (__VG_AVL_H__) */ diff --git a/pattern.c b/pattern.c index 920dd69..b6cf5ce 100644 --- a/pattern.c +++ b/pattern.c @@ -33,6 +33,7 @@ #include "pattern.h" #include "util.h" +#include "avl.h" /* @@ -905,417 +906,6 @@ free_ranges(BIGNUM **ranges) } } -/* - * AVL tree implementation - */ - -typedef enum { CENT = 1, LEFT = 0, RIGHT = 2 } avl_balance_t; - -typedef struct _avl_item_s { - struct _avl_item_s *ai_left, *ai_right, *ai_up; - avl_balance_t ai_balance; -#ifndef NDEBUG - int ai_indexed; -#endif -} avl_item_t; - -typedef struct _avl_root_s { - avl_item_t *ar_root; -} avl_root_t; - -static INLINE void -avl_root_init(avl_root_t *rootp) -{ - rootp->ar_root = NULL; -} - -static INLINE int -avl_root_empty(avl_root_t *rootp) -{ - return (rootp->ar_root == NULL) ? 1 : 0; -} - -static INLINE void -avl_item_init(avl_item_t *itemp) -{ - memset(itemp, 0, sizeof(*itemp)); - itemp->ai_balance = CENT; -} - -#define container_of(ptr, type, member) \ - (((type*) (((unsigned char *)ptr) - \ - (size_t)&(((type *)((unsigned char *)0))->member)))) - -#define avl_item_entry(ptr, type, member) \ - container_of(ptr, type, member) - - - -static INLINE void -_avl_rotate_ll(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *tmp; - tmp = itemp->ai_left; - itemp->ai_left = tmp->ai_right; - if (itemp->ai_left) - itemp->ai_left->ai_up = itemp; - tmp->ai_right = itemp; - - if (itemp->ai_up) { - if (itemp->ai_up->ai_left == itemp) { - itemp->ai_up->ai_left = tmp; - } else { - assert(itemp->ai_up->ai_right == itemp); - itemp->ai_up->ai_right = tmp; - } - } else { - rootp->ar_root = tmp; - } - tmp->ai_up = itemp->ai_up; - itemp->ai_up = tmp; -} - -static INLINE void -_avl_rotate_lr(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *rcp, *rlcp; - rcp = itemp->ai_left; - rlcp = rcp->ai_right; - if (itemp->ai_up) { - if (itemp == itemp->ai_up->ai_left) { - itemp->ai_up->ai_left = rlcp; - } else { - assert(itemp == itemp->ai_up->ai_right); - itemp->ai_up->ai_right = rlcp; - } - } else { - rootp->ar_root = rlcp; - } - rlcp->ai_up = itemp->ai_up; - rcp->ai_right = rlcp->ai_left; - if (rcp->ai_right) - rcp->ai_right->ai_up = rcp; - itemp->ai_left = rlcp->ai_right; - if (itemp->ai_left) - itemp->ai_left->ai_up = itemp; - rlcp->ai_left = rcp; - rlcp->ai_right = itemp; - rcp->ai_up = rlcp; - itemp->ai_up = rlcp; -} - -static INLINE void -_avl_rotate_rr(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *tmp; - tmp = itemp->ai_right; - itemp->ai_right = tmp->ai_left; - if (itemp->ai_right) - itemp->ai_right->ai_up = itemp; - tmp->ai_left = itemp; - - if (itemp->ai_up) { - if (itemp->ai_up->ai_right == itemp) { - itemp->ai_up->ai_right = tmp; - } else { - assert(itemp->ai_up->ai_left == itemp); - itemp->ai_up->ai_left = tmp; - } - } else { - rootp->ar_root = tmp; - } - tmp->ai_up = itemp->ai_up; - itemp->ai_up = tmp; -} - -static INLINE void -_avl_rotate_rl(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *rcp, *rlcp; - rcp = itemp->ai_right; - rlcp = rcp->ai_left; - if (itemp->ai_up) { - if (itemp == itemp->ai_up->ai_right) { - itemp->ai_up->ai_right = rlcp; - } else { - assert(itemp == itemp->ai_up->ai_left); - itemp->ai_up->ai_left = rlcp; - } - } else { - rootp->ar_root = rlcp; - } - rlcp->ai_up = itemp->ai_up; - rcp->ai_left = rlcp->ai_right; - if (rcp->ai_left) - rcp->ai_left->ai_up = rcp; - itemp->ai_right = rlcp->ai_left; - if (itemp->ai_right) - itemp->ai_right->ai_up = itemp; - rlcp->ai_right = rcp; - rlcp->ai_left = itemp; - rcp->ai_up = rlcp; - itemp->ai_up = rlcp; -} - -static void -avl_delete_fix(avl_root_t *rootp, avl_item_t *itemp, avl_item_t *parentp) -{ - avl_item_t *childp; - - if ((parentp->ai_left == NULL) && - (parentp->ai_right == NULL)) { - assert(itemp == NULL); - parentp->ai_balance = CENT; - itemp = parentp; - parentp = itemp->ai_up; - } - - while (parentp) { - if (itemp == parentp->ai_right) { - itemp = parentp->ai_left; - if (parentp->ai_balance == LEFT) { - /* Parent was left-heavy, now worse */ - if (itemp->ai_balance == LEFT) { - /* If left child is also - * left-heavy, LL fixes it. */ - _avl_rotate_ll(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - parentp = itemp; - } else if (itemp->ai_balance == CENT) { - _avl_rotate_ll(rootp, parentp); - itemp->ai_balance = RIGHT; - parentp->ai_balance = LEFT; - break; - } else { - childp = itemp->ai_right; - _avl_rotate_lr(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - if (childp->ai_balance == RIGHT) - itemp->ai_balance = LEFT; - if (childp->ai_balance == LEFT) - parentp->ai_balance = RIGHT; - childp->ai_balance = CENT; - parentp = childp; - } - } else if (parentp->ai_balance == CENT) { - parentp->ai_balance = LEFT; - break; - } else { - parentp->ai_balance = CENT; - } - - } else { - itemp = parentp->ai_right; - if (parentp->ai_balance == RIGHT) { - if (itemp->ai_balance == RIGHT) { - _avl_rotate_rr(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - parentp = itemp; - } else if (itemp->ai_balance == CENT) { - _avl_rotate_rr(rootp, parentp); - itemp->ai_balance = LEFT; - parentp->ai_balance = RIGHT; - break; - } else { - childp = itemp->ai_left; - _avl_rotate_rl(rootp, parentp); - - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - if (childp->ai_balance == RIGHT) - parentp->ai_balance = LEFT; - if (childp->ai_balance == LEFT) - itemp->ai_balance = RIGHT; - childp->ai_balance = CENT; - parentp = childp; - } - } else if (parentp->ai_balance == CENT) { - parentp->ai_balance = RIGHT; - break; - } else { - parentp->ai_balance = CENT; - } - } - - itemp = parentp; - parentp = itemp->ai_up; - } -} - -static void -avl_insert_fix(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *childp, *parentp = itemp->ai_up; - itemp->ai_left = itemp->ai_right = NULL; -#ifndef NDEBUG - assert(!itemp->ai_indexed); - itemp->ai_indexed = 1; -#endif - while (parentp) { - if (itemp == parentp->ai_left) { - if (parentp->ai_balance == LEFT) { - /* Parent was left-heavy, now worse */ - if (itemp->ai_balance == LEFT) { - /* If left child is also - * left-heavy, LL fixes it. */ - _avl_rotate_ll(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - break; - } else { - assert(itemp->ai_balance != CENT); - childp = itemp->ai_right; - _avl_rotate_lr(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - if (childp->ai_balance == RIGHT) - itemp->ai_balance = LEFT; - if (childp->ai_balance == LEFT) - parentp->ai_balance = RIGHT; - childp->ai_balance = CENT; - break; - } - } else if (parentp->ai_balance == CENT) { - parentp->ai_balance = LEFT; - } else { - parentp->ai_balance = CENT; - return; - } - } else { - if (parentp->ai_balance == RIGHT) { - if (itemp->ai_balance == RIGHT) { - _avl_rotate_rr(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - break; - } else { - assert(itemp->ai_balance != CENT); - childp = itemp->ai_left; - _avl_rotate_rl(rootp, parentp); - itemp->ai_balance = CENT; - parentp->ai_balance = CENT; - if (childp->ai_balance == RIGHT) - parentp->ai_balance = LEFT; - if (childp->ai_balance == LEFT) - itemp->ai_balance = RIGHT; - childp->ai_balance = CENT; - break; - } - } else if (parentp->ai_balance == CENT) { - parentp->ai_balance = RIGHT; - } else { - parentp->ai_balance = CENT; - break; - } - } - - itemp = parentp; - parentp = itemp->ai_up; - } -} - -static INLINE avl_item_t * -avl_first(avl_root_t *rootp) -{ - avl_item_t *itemp = rootp->ar_root; - if (itemp) { - while (itemp->ai_left) - itemp = itemp->ai_left; - } - return itemp; -} - -static INLINE avl_item_t * -avl_next(avl_item_t *itemp) -{ - if (itemp->ai_right) { - itemp = itemp->ai_right; - while (itemp->ai_left) - itemp = itemp->ai_left; - return itemp; - } - - while (itemp->ai_up && (itemp == itemp->ai_up->ai_right)) - itemp = itemp->ai_up; - - if (!itemp->ai_up) - return NULL; - - return itemp->ai_up; -} - -static void -avl_remove(avl_root_t *rootp, avl_item_t *itemp) -{ - avl_item_t *relocp, *replacep, *parentp = NULL; -#ifndef NDEBUG - assert(itemp->ai_indexed); - itemp->ai_indexed = 0; -#endif - /* If the item is directly replaceable, do it. */ - if ((itemp->ai_left == NULL) || (itemp->ai_right == NULL)) { - parentp = itemp->ai_up; - replacep = itemp->ai_left; - if (replacep == NULL) - replacep = itemp->ai_right; - if (replacep != NULL) - replacep->ai_up = parentp; - if (parentp == NULL) { - rootp->ar_root = replacep; - } else { - if (itemp == parentp->ai_left) - parentp->ai_left = replacep; - else - parentp->ai_right = replacep; - - avl_delete_fix(rootp, replacep, parentp); - } - return; - } - - /* - * Otherwise we do an indirect replacement with - * the item's leftmost right descendant. - */ - relocp = avl_next(itemp); - assert(relocp); - assert(relocp->ai_up != NULL); - assert(relocp->ai_left == NULL); - replacep = relocp->ai_right; - relocp->ai_left = itemp->ai_left; - if (relocp->ai_left != NULL) - relocp->ai_left->ai_up = relocp; - if (itemp->ai_up == NULL) - rootp->ar_root = relocp; - else { - if (itemp == itemp->ai_up->ai_left) - itemp->ai_up->ai_left = relocp; - else - itemp->ai_up->ai_right = relocp; - } - if (relocp == relocp->ai_up->ai_left) { - assert(relocp->ai_up != itemp); - relocp->ai_up->ai_left = replacep; - parentp = relocp->ai_up; - if (replacep != NULL) - replacep->ai_up = relocp->ai_up; - relocp->ai_right = itemp->ai_right; - } else { - assert(relocp->ai_up == itemp); - relocp->ai_right = replacep; - parentp = relocp; - } - if (relocp->ai_right != NULL) - relocp->ai_right->ai_up = relocp; - relocp->ai_up = itemp->ai_up; - relocp->ai_balance = itemp->ai_balance; - avl_delete_fix(rootp, replacep, parentp); -} - - /* * Address prefix AVL tree node