/*
 * Insert an item to the tree.
 * Return 0 if a new node was created, 1 if a node was updated, or -1 on error.
 */
int
mtree_trie_insert(struct mtree_trie *trie, const char *key, void *item)
{
    struct mtree_trie_node	*u;
    struct mtree_trie_node	*node;
    size_t			 bit;

    assert(trie != NULL);
    assert(item != NULL);
    assert(key != NULL && *key != '\0');

    u = find_node(trie, key);
    if (u != NULL && strcmp(u->key, key) == 0) {
        /*
         * Already in the trie, just update the item.
         */
        if (trie->free_fn != NULL && u->item != NULL)
            trie->free_fn(u->item);
        u->item = item;
        return (1);
    }
    if ((node = create_node(key, item)) == NULL)
        return (-1);

    if (u == NULL) {
        /*
         * Trie is empty, insert to the left under the head.
         */
        for (bit = 0; KEY_BIT(key, node->key_len, bit) == 0; bit++)
            ;
        node->bit  = bit;
        node->left = trie->top;
        trie->top->left = node;
    } else {
        for (bit = 0;; bit++) {
            int kbit = KEY_BIT(key, node->key_len, bit);

            if (kbit != KEY_BIT(u->key, u->key_len, bit)) {
                if (kbit == 0)
                    node->right = NULL;
                else
                    node->left = NULL;
                node->bit = bit;
                break;
            }
        }
        trie->top->left = insert_node(trie->top->left, node, trie->top);
    }
    return (0);
}
Beispiel #2
0
static struct mtree_trie *
insert_node(struct mtree_trie *u, struct mtree_trie *node, struct mtree_trie *prev)
{

	if (u->bit >= node->bit || u->bit <= prev->bit) {
		if (node->left == node)
			node->right = u;
		else
			node->left = u;
		return (node);
	}
	if (KEY_BIT(node->key, node->key_len, u->bit) == 0)
		u->left = insert_node(u->left, node, u);
	else
		u->right = insert_node(u->right, node, u);
	return (u);
}
static struct mtree_trie_node *
find_node(struct mtree_trie *trie, const char *key)
{
    struct mtree_trie_node	*u;
    size_t			 len;
    size_t			 d;

    if (trie->top->left == trie->top)
        return (NULL);

    u   = trie->top->left;
    len = strlen(key);
    do {
        d = u->bit;
        u = KEY_BIT(key, len, d) == 0 ? u->left : u->right;
    } while (u != NULL && u->bit > d);

    return (u);
}