Exemplo n.º 1
0
/**
 * Free resources used to hold information about the tree. This
 * function does not free memory pointed to by the data pointer
 * in a node - you have to free this memory by walking thru the
 * tree or use the callback version of rbt_free for a specific
 * tree type.
 * @param rbt tree pointer
 */
void rbt_free(rbt_t *rbt, void (*callback)(void *))
{
        struct rbt_node *stack[48], *n;
        register uint8_t depth;

        rbt_wlock(rbt);

        depth = 0;
        n = rbt_node_ptr(rbt->root);

        if (n != NULL) {
                rbt_walk_push(n);

                while(depth > 0) {
                        n = rbt_node_ptr(rbt_walk_top()->_chld[RBT_NODE_SL]);

                        if (n != NULL)
                                rbt_walk_push(n);
                        else {
                        __in:
                                if (callback != NULL)
                                        callback((void *)&(rbt_walk_top()->_node));

                                n = rbt_node_ptr(rbt_walk_top()->_chld[RBT_NODE_SR]);
                                free(rbt_walk_top());

                                if (n != NULL)
                                        rbt_walk_top() = n;
                                else {
                                        if (--depth > 0)
                                                goto __in;
                                        else
                                                break;
                                }
                        }
                }
        }
        rbt_wunlock(rbt);

        rbt->root = NULL;
        rbt->size = 0;
        rbt->type = -1;

#if defined(RBT_IMPLICIT_LOCKING)
        pthread_rwlock_destroy (&rbt->lock);
#endif
        free (rbt);
        return;
}
Exemplo n.º 2
0
/*
 * Add new entry to the tree. If `coll' is not NULL and there is
 * already an entry with the same key (i.e. a collision), then
 * place the old data pointer at `*coll' and update it to the
 * new data pointer. Otherwise, if `coll' is NULL and there is a
 * collision, then an error is returned and no modification of
 * the tree is made.
 *
 * @param rbt pointer to the tree
 * @param key key
 * @param data data pointer
 * @param coll where to store the data pointer from an colliding entry
 */
int rbt_i64_add(rbt_t *rbt, int64_t key, void *data, void **coll)
{
        struct rbt_node fake;
        register struct rbt_node *h[4];
        register uint8_t dvec;
        register int64_t n_key, u_key;

        u_key = key;
        rbt_wlock(rbt);

        /*
         * Fake node
         */
        fake._chld[RBT_NODE_SL] = NULL;
        fake._chld[RBT_NODE_SR] = rbt->root;
        rbt_node_setcolor(&fake, RBT_NODE_CB);

        /*
         * Prepare node history stack & direction history vector
         */
        h[3] = NULL;
        h[2] = NULL;
        h[1] = &fake;
        h[0] = rbt->root;
        dvec = RBT_NODE_SR;

        for (;;) {
                if (rbt_node_ptr(h[0]) == NULL) {
                        /*
                         * Allocate new node aligned to sizeof(void *) bytes.
                         * On most systems, malloc already returns aligned
                         * memory but we want to ensure that its aligned using
                         * posix_memalign(3).
                         */
                        h[0] = rbt_i64_node_alloc ();

                        rbt_i64_node(h[0])->key  = key;
                        rbt_i64_node(h[0])->data = data;

                        /*
                         * Set the new node as the child of the last node we've
                         * visited. The last direction is the lowest bit of the
                         * direction history vector.
                         */
                        rbt_node_setptr(rbt_node_ptr(h[1])->_chld[dvec & 1], h[0]);
                        rbt_node_setcolor(h[0], RBT_NODE_CR);

                        /*
                         * Since we are inserting a new red node, we need to fix
                         * a red violation if the parent of the new node is red.
                         */
                        if (rbt_node_getcolor(h[1]) == RBT_NODE_CR) {
                                rbt_redfix(h, dvec, rbt_node_ptr(h[3])->_chld[(dvec >> 2) & 1]);
                        }

                        /*
                         * Update root node and color it black
                         */
                        rbt->root = fake._chld[RBT_NODE_SR];
                        rbt_node_setcolor(rbt->root, RBT_NODE_CB);

                        /*
                         * Update node counter
                         */
                        ++(rbt->size);

                        break;
                } else if (rbt_node_getcolor(rbt_node_ptr(h[0])->_chld[0]) == RBT_NODE_CR &&
Exemplo n.º 3
0
static void rbt_i64_node_free(struct rbt_node *n)
{
        if (n != NULL)
                sm_free(rbt_node_ptr(n));
}