/** * @brief Enumerate entries in trie * * @param trie : the trie * @param enum_func : the callback function to be called on each key * @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 entries in trie. For each entry, the user-supplied * @a enum_func callback function is called, with the entry key and data. * Returning FALSE from such callback will stop enumeration and return FALSE. */ Bool trie_enumerate (const Trie *trie, TrieEnumFunc enum_func, void *user_data) { TrieState *root; TrieIterator *iter; Bool cont = TRUE; root = trie_root (trie); if (!root) return FALSE; iter = trie_iterator_new (root); if (!iter) goto exit_root_created; while (cont && trie_iterator_next (iter)) { AlphaChar *key = trie_iterator_get_key (iter); TrieData data = trie_iterator_get_data (iter); cont = (*enum_func) (key, data, user_data); free (key); } trie_iterator_free (iter); trie_state_free (root); return cont; exit_root_created: trie_state_free (root); return FALSE; }
/* * call-seq: * children(prefix) -> [ key, ... ] * * Finds all keys in the Trie beginning with the given prefix. * */ static VALUE rb_trie_children(VALUE self, VALUE prefix) { if(NIL_P(prefix)) return rb_ary_new(); StringValue(prefix); Trie *trie; Data_Get_Struct(self, Trie, trie); int prefix_size = RSTRING_LEN(prefix); TrieState *state = trie_root(trie); VALUE children = rb_ary_new(); TrieChar *char_prefix = (TrieChar*)RSTRING_PTR(prefix); const TrieChar *iterator = char_prefix; while(*iterator != 0) { if(!trie_state_is_walkable(state, *iterator)) return children; trie_state_walk(state, *iterator); iterator++; } if(trie_state_is_terminal(state)) rb_ary_push(children, prefix); char prefix_buffer[1024]; memcpy(prefix_buffer, char_prefix, prefix_size); prefix_buffer[prefix_size] = 0; walk_all_paths(trie, children, state, prefix_buffer, prefix_size); trie_state_free(state); return children; }
static BrkPool * brk_root_pool (int pos_size) { Trie *dict; BrkPool *pool; BrkPool *node; BrkShot root_shot; pool = NULL; if (NULL == (dict = brk_get_dict())) return NULL; root_shot.dict_state = trie_root (dict); root_shot.brk_pos = NULL; /* it's not used anyway */ root_shot.n_brk_pos = pos_size; root_shot.str_pos = root_shot.cur_brk_pos = 0; root_shot.penalty = 0; node = brk_pool_node_new (&root_shot); if (node) { pool = brk_pool_add (pool, node); } brk_shot_destruct (&root_shot); return pool; }
/* * call-seq: * root -> TrieNode * * Returns a TrieNode representing the root of the Trie. * */ static VALUE rb_trie_root(VALUE self) { Trie *trie; Data_Get_Struct(self, Trie, trie); VALUE trie_node = rb_trie_node_alloc(cTrieNode); TrieState *state = trie_root(trie); RDATA(trie_node)->data = state; return trie_node; }
/* * call-seq: * root -> TrieNode * * Returns a TrieNode representing the root of the Trie. * */ static VALUE rb_trie_root(VALUE self) { Trie *trie; Data_Get_Struct(self, Trie, trie); VALUE trie_node = rb_trie_node_alloc(cTrieNode); TrieState *state = trie_root(trie); RDATA(trie_node)->data = state; rb_iv_set(trie_node, "@state", Qnil); rb_iv_set(trie_node, "@full_state", rb_str_new2("")); return trie_node; }
SBTrieState * sb_trie_root (SBTrie *sb_trie) { SBTrieState *sb_state; sb_state = (SBTrieState *) malloc (sizeof (SBTrieState)); if (!sb_state) return NULL; sb_state->sb_trie = sb_trie; sb_state->trie_state = trie_root (sb_trie->trie); return sb_state; }
int main () { Trie *test_trie; DictRec *dict_p; TrieState *trie_root_state; TrieIterator *trie_it; Bool is_failed; msg_step ("Preparing trie"); test_trie = en_trie_new (); if (!test_trie) { fprintf (stderr, "Fail to create test trie\n"); goto err_trie_not_created; } /* store */ msg_step ("Adding data to trie"); for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_store (test_trie, dict_p->key, dict_p->data)) { printf ("Failed to add key '%ls', data %d.\n", dict_p->key, dict_p->data); goto err_trie_created; } } /* iterate & check */ msg_step ("Iterating and checking trie contents"); trie_root_state = trie_root (test_trie); if (!trie_root_state) { printf ("Failed to get trie root state\n"); goto err_trie_created; } trie_it = trie_iterator_new (trie_root_state); if (!trie_it) { printf ("Failed to get trie iterator\n"); goto err_trie_root_created; } is_failed = FALSE; while (trie_iterator_next (trie_it)) { AlphaChar *key; TrieData key_data, src_data; key = trie_iterator_get_key (trie_it); if (!key) { printf ("Failed to get key from trie iterator\n"); is_failed = TRUE; continue; } key_data = trie_iterator_get_data (trie_it); if (TRIE_DATA_ERROR == key_data) { printf ("Failed to get data from trie iterator for key '%ls'\n", key); is_failed = TRUE; } /* mark entries found in trie */ src_data = dict_src_get_data (key); if (TRIE_DATA_ERROR == src_data) { printf ("Extra entry in trie: key '%ls', data %d.\n", key, key_data); is_failed = TRUE; } else if (src_data != key_data) { printf ("Data mismatch for: key '%ls', expected %d, got %d.\n", key, src_data, key_data); is_failed = TRUE; } else { dict_src_set_data (key, TRIE_DATA_READ); } free (key); } /* check for unmarked entries, (i.e. missed in trie) */ for (dict_p = dict_src; dict_p->key; dict_p++) { if (dict_p->data != TRIE_DATA_READ) { printf ("Entry missed in trie: key '%ls', data %d.\n", dict_p->key, dict_p->data); is_failed = TRUE; } } if (is_failed) { printf ("Errors found in trie iteration.\n"); goto err_trie_it_created; } trie_iterator_free (trie_it); trie_state_free (trie_root_state); trie_free (test_trie); return 0; err_trie_it_created: trie_iterator_free (trie_it); err_trie_root_created: trie_state_free (trie_root_state); err_trie_created: trie_free (test_trie); err_trie_not_created: return 1; }
int main (void) { Trie *test_trie; DictRec *dict_p; TrieData trie_data; Bool is_failed; int n_entries, n_dels, i; TrieState *trie_root_state; TrieIterator *trie_it; msg_step ("Preparing trie"); test_trie = en_trie_new (); if (!test_trie) { fprintf (stderr, "Fail to create test trie\n"); goto err_trie_not_created; } /* store */ msg_step ("Adding data to trie"); for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_store (test_trie, dict_p->key, dict_p->data)) { printf ("Failed to add key '%ls', data %d.\n", (wchar_t *)dict_p->key, dict_p->data); goto err_trie_created; } } /* retrieve */ msg_step ("Retrieving data from trie"); is_failed = FALSE; for (dict_p = dict_src; dict_p->key; dict_p++) { if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) { printf ("Failed to retrieve key '%ls'.\n", (wchar_t *)dict_p->key); is_failed = TRUE; } if (trie_data != dict_p->data) { printf ("Wrong data for key '%ls'; expected %d, got %d.\n", (wchar_t *)dict_p->key, dict_p->data, trie_data); is_failed = TRUE; } } if (is_failed) { printf ("Trie store/retrieval test failed.\n"); goto err_trie_created; } /* delete */ msg_step ("Deleting some entries from trie"); n_entries = dict_src_n_entries (); srand (time (NULL)); for (n_dels = n_entries/3 + 1; n_dels > 0; n_dels--) { /* pick an undeleted entry */ do { i = rand () % n_entries; } while (TRIE_DATA_READ == dict_src[i].data); printf ("Deleting '%ls'\n", (wchar_t *)dict_src[i].key); if (!trie_delete (test_trie, dict_src[i].key)) { printf ("Failed to delete '%ls'\n", (wchar_t *)dict_src[i].key); is_failed = TRUE; } dict_src[i].data = TRIE_DATA_READ; } if (is_failed) { printf ("Trie deletion test failed.\n"); goto err_trie_created; } /* retrieve */ msg_step ("Retrieving data from trie again after deletions"); for (dict_p = dict_src; dict_p->key; dict_p++) { /* skip deleted entries */ if (TRIE_DATA_READ == dict_p->data) continue; if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) { printf ("Failed to retrieve key '%ls'.\n", (wchar_t *)dict_p->key); is_failed = TRUE; } if (trie_data != dict_p->data) { printf ("Wrong data for key '%ls'; expected %d, got %d.\n", (wchar_t *)dict_p->key, dict_p->data, trie_data); is_failed = TRUE; } } if (is_failed) { printf ("Trie retrival-after-deletion test failed.\n"); goto err_trie_created; } /* enumerate & check */ msg_step ("Iterating trie contents after deletions"); trie_root_state = trie_root (test_trie); if (!trie_root_state) { printf ("Failed to get trie root state\n"); goto err_trie_created; } trie_it = trie_iterator_new (trie_root_state); if (!trie_it) { printf ("Failed to get trie iterator\n"); goto err_trie_root_created; } while (trie_iterator_next (trie_it)) { AlphaChar *key; TrieData key_data, src_data; key = trie_iterator_get_key (trie_it); if (!key) { printf ("Failed to get key from trie iterator\n"); is_failed = TRUE; continue; } key_data = trie_iterator_get_data (trie_it); if (TRIE_DATA_ERROR == key_data) { printf ("Failed to get data from trie iterator for key '%ls'\n", (wchar_t *)key); is_failed = TRUE; } /* mark entries found in trie */ src_data = dict_src_get_data (key); if (TRIE_DATA_ERROR == src_data) { printf ("Extra entry in trie: key '%ls', data %d.\n", (wchar_t *)key, key_data); is_failed = TRUE; } else if (src_data != key_data) { printf ("Data mismatch for: key '%ls', expected %d, got %d.\n", (wchar_t *)key, src_data, key_data); is_failed = TRUE; } else { dict_src_set_data (key, TRIE_DATA_READ); } free (key); } /* check for unmarked entries, (i.e. missed in trie) */ for (dict_p = dict_src; dict_p->key; dict_p++) { if (dict_p->data != TRIE_DATA_READ) { printf ("Entry missed in trie: key '%ls', data %d.\n", (wchar_t *)dict_p->key, dict_p->data); is_failed = TRUE; } } if (is_failed) { printf ("Errors found in trie iteration after deletions.\n"); goto err_trie_it_created; } trie_iterator_free (trie_it); trie_state_free (trie_root_state); trie_free (test_trie); return 0; err_trie_it_created: trie_iterator_free (trie_it); err_trie_root_created: trie_state_free (trie_root_state); err_trie_created: trie_free (test_trie); err_trie_not_created: return 1; }
ATTrie::Position ATTrie :: startWalk() { return (void*) trie_root(data->trie); }