Beispiel #1
0
static rxt_node* get_internal_custom(char *key, rxt_node *root, rxt_compare_method compare_method)
{
    int match;
    if (!root) 
    {
        return NULL;
    }

    if (root->color) 
    {
        if (2 == root->color) 
        {
            root = (rxt_node *)root->value;
        }

        match = compare_method(key, root);
        if (match)
        {
            return root;
        }
        else
        {
            return NULL;
        }
        return NULL;
    }

    if (get_bit_at(key, root->pos))
    {
        return get_internal_custom(key, root->right, compare_method);
    }
    return get_internal_custom(key, root->left, compare_method);
}
Beispiel #2
0
static rxt_node* get_internal(char *key, rxt_node *root)
{
    int equal = 1;
    char *route_token;
    char *route_token_ptr;
    char *request_token;
    char *request_token_ptr;
    char prefix;

    if (!root) return NULL;

    if (root->color) 
    {
        if (2 == root->color) 
        {
            root = (rxt_node *)root->value;
        }

        route_token = strtok_r(root->key, "/", &route_token_ptr);
        request_token = strtok_r(key, "/", &request_token_ptr);
        while (route_token != NULL && request_token != NULL)
        {
            if (route_token == NULL || request_token == NULL)
                break;

            prefix = *route_token;
            if (prefix == '$')
            {
                // Variable substitution.
            }
            else
            {
                if (strncasecmp(route_token, request_token, 0))
                {
                    equal = 0;
                    break;
                }
            }
            
            //printf ("ROUTE:%s\tREQUEST:%s\n", route_token, request_token);
            route_token = strtok_r(NULL, "/", &route_token_ptr);
            request_token = strtok_r(NULL, "/", &request_token_ptr);
        }

        if (equal)
        {
            return root;
        }
        return NULL;
    }

    if (get_bit_at(key, root->pos))
    {
        return get_internal(key, root->right);
    }
    return get_internal(key, root->left);
}
Beispiel #3
0
int rxt_put(char *key, void *value, rxt_node *n)
{
#define NEWLEAF(nl, k, v) \
    nl = (rxt_node *)malloc(sizeof(rxt_node)); \
    if (!nl) return -1; \
    strncpy(nl->keycache, k, RADIXTREE_KEYSIZE); \
    nl->keycache[RADIXTREE_KEYSIZE-1] = '\0'; \
    nl->key = nl->keycache; \
    nl->pos = keylen(k); \
    nl->value = v; \
    nl->color = 1; \
    nl->parent = n; \
    nl->left = NULL; \
    nl->right = NULL

    rxt_node *newleaf;
    NEWLEAF(newleaf, key, value);

    // this special case takes care of the first two entries
    if (!(n->left || n->right)) {
        rxt_node *sib;
        int bits;
        // create root
        if (!n->value) {
            // attach root
            n->color = 2;
            n->value = newleaf;
            return 0;
        }
        // else convert root to inner and attach leaves
        sib = (rxt_node *)n->value;

        // count bits in common
        bits = count_common_bits(key, sib->key,
                    rdx_min(newleaf->pos, sib->pos));


        if (get_bit_at(key, bits)) {
            n->right = newleaf;
            n->left = sib;
        } else {
            n->right = sib;
            n->left = newleaf;
        }
        n->value = NULL;
        n->key = sib->key;
        n->pos = bits;
        n->color = 0;
        return 0;
    }

    newleaf->parent = NULL; // null for now

    return insert_internal(newleaf, n);

#undef NEWLEAF
}
Beispiel #4
0
static rxt_node* get_internal(char *key, rxt_node *root)
{
    if (!root) return NULL;

    if (root->color) {
        if (2 == root->color) root = root->value;
        if (!strncmp(key, root->key, root->pos))
            return root;
        return NULL;
    }

    if (get_bit_at(key, root->pos))
        return get_internal(key, root->right);
    return get_internal(key, root->left);
}
Beispiel #5
0
static int insert_leaf(rxt_node *newleaf, rxt_node *sibling, rxt_node *parent)
{
    int idx, bit, max_len;
    rxt_node *inner;


    max_len = rdx_min(newleaf->pos, sibling->pos);
    idx  = count_common_bits(newleaf->key, sibling->key, max_len);
    bit = get_bit_at(newleaf->key, idx);

    if (!parent) {
        // insert at the root, so rotate things like so:
/*
           /\    to     /\
          1  2         /\ 3
                      1  2                   */

        parent = sibling;
        inner = (rxt_node *)malloc(sizeof(rxt_node));
        if (!inner) return -1;
        inner->color = 0;
        inner->value = NULL;
        inner->parent = parent;
        inner->left = parent->left;
        inner->right = parent->right;
        inner->key = parent->key;
        inner->pos = parent->pos;
        parent->pos = idx;
        parent->left->parent = inner;
        parent->right->parent = inner;
        newleaf->parent = parent;
        if (bit) {
            parent->right = newleaf;
            parent->left = inner;
        } else {
            parent->right = inner;
            parent->left = newleaf;
        }
        return 0;
    }

    if (idx < parent->pos) {
        // use the parent as a sibling
        return insert_leaf(newleaf, parent, parent->parent);
    } else {
        // otherwise, add newleaf as a child of inner

        // Check for duplicates.
        // FIXME feels hackish; do this properly.
        if (newleaf->pos == sibling->pos &&
            !strncmp(newleaf->key, sibling->key, newleaf->pos)) {
            free(newleaf);
            return -1;
        }

        inner = (rxt_node *)malloc(sizeof(rxt_node));
        if (!inner) free(inner);
        inner->color = 0;
        inner->value = NULL;
        inner->parent = parent;
        inner->pos = idx;
        inner->key = sibling->key;
        newleaf->parent = inner;
        sibling->parent = inner;

        if (bit) {
            inner->right = newleaf;
            inner->left = sibling;
        } else {
            inner->right = sibling;
            inner->left = newleaf;
        }

        // now find out which branch of parent to assign inner
        if (parent->left == sibling)
            parent->left = inner;
        else if (parent->right == sibling)
            parent->right = inner;
        else {
            fprintf(stderr, "inappropriate child %s/%s found in parent when inserting leaf %s (expected %s)\n", parent->left->key, parent->right->key, newleaf->key, sibling->key);
            return -1;
        }
    }
    return 0;
}