Пример #1
0
struct rb_node *
rb_node_create (void *value) {
    return rb_node_init(rb_node_alloc(), value);
}
Пример #2
0
/**
   Insert value.

   Returns 1 if value was inserted, 0 if the value is already stored,
   and -1 in case of error (e.g., memory allocation failure).
*/
int bst_insert(rb_tree_t *tree, void *key, size_t key_len,
               void *val, size_t val_len, rb_node_t **new_node)
{
    rb_node_t *parent = NULL, *curr = tree->root;
    rb_key_t insert_key = { .data = (void *)key, .len = key_len };

    if (!curr) {
        /* Insert root */
        tree->root = rb_node_alloc(key, key_len, val, val_len, parent);

        if (!tree->root)
            return -1;

        if (new_node)
            *new_node = tree->root;

        LOG_DBG("Added new root\n");

        return 1;
    }

    while (1) {
        int comp;

        parent = curr;

        comp = tree->ops->key_compare(&insert_key, &curr->key);

        /*
          if (comp == 0) {
          //LOG_DBG("element exists\n");
          return 0;
          } else
        */
        if (comp < 0) {
            curr = curr->left;
            //LOG_DBG("\tgoing left\n");

            if (!curr) {
                /* Insert new node at found location */
                curr = rb_node_alloc(key, key_len, val, val_len, parent);
                parent->left = curr;
                break;
            }
        } else {
            curr = curr->right;
            //LOG_DBG("\tgoing right\n");

            if (!curr) {
                /* Insert new node at found location */
                curr = rb_node_alloc(key, key_len, val, val_len, parent);
                parent->right = curr;
                break;
            }
        }
    }

    LOG_DBG("\tnew node: %s\n", tree->ops->value_print(&curr->val));
    LOG_DBG("\tparent: %s\n", tree->ops->value_print(&parent->val));

    if (new_node)
        *new_node = curr;

    return curr ? 1 : -1;
}

static inline rb_node_t *grandparent(rb_node_t *node)
{
    if (node && node->parent)
        return node->parent->parent;
    return NULL;
}

static inline rb_node_t *uncle(rb_node_t *node)
{
    rb_node_t *gp = grandparent(node);

    if (gp == NULL)
        return NULL;

    if (node->parent == gp->left)
        return gp->right;

    return gp->left;
}