Exemple #1
0
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));
}
Exemple #2
0
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);
}
Exemple #3
0
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;
    }
}
Exemple #4
0
/*
 * 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;
}
Exemple #5
0
/*
 * 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;
}
Exemple #6
0
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;
}
Exemple #7
0
/*
 *	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;
}
Exemple #8
0
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' : ' ');
}