Пример #1
0
/**
 * @brief Find next separate node in a sub-trie
 *
 * @param d     : the double-array structure
 * @param root  : the sub-trie root to search from
 * @param sep   : the current separate node
 * @param keybuff : the TrieString buffer for incrementally calcuating key
 *
 * @return index to the next separate node; TRIE_INDEX_ERROR if no more
 *         separate node is found
 *
 * Find the next separate node under a sub-trie rooted at @a root starting
 * from the current separate node @a sep.
 *
 * On return, @a keybuff is incrementally updated from the key which walks
 * to previous separate node to the one which walks to the new separate node.
 * So, it is assumed to be initialized by at least one da_first_separate()
 * call before. This incremental key calculation is more efficient than later
 * totally reconstructing key from the given separate node.
 *
 * Available since: 0.2.6
 */
TrieIndex
da_next_separate (DArray *d, TrieIndex root, TrieIndex sep, TrieString *keybuff)
{
    TrieIndex parent;
    TrieIndex base;
    TrieIndex c, max_c;

    while (sep != root) {
        parent = da_get_check (d, sep);
        base = da_get_base (d, parent);
        c = sep - base;

        trie_string_cut_last (keybuff);

        /* find next sibling of sep */
        max_c = MIN_VAL (TRIE_CHAR_MAX, d->num_cells - base);
        while (++c <= max_c) {
            if (da_get_check (d, base + c) == parent) {
                trie_string_append_char (keybuff, c);
                return da_first_separate (d, base + c, keybuff);
            }
        }

        sep = parent;
    }

    return TRIE_INDEX_ERROR;
}
Пример #2
0
/**
 * @brief Move trie iterator to the next entry
 *
 * @param  iter  : an iterator
 *
 * @return boolean value indicating the availability of the entry
 *
 * Move trie iterator to the next entry.
 * On return, the iterator @a iter is updated to reference to the new entry
 * if successfully moved.
 *
 * Available since: 0.2.6
 */
Bool
trie_iterator_next (TrieIterator *iter)
{
    TrieState *s = iter->state;
    TrieIndex sep;

    /* first iteration */
    if (!s) {
        s = iter->state = trie_state_clone (iter->root);

        /* for tail state, we are already at the only entry */
        if (s->is_suffix)
            return TRUE;

        iter->key = trie_string_new (20);
        sep = da_first_separate (s->trie->da, s->index, iter->key);
        if (TRIE_INDEX_ERROR == sep)
            return FALSE;

        s->index = sep;
        return TRUE;
    }

    /* no next entry for tail state */
    if (s->is_suffix)
        return FALSE;

    /* iter->state is a separate node */
    sep = da_next_separate (s->trie->da, iter->root->index, s->index,
                            iter->key);
    if (TRIE_INDEX_ERROR == sep)
        return FALSE;

    s->index = sep;
    return TRUE;
}