Example #1
0
/**
 * @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;
}
Example #2
0
File: trie.c Project: kritik/trie
/*
 * 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;
}
Example #3
0
static void
brk_shot_destruct (BrkShot *shot)
{
    if (shot->dict_state)
        trie_state_free (shot->dict_state);
    if (shot->brk_pos)
        free (shot->brk_pos);
}
Example #4
0
void
sb_trie_state_free (SBTrieState *s)
{
    if (!s)
        return;

    trie_state_free (s->trie_state);
    free (s);
}
Example #5
0
/**
 * @brief Free a trie iterator
 *
 * @param  iter  : the trie iterator to free
 *
 * Destruct the iterator @a iter and free its allocated memory.
 *
 * Available since: 0.2.6
 */
void
trie_iterator_free (TrieIterator *iter)
{
    if (iter->state) {
        trie_state_free (iter->state);
    }
    if (iter->key) {
        trie_string_free (iter->key);
    }
    free (iter);
}
Example #6
0
File: trie.c Project: kritik/trie
/*
 * call-seq:
 *   value
 *
 * Attempts to get the value at this node of the Trie.  This only works if the node is a terminal 
 * (i.e. end of a key), otherwise it returns nil.
 *
 */
static VALUE rb_trie_node_value(VALUE self) {
    TrieState *state;
	TrieState *dup;
    Data_Get_Struct(self, TrieState, state);
    
    dup = trie_state_clone(state);

    trie_state_walk(dup, 0);
    TrieData trie_data = trie_state_get_data(dup);
    trie_state_free(dup);

    return TRIE_DATA_ERROR == trie_data ? Qnil : (VALUE)trie_data;
}
Example #7
0
Bool
trie_state_is_leaf (const TrieState *s)
{
    TrieState *t;
    Bool       ret;

    t = trie_state_clone (s);

    ret = trie_state_walk (t, TRIE_CHAR_TERM);

    trie_state_free (t);

    return ret;
}
Example #8
0
File: trie.c Project: kritik/trie
static VALUE walk_all_paths(Trie *trie, VALUE children, TrieState *state, char *prefix, int prefix_size) {
	int c;
    for(c = 1; c < 256; c++) {
		if(trie_state_is_walkable(state,c)) {
			TrieState *next_state = trie_state_clone(state);
			trie_state_walk(next_state, c);

			prefix[prefix_size] = c;
			prefix[prefix_size + 1] = 0;

			if(trie_state_is_terminal(next_state)) {
				char *word = (char*) malloc(prefix_size + 2);
				memcpy(word, prefix, prefix_size + 2);
				rb_ary_push(children, rb_str_new2(word));
			}

			walk_all_paths(trie, children, next_state, prefix, prefix_size + 1);
			
			prefix[prefix_size] = 0;
			trie_state_free(next_state);
		}
    }
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
void ATTrie :: freePosition(ATTrie::Position p)
{
    trie_state_free((TrieState*)p);
}
Example #12
0
void
sb_trie_state_free (SBTrieState *s)
{
    trie_state_free (s->trie_state);
    free (s);
}