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); }
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); }
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 }
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); }
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; }