static void avl_checknode( register avltree_desc_t *tree, register avlnode_t *np) { register avlnode_t *back = np->avl_back; register avlnode_t *forw = np->avl_forw; register avlnode_t *nextino = np->avl_nextino; register int bal = np->avl_balance; ASSERT(bal != AVL_BALANCE || (!back && !forw) || (back && forw)); ASSERT(bal != AVL_FORW || forw); ASSERT(bal != AVL_BACK || back); if (forw) { ASSERT(AVL_START(tree, np) < AVL_START(tree, forw)); ASSERT(np->avl_forw->avl_parent == np); ASSERT(back || bal == AVL_FORW); } else { ASSERT(bal != AVL_FORW); ASSERT(bal == AVL_BALANCE || back); ASSERT(bal == AVL_BACK || !back); } if (back) { ASSERT(AVL_START(tree, np) > AVL_START(tree, back)); ASSERT(np->avl_back->avl_parent == np); ASSERT(forw || bal == AVL_BACK); } else { ASSERT(bal != AVL_BACK); ASSERT(bal == AVL_BALANCE || forw); ASSERT(bal == AVL_FORW || !forw); } if (nextino == NULL) ASSERT(forw == NULL); else ASSERT(AVL_END(tree, np) <= AVL_START(tree, nextino)); }
static avlnode_t * avl_insert_find_growth( register avltree_desc_t *tree, register __psunsigned_t start, /* range start at start, */ register __psunsigned_t end, /* exclusive */ register int *growthp) /* OUT */ { avlnode_t *root = tree->avl_root; register avlnode_t *np; np = root; ASSERT(np); /* caller ensures that there is atleast one node in tree */ for ( ; ; ) { CERT(np->avl_parent || root == np); CERT(!np->avl_parent || root != np); CERT(!(np->avl_back) || np->avl_back->avl_parent == np); CERT(!(np->avl_forw) || np->avl_forw->avl_parent == np); CERT(np->avl_balance != AVL_FORW || np->avl_forw); CERT(np->avl_balance != AVL_BACK || np->avl_back); CERT(np->avl_balance != AVL_BALANCE || np->avl_back == NULL || np->avl_forw); CERT(np->avl_balance != AVL_BALANCE || np->avl_forw == NULL || np->avl_back); if (AVL_START(tree, np) >= end) { if (np->avl_back) { np = np->avl_back; continue; } *growthp = AVL_BACK; break; } if (AVL_END(tree, np) <= start) { if (np->avl_forw) { np = np->avl_forw; continue; } *growthp = AVL_FORW; break; } /* found exact match -- let caller decide if it is an error */ return(NULL); } return(np); }
static void avl_insert_grow( register avltree_desc_t *tree, register avlnode_t *parent, register avlnode_t *newnode, register int growth) { register avlnode_t *nnext; register __psunsigned_t start = AVL_START(tree, newnode); if (growth == AVL_BACK) { parent->avl_back = newnode; /* * we are growing to the left; previous in-order to newnode is * closest ancestor with lesser value. Before this * insertion, this ancestor will be pointing to * newnode's parent. After insertion, next in-order to newnode * is the parent. */ newnode->avl_nextino = parent; nnext = parent; while (nnext) { if (AVL_END(tree, nnext) <= start) break; nnext = nnext->avl_parent; } if (nnext) { /* * nnext will be null if newnode is * the least element, and hence very first in the list. */ ASSERT(nnext->avl_nextino == parent); nnext->avl_nextino = newnode; } } else { parent->avl_forw = newnode; newnode->avl_nextino = parent->avl_nextino; parent->avl_nextino = newnode; } }
/* * Returns a pointer to node which contains exact value. */ avlnode_t * avl_find( register avltree_desc_t *tree, register __psunsigned_t value) { register avlnode_t *np = tree->avl_root; register __psunsigned_t nvalue; while (np) { nvalue = AVL_START(tree, np); if (value < nvalue) { np = np->avl_back; continue; } if (value == nvalue) { return np; } np = np->avl_forw; } return NULL; }
/* * Returns a pointer to node which contains exact value. */ avlnode_t * avl_find( avltree_desc_t *tree, uintptr_t value) { avlnode_t *np = tree->avl_root; uintptr_t nvalue; while (np) { nvalue = AVL_START(tree, np); if (value < nvalue) { np = np->avl_back; continue; } if (value == nvalue) { return np; } np = np->avl_forw; } return NULL; }
avlnode_t * avl_insert( register avltree_desc_t *tree, register avlnode_t *newnode) { register avlnode_t *np; register __psunsigned_t start = AVL_START(tree, newnode); register __psunsigned_t end = AVL_END(tree, newnode); int growth; ASSERT(newnode); ASSERT(start <= end); /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if ((np = tree->avl_root) == NULL) { /* degenerate case... */ tree->avl_root = newnode; tree->avl_firstino = newnode; return newnode; } if ((np = avl_insert_find_growth(tree, start, end, &growth)) == NULL) { if (start != end) { /* non-zero length range */ fprintf(stderr, _("avl_insert: Warning! duplicate range [%llu,%llu]\n"), (unsigned long long)start, (unsigned long long)end); } return(NULL); } avl_insert_grow(tree, np, newnode, growth); if (growth == AVL_BACK) { /* * Growing to left. if np was firstino, newnode will be firstino */ if (tree->avl_firstino == np) tree->avl_firstino = newnode; } #ifdef notneeded else if (growth == AVL_FORW) /* * Cannot possibly be firstino; there is somebody to our left. */ ; #endif newnode->avl_parent = np; CERT(np->avl_forw == newnode || np->avl_back == newnode); avl_balance(&tree->avl_root, np, growth); avl_checktree(tree, tree->avl_root); return newnode; }
/* * avl_findanyrange: * * Given range r [start, end), find any range which is contained in r. * if checklen is non-zero, then only ranges of non-zero length are * considered in finding a match. */ avlnode_t * avl_findanyrange( register avltree_desc_t *tree, register __psunsigned_t start, register __psunsigned_t end, int checklen) { register avlnode_t *np = tree->avl_root; /* np = avl_findadjacent(tree, start, AVL_SUCCEED); */ while (np) { if (start < AVL_START(tree, np)) { if (np->avl_back) { np = np->avl_back; continue; } /* if we were to add node with start, would * have a growth of AVL_BACK */ /* if succeeding node is needed, this is it. */ break; } if (start >= AVL_END(tree, np)) { if (np->avl_forw) { np = np->avl_forw; continue; } /* if we were to add node with start, would * have a growth of AVL_FORW; */ /* we are looking for a succeeding node; * this is nextino. */ np = np->avl_nextino; break; } /* AVL_START(tree, np) <= start < AVL_END(tree, np) */ break; } if (np) { if (checklen == AVL_INCLUDE_ZEROLEN) { if (end <= AVL_START(tree, np)) { /* something follows start, but is * is entierly after the range (end) */ return(NULL); } /* np may stradle [start, end) */ return(np); } /* * find non-zero length region */ while (np && (AVL_END(tree, np) - AVL_START(tree, np) == 0) && (AVL_START(tree, np) < end)) np = np->avl_nextino; if ((np == NULL) || (AVL_START(tree, np) >= end)) return NULL; return(np); } /* * nothing succeeds start, all existing ranges are before start. */ return NULL; }
static void avl_printnode(avltree_desc_t *tree, avlnode_t *np, int nl) { printf("[%d-%d]%c", AVL_START(tree, np), (AVL_END(tree, np) - 1), nl ? '\n' : ' '); }