fed72131878c3fb51d4412f0ccfdf707993e86cb
[platform/upstream/libdatrie.git] / tests / test_store-retrieve.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * libdatrie - Double-Array Trie Library
4  * Copyright (C) 2013  Theppitak Karoonboonyanan <theppitak@gmail.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 /*
22  * test_store-retrieve.c - Test for datrie store/retrieve operations
23  * Created: 2013-10-16
24  * Author:  Theppitak Karoonboonyanan <theppitak@gmail.com>
25  */
26
27 #include <datrie/trie.h>
28 #include "utils.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32
33 int
34 main ()
35 {
36     Trie         *test_trie;
37     DictRec      *dict_p;
38     TrieData      trie_data;
39     Bool          is_failed;
40     int           n_entries, n_dels, i;
41     TrieState    *trie_root_state;
42     TrieIterator *trie_it;
43
44     msg_step ("Preparing trie");
45     test_trie = en_trie_new ();
46     if (!test_trie) {
47         fprintf (stderr, "Fail to create test trie\n");
48         goto err_trie_not_created;
49     }
50
51     /* store */
52     msg_step ("Adding data to trie");
53     for (dict_p = dict_src; dict_p->key; dict_p++) {
54         if (!trie_store (test_trie, dict_p->key, dict_p->data)) {
55             printf ("Failed to add key '%ls', data %d.\n",
56                     dict_p->key, dict_p->data);
57             goto err_trie_created;
58         }
59     }
60
61     /* retrieve */
62     msg_step ("Retrieving data from trie");
63     is_failed = FALSE;
64     for (dict_p = dict_src; dict_p->key; dict_p++) {
65         if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) {
66             printf ("Failed to retrieve key '%ls'.\n", dict_p->key);
67             is_failed = TRUE;
68         }
69         if (trie_data != dict_p->data) {
70             printf ("Wrong data for key '%ls'; expected %d, got %d.\n",
71                     dict_p->key, dict_p->data, trie_data);
72             is_failed = TRUE;
73         }
74     }
75     if (is_failed) {
76         printf ("Trie store/retrieval test failed.\n");
77         goto err_trie_created;
78     }
79
80     /* delete */
81     msg_step ("Deleting some entries from trie");
82     n_entries = dict_src_n_entries ();
83     srand (time (NULL));
84     for (n_dels = n_entries/3 + 1; n_dels > 0; n_dels--) {
85         /* pick an undeleted entry */
86         do {
87             i = rand () % n_entries;
88         } while (TRIE_DATA_READ == dict_src[i].data);
89
90         printf ("Deleting '%ls'\n", dict_src[i].key);
91         if (!trie_delete (test_trie, dict_src[i].key)) {
92             printf ("Failed to delete '%ls'\n", dict_src[i].key);
93             is_failed = TRUE;
94         }
95         dict_src[i].data = TRIE_DATA_READ;
96     }
97     if (is_failed) {
98         printf ("Trie deletion test failed.\n");
99         goto err_trie_created;
100     }
101
102     /* retrieve */
103     msg_step ("Retrieving data from trie again after deletions");
104     for (dict_p = dict_src; dict_p->key; dict_p++) {
105         /* skip deleted entries */
106         if (TRIE_DATA_READ == dict_p->data)
107             continue;
108
109         if (!trie_retrieve (test_trie, dict_p->key, &trie_data)) {
110             printf ("Failed to retrieve key '%ls'.\n", dict_p->key);
111             is_failed = TRUE;
112         }
113         if (trie_data != dict_p->data) {
114             printf ("Wrong data for key '%ls'; expected %d, got %d.\n",
115                     dict_p->key, dict_p->data, trie_data);
116             is_failed = TRUE;
117         }
118     }
119     if (is_failed) {
120         printf ("Trie retrival-after-deletion test failed.\n");
121         goto err_trie_created;
122     }
123
124     /* enumerate & check */
125     msg_step ("Iterating trie contents after deletions");
126     trie_root_state = trie_root (test_trie);
127     if (!trie_root_state) {
128         printf ("Failed to get trie root state\n");
129         goto err_trie_created;
130     }
131     trie_it = trie_iterator_new (trie_root_state);
132     if (!trie_it) {
133         printf ("Failed to get trie iterator\n");
134         goto err_trie_root_created;
135     }
136
137     while (trie_iterator_next (trie_it)) {
138         AlphaChar *key;
139         TrieData   key_data, src_data;
140
141         key = trie_iterator_get_key (trie_it);
142         if (!key) {
143             printf ("Failed to get key from trie iterator\n");
144             is_failed = TRUE;
145             continue;
146         }
147         key_data = trie_iterator_get_data (trie_it);
148         if (TRIE_DATA_ERROR == key_data) {
149             printf ("Failed to get data from trie iterator for key '%ls'\n",
150                     key);
151             is_failed = TRUE;
152         }
153         /* mark entries found in trie */
154         src_data = dict_src_get_data (key);
155         if (TRIE_DATA_ERROR == src_data) {
156             printf ("Extra entry in trie: key '%ls', data %d.\n",
157                     key, key_data);
158             is_failed = TRUE;
159         } else if (src_data != key_data) {
160             printf ("Data mismatch for: key '%ls', expected %d, got %d.\n",
161                     key, src_data, key_data);
162             is_failed = TRUE;
163         } else {
164             dict_src_set_data (key, TRIE_DATA_READ);
165         }
166
167         free (key);
168     }
169
170     /* check for unmarked entries, (i.e. missed in trie) */
171     for (dict_p = dict_src; dict_p->key; dict_p++) {
172         if (dict_p->data != TRIE_DATA_READ) {
173             printf ("Entry missed in trie: key '%ls', data %d.\n",
174                     dict_p->key, dict_p->data);
175             is_failed = TRUE;
176         }
177     }
178
179     if (is_failed) {
180         printf ("Errors found in trie iteration after deletions.\n");
181         goto err_trie_it_created;
182     }
183
184     trie_iterator_free (trie_it);
185     trie_state_free (trie_root_state);
186     trie_free (test_trie);
187     return 0;
188
189 err_trie_it_created:
190     trie_iterator_free (trie_it);
191 err_trie_root_created:
192     trie_state_free (trie_root_state);
193 err_trie_created:
194     trie_free (test_trie);
195 err_trie_not_created:
196     return 1;
197 }
198
199 /*
200 vi:ts=4:ai:expandtab
201 */