Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/**
 * @brief Rewind a trie state
 *
 * @param s    : the state to rewind
 *
 * Put the state at root.
 */
void
trie_state_rewind(trie_state_t s)
{
	s->index = da_get_root(s->trie->da);
	s->suffixp = false;
	return;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
static int
trie_store_maybe(trie_t trie, const char *key, trie_data_t d, int overwritep)
{
	trie_idx_t s, t;
	short int suffix_idx;
	const char *p, *sep;

	/* walk through branches */
	s = da_get_root(trie->da);
	for (p = key; !trie_da_separate_p(trie->da, s); p++) {
		if (da_walk(trie->da, &s, alpha_map_char_to_trie(*p)) < 0) {
			char *key_str;
			int res;

			key_str = alpha_map_char_to_trie_str(p);
			res = trie_branch_in_branch(trie, s, key_str, d);
			free(key_str);

			return res;
		}
		if (*p == '\0') {
			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(*p)) < 0) {
			char *tail_str;
			int res;

			tail_str = alpha_map_char_to_trie_str(sep);
			res = trie_branch_in_tail(trie, s, tail_str, d);
			free(tail_str);
			return res;
		}
		if (*p == '\0') {
			break;
		}
	}

	/* duplicated key, overwrite val if flagged */
	if (!overwritep) {
		return -1;
	}
	tail_set_data(trie->tail, t, d);
	trie->dirtyp = 1;
	return 0;
}
Ejemplo n.º 6
0
/**
 * @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.
 */
int
trie_delete(trie_t trie, const char *key)
{
	trie_idx_t s, t;
	short int suffix_idx;
	const char *p;

	/* walk through branches */
	s = da_get_root(trie->da);
	for (p = key; !trie_da_separate_p(trie->da, s); p++) {
		if (da_walk(trie->da, &s, alpha_map_char_to_trie(*p)) < 0) {
			return -1;
		}
		if (*p == 0) {
			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(*p)) < 0) {
			return -1;
		}
		if (*p == 0) {
			break;
		}
	}

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

	trie->dirtyp = 1;
	return 0;
}
Ejemplo n.º 7
0
/**
 * @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;
}
Ejemplo n.º 8
0
/**
 * @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.
 */
int
trie_retrieve(const_trie_t trie, const char *key, trie_data_t *o_data)
{
	trie_idx_t s;
	short int suffix_idx;
	const char *p;

	/* walk through branches */
	s = da_get_root(trie->da);
	for (p = key; !trie_da_separate_p(trie->da, s); p++) {
		if (da_walk(trie->da, &s, alpha_map_char_to_trie(*p)) < 0) {
			return -1;
		}
		if (*p == 0) {
			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(*p)) < 0) {
			return -1;
		}
		if (*p == 0) {
			break;
		}
	}

	/* found, set the val and return */
	if (o_data) {
		*o_data = tail_get_data(trie->tail, s);
	}
	return 0;
}
Ejemplo n.º 9
0
static TrieChar *
da_get_state_key   (const DArray   *d,
                    TrieIndex       state)
{
    TrieChar   *key;
    int         key_size, key_length;
    int         i;

    key_size = 20;
    key_length = 0;
    key = (TrieChar *) malloc (key_size);

    /* trace back to root */
    while (da_get_root (d) != state) {
        TrieIndex   parent;

        if (key_length + 1 >= key_size) {
            key_size += 20;
            key = (TrieChar *) realloc (key, key_size);
        }
        parent = da_get_check (d, state);
        key[key_length++] = (TrieChar) (state - da_get_base (d, parent));
        state = parent;
    }
    key[key_length] = '\0';

    /* reverse the string */
    for (i = 0; i < --key_length; i++) {
        TrieChar temp;

        temp = key[i];
        key[i] = key[key_length];
        key[key_length] = temp;
    }

    return key;
}
Ejemplo n.º 10
0
/**
 * @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;
}
Ejemplo n.º 11
0
/**
 * @brief Get root state of a trie
 *
 * @param trie : the trie
 *
 * @return the root state of the trie
 *
 * Get root state of @a trie, for stepwise walking.
 *
 * The returned state is allocated and must be freed with trie_state_free()
 */
trie_state_t
trie_root(const_trie_t trie)
{
	return make_trie_state(trie, da_get_root(trie->da), 0, false);
}
Ejemplo n.º 12
0
/**
 * @brief Enumerate entries stored in double-array structure
 *
 * @param d          : the double-array structure
 * @param enum_func  : the callback function to be called on each separate node
 * @param user_data  : user-supplied data to send as an argument to @a enum_func
 *
 * @return boolean value indicating whether all the keys are visited
 *
 * Enumerate all keys stored in double-array structure. For each entry, the 
 * user-supplied @a enum_func callback function is called, with the entry key,
 * the separate node, and user-supplied data. Returning FALSE from such
 * callback will stop enumeration and return FALSE.
 */
Bool
da_enumerate (const DArray *d, DAEnumFunc enum_func, void *user_data)
{
    return da_enumerate_recursive (d, da_get_root (d), enum_func, user_data);
}
Ejemplo n.º 13
0
/**
 * @brief Prune the single branch
 *
 * @param d : the double-array structure
 * @param s : the dangling state to prune off
 *
 * Prune off a non-separate path up from the final state @a s.
 * If @a s still has some children states, it does nothing. Otherwise, 
 * it deletes the node and all its parents which become non-separate.
 */
void
da_prune (DArray *d, TrieIndex s)
{
    da_prune_upto (d, da_get_root (d), s);
}
Ejemplo n.º 14
0
/**
 * @brief Rewind a trie state
 *
 * @param s    : the state to rewind
 *
 * Put the state at root.
 */
void
trie_state_rewind (TrieState *s)
{
    s->index      = da_get_root (s->trie->da);
    s->is_suffix  = FALSE;
}
Ejemplo n.º 15
0
/**
 * @brief Get root state of a trie
 *
 * @param trie : the trie
 *
 * @return the root state of the trie
 *
 * Get root state of @a trie, for stepwise walking.
 *
 * The returned state is allocated and must be freed with trie_state_free()
 */
TrieState *
trie_root (const Trie *trie)
{
    return trie_state_new (trie, da_get_root (trie->da), 0, FALSE);
}