Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
0
/**
 * @brief Test walkability of character from state
 *
 * @param s    : the state to check
 * @param c    : the input character
 *
 * @return boolean indicating walkability
 *
 * Test if there is a transition from state @a s with input character @a c.
 */
bool
trie_state_walkable_p(const_trie_state_t s, char c)
{
	char tc = alpha_map_char_to_trie(c);

	if (!s->suffixp) {
		return da_walkable_p(s->trie->da, s->index, tc);
	}
	/* otherwise */
	return tail_walkable_char_p(s->trie->tail, s->index, s->suffix_idx, tc);
}
Beispiel #4
0
/**
 * @brief Test walkability of character from state
 *
 * @param s    : the state to check
 * @param c    : the input character
 *
 * @return boolean indicating walkability
 *
 * Test if there is a transition from state @a s with input character @a c.
 */
Bool
trie_state_is_walkable (const TrieState *s, AlphaChar c)
{
    TrieChar tc = alpha_map_char_to_trie (s->trie->alpha_map, c);

    if (!s->is_suffix)
        return da_is_walkable (s->trie->da, s->index, tc);
    else
        return tail_is_walkable_char (s->trie->tail, s->index, s->suffix_idx,
                                      tc);
}
Beispiel #5
0
static char*
alpha_map_char_to_trie_str(const char *str)
{
	char *trie_str, *p;

	trie_str = malloc(strlen(str) + 1);
	for (p = trie_str; *str; p++, str++) {
		*p = alpha_map_char_to_trie(*str);
	}
	*p = 0;
	return trie_str;
}
Beispiel #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;
}
Beispiel #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;
}
Beispiel #8
0
TrieChar *
alpha_map_char_to_trie_str (const AlphaMap *alpha_map, const AlphaChar *str)
{
    TrieChar   *trie_str, *p;

    trie_str = (TrieChar *) malloc (alpha_char_strlen (str) + 1);
    for (p = trie_str; *str; p++, str++) {
        *p = alpha_map_char_to_trie (alpha_map, *str);
    }
    *p = 0;

    return trie_str;
}
Beispiel #9
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;
}
Beispiel #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;
}
Beispiel #11
0
/**
 * @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.
 */
int
trie_state_walk(trie_state_t s, char c)
{
	char tc = alpha_map_char_to_trie(c);

	if (!s->suffixp) {
		int ret = da_walk(s->trie->da, &s->index, tc);

		if (ret == 0 && trie_da_separate_p(s->trie->da, s->index)) {
			s->index = trie_da_get_tail_index(s->trie->da, s->index);
			s->suffix_idx = 0;
			s->suffixp = true;
		}

		return ret;
	}
	/* otherwise */
	return tail_walk_char(s->trie->tail, s->index, &s->suffix_idx, tc);
}
Beispiel #12
0
/**
 * @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);
    }
}
Beispiel #13
0
TrieChar *
alpha_map_char_to_trie_str (const AlphaMap *alpha_map, const AlphaChar *str)
{
    TrieChar   *trie_str, *p;

    trie_str = (TrieChar *) malloc (alpha_char_strlen (str) + 1);
    if (UNLIKELY (!trie_str))
        return NULL;

    for (p = trie_str; *str; p++, str++) {
        TrieIndex tc = alpha_map_char_to_trie (alpha_map, *str);
        if (TRIE_INDEX_MAX == tc)
            goto error_str_allocated;
        *p = (TrieChar) tc;
    }
    *p = 0;

    return trie_str;

error_str_allocated:
    free (trie_str);
    return NULL;
}