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; }
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; }
/** * @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); }
/** * @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); }
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; }
/** * @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; }
/** * @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; }
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; }
/** * @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; }
/** * @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; }
/** * @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); }
/** * @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); } }
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; }