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
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 #3
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;
}