コード例 #1
0
ファイル: trie.c プロジェクト: svn2github/datrie
Bool
trie_store (Trie *trie, const TrieChar *key, TrieData data)
{
    TrieIndex        s, t;
    short            suffix_idx;
    const TrieChar  *p;
    size_t           len;

    /* walk through branches */
    s = da_get_root (trie->da);
    for (p = key; !trie_da_is_separate (trie->da, s); p++) {
        if (!da_walk (trie->da, &s, *p))
            return trie_branch_in_branch (trie, s, p, data);
        if ('\0' == *p)
            break;
    }

    /* walk through tail */
    t = trie_da_get_tail_index (trie->da, s);
    if ('\0' != *p) {
        suffix_idx = 0;
        len = strlen ((const char *) p) + 1;    /* including null-terminator */
        if (tail_walk_str (trie->tail, t, &suffix_idx, p, len) != len)
            return trie_branch_in_tail (trie, s, p, data);
    }

    /* duplicated key, overwrite val */
    tail_set_data (trie->tail, t, data);
    return TRUE;
}
コード例 #2
0
ファイル: trie.c プロジェクト: svn2github/datrie
Bool
trie_retrieve (Trie *trie, const TrieChar *key, TrieData *o_data)
{
    TrieIndex        s;
    short            suffix_idx;
    const TrieChar  *p;
    size_t           len;

    /* walk through branches */
    s = da_get_root (trie->da);
    for (p = key; !trie_da_is_separate (trie->da, s); p++) {
        if (!da_walk (trie->da, &s, *p))
            return FALSE;
        if ('\0' == *p)
            break;
    }

    /* walk through tail */
    s = trie_da_get_tail_index (trie->da, s);
    if ('\0' != *p) {
        suffix_idx = 0;
        len = strlen ((const char *) p) + 1;    /* including null-terminator */
        if (tail_walk_str (trie->tail, s, &suffix_idx, p, len) != len)
            return FALSE;
    }

    /* found, set the val and return */
    if (o_data)
        *o_data = tail_get_data (trie->tail, s);
    return TRUE;
}
コード例 #3
0
ファイル: trie.c プロジェクト: Rustem/datrie
/**
 * @brief Get data from terminal state
 *
 * @param s    : a terminal state
 *
 * @return the data associated with the terminal state @a s,
 *         or TRIE_DATA_ERROR if @a s is not a terminal state
 *
 */
TrieData
trie_state_get_terminal_data (const TrieState *s)
{
    TrieIndex        tail_index;
    TrieIndex index = s->index;

    if (!s)
        return TRIE_DATA_ERROR;

    if (!s->is_suffix){
        if (!trie_da_is_separate(s->trie->da, index)) {
            /* walk to a terminal char to get the data */
            Bool ret = da_walk (s->trie->da, &index, TRIE_CHAR_TERM);
            if (!ret) {
                return TRIE_DATA_ERROR;
            }
        }
        tail_index = trie_da_get_tail_index (s->trie->da, index);
    }
    else {
        tail_index = s->index;
    }

    return tail_get_data (s->trie->tail, tail_index);
}
コード例 #4
0
ファイル: trie.c プロジェクト: svn2github/datrie
static Bool
trie_store_conditionally (Trie            *trie,
                          const AlphaChar *key,
                          TrieData         data,
                          Bool             is_overwrite)
{
    TrieIndex        s, t;
    short            suffix_idx;
    const AlphaChar *p, *sep;

    /* walk through branches */
    s = da_get_root (trie->da);
    for (p = key; !trie_da_is_separate (trie->da, s); p++) {
        if (!da_walk (trie->da, &s,
                      alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            TrieChar *key_str;
            Bool      res;

            key_str = alpha_map_char_to_trie_str (trie->alpha_map, p);
            res = trie_branch_in_branch (trie, s, key_str, data);
            free (key_str);

            return res;
        }
        if (0 == *p)
            break;
    }

    /* walk through tail */
    sep = p;
    t = trie_da_get_tail_index (trie->da, s);
    suffix_idx = 0;
    for ( ; ; p++) {
        if (!tail_walk_char (trie->tail, t, &suffix_idx,
                             alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            TrieChar *tail_str;
            Bool      res;

            tail_str = alpha_map_char_to_trie_str (trie->alpha_map, sep);
            res = trie_branch_in_tail (trie, s, tail_str, data);
            free (tail_str);

            return res;
        }
        if (0 == *p)
            break;
    }

    /* duplicated key, overwrite val if flagged */
    if (!is_overwrite) {
        return FALSE;
    }
    tail_set_data (trie->tail, t, data);
    trie->is_dirty = TRUE;
    return TRUE;
}
コード例 #5
0
ファイル: trie.c プロジェクト: svn2github/datrie
Bool
trie_state_walk (TrieState *s, const TrieChar c)
{
    if (!s->is_suffix) {
        Bool ret;

        ret = da_walk (s->trie->da, &s->index, c);

        if (ret && trie_da_is_separate (s->trie->da, s->index)) {
            s->index = trie_da_get_tail_index (s->trie->da, s->index);
            s->suffix_idx = 0;
            s->is_suffix = TRUE;
        }

        return ret;
    } else {
        return tail_walk_char (s->trie->tail, s->index, &s->suffix_idx, c);
    }
}
コード例 #6
0
ファイル: trie.c プロジェクト: svn2github/datrie
/**
 * @brief Get data for the entry referenced by an iterator
 *
 * @param iter  : an iterator
 *
 * @return the data associated with the entry referenced by iterator @a iter,
 *         or TRIE_DATA_ERROR if @a iter does not reference to a unique entry
 *
 * Get value for the entry referenced by an iterator. Getting value from an
 * un-iterated (or broken for any reason) iterator will result in
 * TRIE_DATA_ERROR.
 *
 * Available since: 0.2.6
 */
TrieData
trie_iterator_get_data (const TrieIterator *iter)
{
    const TrieState *s = iter->state;
    TrieIndex        tail_index;

    if (!s)
        return TRIE_DATA_ERROR;

    if (!s->is_suffix) {
        if (!trie_da_is_separate (s->trie->da, s->index))
            return TRIE_DATA_ERROR;

        tail_index = trie_da_get_tail_index (s->trie->da, s->index);
    } else {
        tail_index = s->index;
    }

    return tail_get_data (s->trie->tail, tail_index);
}
コード例 #7
0
ファイル: trie.c プロジェクト: svn2github/datrie
/**
 * @brief Walk the trie from the state
 *
 * @param s    : current state
 * @param c    : key character for walking
 *
 * @return boolean value indicating the success of the walk
 *
 * Walk the trie stepwise, using a given character @a c.
 * On return, the state @a s is updated to the new state if successfully walked.
 */
Bool
trie_state_walk (TrieState *s, AlphaChar c)
{
    TrieChar tc = alpha_map_char_to_trie (s->trie->alpha_map, c);

    if (!s->is_suffix) {
        Bool ret;

        ret = da_walk (s->trie->da, &s->index, tc);

        if (ret && trie_da_is_separate (s->trie->da, s->index)) {
            s->index = trie_da_get_tail_index (s->trie->da, s->index);
            s->suffix_idx = 0;
            s->is_suffix = TRUE;
        }

        return ret;
    } else {
        return tail_walk_char (s->trie->tail, s->index, &s->suffix_idx, tc);
    }
}
コード例 #8
0
ファイル: trie.c プロジェクト: svn2github/datrie
/**
 * @brief Delete an entry from trie
 *
 * @param trie  : the trie
 * @param key   : the key for the entry to delete
 *
 * @return boolean value indicating whether the key exists and is removed
 *
 * Delete an entry for the given @a key from @a trie.
 */
Bool
trie_delete (Trie *trie, const AlphaChar *key)
{
    TrieIndex        s, t;
    short            suffix_idx;
    const AlphaChar *p;

    /* walk through branches */
    s = da_get_root (trie->da);
    for (p = key; !trie_da_is_separate (trie->da, s); p++) {
        if (!da_walk (trie->da, &s,
                      alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            return FALSE;
        }
        if (0 == *p)
            break;
    }

    /* walk through tail */
    t = trie_da_get_tail_index (trie->da, s);
    suffix_idx = 0;
    for ( ; ; p++) {
        if (!tail_walk_char (trie->tail, t, &suffix_idx,
                             alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            return FALSE;
        }
        if (0 == *p)
            break;
    }

    tail_delete (trie->tail, t);
    da_set_base (trie->da, s, TRIE_INDEX_ERROR);
    da_prune (trie->da, s);

    trie->is_dirty = TRUE;
    return TRUE;
}
コード例 #9
0
ファイル: trie.c プロジェクト: svn2github/datrie
/**
 * @brief Retrieve an entry from trie
 *
 * @param trie   : the trie
 * @param key    : the key for the entry to retrieve
 * @param o_data : the storage for storing the entry data on return
 *
 * @return boolean value indicating the existence of the entry.
 *
 * Retrieve an entry for the given @a key from @a trie. On return,
 * if @a key is found and @a o_data is not NULL, @a *o_data is set
 * to the data associated to @a key.
 */
Bool
trie_retrieve (const Trie *trie, const AlphaChar *key, TrieData *o_data)
{
    TrieIndex        s;
    short            suffix_idx;
    const AlphaChar *p;

    /* walk through branches */
    s = da_get_root (trie->da);
    for (p = key; !trie_da_is_separate (trie->da, s); p++) {
        if (!da_walk (trie->da, &s,
                      alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            return FALSE;
        }
        if (0 == *p)
            break;
    }

    /* walk through tail */
    s = trie_da_get_tail_index (trie->da, s);
    suffix_idx = 0;
    for ( ; ; p++) {
        if (!tail_walk_char (trie->tail, s, &suffix_idx,
                             alpha_map_char_to_trie (trie->alpha_map, *p)))
        {
            return FALSE;
        }
        if (0 == *p)
            break;
    }

    /* found, set the val and return */
    if (o_data)
        *o_data = tail_get_data (trie->tail, s);
    return TRUE;
}