コード例 #1
0
ファイル: hat-trie.c プロジェクト: gitter-badger/knot
int hattrie_find_leq (hattrie_t* T, const char* key, size_t len, value_t** dst)
{
    /* create node stack for traceback */
    size_t sp = 0;
    node_ptr bs[NODESTACK_INIT];  /* base stack (will be enough mostly) */
    node_ptr *ns = bs;            /* generic ptr, could point to new mem */
    ns[sp] = T->root;

    /* find node for given key */
    int ret = 1; /* no node on the left matches */
    node_ptr node = hattrie_find_ns(&ns, &sp, NODESTACK_INIT, &key, &len);
    if (node.flag == NULL) {
        *dst = hattrie_walk_left(ns, sp, key, hattrie_find_rightmost);
        if (ns != bs) free(ns);
        if (*dst) {
            return -1; /* found previous */
        }
        return 1; /* no previous key found */
    }

    /* assign value from trie or find in table */
    if (*node.flag & NODE_TYPE_TRIE) {
        *dst = &node.t->val;
        ret = 0;     /* found exact match */
    } else {
        *dst = hhash_find(node.b, key, len);
        if (*dst) {
            ret = 0; /* found exact match */
        } else {     /* look for previous in hashtable */
            ret = hhash_find_leq(node.b, key, len, dst);
        }
    }

    /* return if found equal or left in hashtable */
    if (*dst == 0) {
        /* we're retracing from pure bucket, pop the key */
        if (*node.flag & NODE_TYPE_PURE_BUCKET) {
            --key;
        }
        /* walk up the stack of visited nodes and find closest match on the left */
        *dst = hattrie_walk_left(ns, sp, key, hattrie_find_rightmost);
        if (*dst) {
            ret = -1; /* found previous */
        } else {
            ret = 1; /* no previous key found */
        }
    }

    if (ns != bs) free(ns);
    return ret;
}
コード例 #2
0
ファイル: hat-trie.c プロジェクト: nice-redbull/knot
int hattrie_find_lpr (hattrie_t* T, const char* key, size_t len, value_t** dst)
{
    /* create node stack for traceback */
    int ret = -1;
    size_t sp = 0;
    node_ptr bs[NODESTACK_INIT];  /* base stack (will be enough mostly) */
    node_ptr *ns = bs;            /* generic ptr, could point to new mem */
    ns[sp] = T->root;
    *dst = NULL;

    /* consume trie nodes for key (thus building prefix chain) */
    node_ptr node = hattrie_find_ns(&ns, &sp, NODESTACK_INIT, &key, &len);
    if (node.flag == NULL) {
        if (sp == 0) { /* empty trie, no prefix match */
            if (ns != bs) free(ns);
            return -1;
        }
        node = ns[--sp]; /* dead end, pop node */
    }

    /* search for suffix in current node */
    size_t suffix = len; /* suffix length */
    if (*node.flag & NODE_TYPE_TRIE) {
        *dst = &node.t->val; /* use current trie node value */
    } else {
        while (*dst == NULL) { /* find remainder in current ahtable */
            *dst = ahtable_tryget(node.b, key, suffix);
            if (suffix == 0)
                break;
            --suffix;
        }
    }

    /* not in current node, need to traceback node stack */
    while (*dst == NULL) {
        node = ns[sp]; /* parent node, always a trie node type */
        if (*node.flag & NODE_HAS_VAL)
            *dst = &node.t->val;
        if (sp == 0)
            break;
        --sp;
    }

    if (*dst) { /* prefix found? */
        ret = 0;
    }

    if (ns != bs) free(ns);
    return ret;
}
コード例 #3
0
ファイル: hat-trie.c プロジェクト: gitter-badger/knot
int hattrie_find_next (hattrie_t* T, const char* key, size_t len, value_t **dst)
{
    /* create node stack for traceback */
    size_t sp = 0;
    node_ptr bs[NODESTACK_INIT];  /* base stack (will be enough mostly) */
    node_ptr *ns = bs;            /* generic ptr, could point to new mem */
    ns[sp] = T->root;

    /* find node for given key */
    node_ptr ptr = hattrie_find_ns(&ns, &sp, NODESTACK_INIT, &key, &len);
    if (ptr.flag == NULL) {
        *dst = hattrie_walk_right(ns, sp, key, hattrie_find_leftmost);
        if (ns != bs) free(ns);
        if (*dst) {
            return 0; /* found next. */
        } else {
            return 1; /* no next key found. */
        }
    }

    int ret = 0;
    if (*ptr.flag & NODE_TYPE_TRIE) {
        /* Get next using walk. */
        ret = 1;
    } else {
        ret = hhash_find_next(ptr.b, key, len, dst);
    }

    if (ret == 1) {
        /* we're retracing from pure bucket, pop the key. */
        if (*ptr.flag & NODE_TYPE_PURE_BUCKET) {
            --key;
        }
        *dst = hattrie_walk_right(ns, sp, key, hattrie_find_leftmost);
        if (ns != bs) free(ns);
        if (*dst) {
            ret = 0; /* found next. */
        } else {
            ret = 1; /* no next key found. */
        }
    }

    return ret;
}
コード例 #4
0
ファイル: hat-trie.c プロジェクト: gitter-badger/knot
/* find node in trie */
static inline node_ptr hattrie_find(node_ptr *parent, const char **key, size_t *len)
{
    size_t sp = 0;
    return hattrie_find_ns(&parent, &sp, 0, key, len);
}