1#include <string.h>
2
3#include <marisa_alpha.h>
4
5#include "assert.h"
6
7void TestHandle(void) {
8  marisa_alpha_trie *trie = NULL;
9
10  TEST_START();
11
12  ASSERT(marisa_alpha_init(&trie) == MARISA_ALPHA_OK);
13  ASSERT(marisa_alpha_init(&trie) == MARISA_ALPHA_HANDLE_ERROR);
14  ASSERT(marisa_alpha_end(trie) == MARISA_ALPHA_OK);
15  ASSERT(marisa_alpha_end(NULL) == MARISA_ALPHA_HANDLE_ERROR);
16
17  ASSERT(marisa_alpha_build(NULL, NULL, 0, NULL, NULL, NULL, 0) ==
18      MARISA_ALPHA_HANDLE_ERROR);
19
20  ASSERT(marisa_alpha_mmap(NULL, NULL, 0, 0) == MARISA_ALPHA_HANDLE_ERROR);
21  ASSERT(marisa_alpha_map(NULL, NULL, 0) == MARISA_ALPHA_HANDLE_ERROR);
22
23  ASSERT(marisa_alpha_load(NULL, NULL, 0, 0) == MARISA_ALPHA_HANDLE_ERROR);
24  ASSERT(marisa_alpha_fread(NULL, NULL) == MARISA_ALPHA_HANDLE_ERROR);
25  ASSERT(marisa_alpha_read(NULL, 0) == MARISA_ALPHA_HANDLE_ERROR);
26
27  ASSERT(marisa_alpha_save(NULL, NULL, 0, 0, 0) == MARISA_ALPHA_HANDLE_ERROR);
28  ASSERT(marisa_alpha_fwrite(NULL, NULL) == MARISA_ALPHA_HANDLE_ERROR);
29  ASSERT(marisa_alpha_write(NULL, 0) == MARISA_ALPHA_HANDLE_ERROR);
30
31  ASSERT(marisa_alpha_restore(NULL, 0, NULL, 0, NULL) ==
32      MARISA_ALPHA_HANDLE_ERROR);
33
34  ASSERT(marisa_alpha_lookup(NULL, NULL, 0, NULL) ==
35      MARISA_ALPHA_HANDLE_ERROR);
36
37  ASSERT(marisa_alpha_find(NULL, NULL, 0, NULL, NULL, 0, NULL) ==
38      MARISA_ALPHA_HANDLE_ERROR);
39  ASSERT(marisa_alpha_find_first(NULL, NULL, 0, NULL, NULL) ==
40      MARISA_ALPHA_HANDLE_ERROR);
41  ASSERT(marisa_alpha_find_last(NULL, NULL, 0, NULL, NULL) ==
42      MARISA_ALPHA_HANDLE_ERROR);
43  ASSERT(marisa_alpha_find_callback(NULL, NULL, 0, NULL, NULL) ==
44      MARISA_ALPHA_HANDLE_ERROR);
45
46  ASSERT(marisa_alpha_predict(NULL, NULL, 0, NULL, 0, NULL) ==
47      MARISA_ALPHA_HANDLE_ERROR);
48  ASSERT(marisa_alpha_predict_breadth_first(NULL, NULL, 0, NULL, 0, NULL) ==
49      MARISA_ALPHA_HANDLE_ERROR);
50  ASSERT(marisa_alpha_predict_depth_first(NULL, NULL, 0, NULL, 0, NULL) ==
51      MARISA_ALPHA_HANDLE_ERROR);
52  ASSERT(marisa_alpha_predict_callback(NULL, NULL, 0, NULL, NULL) ==
53      MARISA_ALPHA_HANDLE_ERROR);
54
55  ASSERT(marisa_alpha_get_num_tries(NULL) == 0);
56  ASSERT(marisa_alpha_get_num_keys(NULL) == 0);
57  ASSERT(marisa_alpha_get_num_nodes(NULL) == 0);
58  ASSERT(marisa_alpha_get_total_size(NULL) == 0);
59
60  ASSERT(marisa_alpha_clear(NULL) == MARISA_ALPHA_HANDLE_ERROR);
61
62  TEST_END();
63}
64
65int callback_for_find(void *num_keys,
66    marisa_alpha_uint32 key_id, size_t key_length) {
67  ASSERT(*(size_t *)num_keys == 0);
68  ASSERT(key_id == 1);
69  ASSERT(key_length == 3);
70  ++*(size_t *)num_keys;
71  return 1;
72}
73
74int callback_for_predict(void *num_keys,
75    marisa_alpha_uint32 key_id, const char *key, size_t key_length) {
76  ASSERT(*(size_t *)num_keys < 2);
77  switch (*(size_t *)num_keys) {
78    case 0: {
79      ASSERT(key_id == 0);
80      ASSERT(key_length == 3);
81      ASSERT(strcmp(key, "app") == 0);
82      break;
83    }
84    case 1: {
85      ASSERT(key_id == 3);
86      ASSERT(key_length == 5);
87      ASSERT(strcmp(key, "apple") == 0);
88      break;
89    }
90  }
91  ++*(size_t *)num_keys;
92  return 1;
93}
94
95void TestTrie() {
96  marisa_alpha_trie *trie = NULL;
97  const char *keys[8];
98  marisa_alpha_uint32 key_ids[8];
99  size_t i;
100  char key_buf[16];
101  size_t key_length;
102  marisa_alpha_uint32 key_id;
103  marisa_alpha_uint32 found_key_ids[8];
104  size_t found_key_lengths[8];
105  size_t num_found_keys;
106
107  TEST_START();
108
109  ASSERT(marisa_alpha_init(&trie) == MARISA_ALPHA_OK);
110
111  ASSERT(marisa_alpha_get_num_tries(trie) == 0);
112  ASSERT(marisa_alpha_get_num_keys(trie) == 0);
113  ASSERT(marisa_alpha_get_num_nodes(trie) == 0);
114  ASSERT(marisa_alpha_get_total_size(trie) ==
115      (sizeof(marisa_alpha_uint32) * 23));
116
117  ASSERT(marisa_alpha_build(trie, NULL, 0, NULL, NULL, NULL, 0) ==
118      MARISA_ALPHA_OK);
119
120  ASSERT(marisa_alpha_get_num_tries(trie) == 1);
121  ASSERT(marisa_alpha_get_num_keys(trie) == 0);
122  ASSERT(marisa_alpha_get_num_nodes(trie) == 1);
123
124  keys[0] = "apple";
125  keys[1] = "and";
126  keys[2] = "Bad";
127  keys[3] = "apple";
128  keys[4] = "app";
129
130  ASSERT(marisa_alpha_build(trie, keys, 5, NULL, NULL, key_ids,
131      1 | MARISA_ALPHA_WITHOUT_TAIL | MARISA_ALPHA_LABEL_ORDER) ==
132      MARISA_ALPHA_OK);
133
134  ASSERT(marisa_alpha_get_num_tries(trie) == 1);
135  ASSERT(marisa_alpha_get_num_keys(trie) == 4);
136  ASSERT(marisa_alpha_get_num_nodes(trie) == 11);
137
138  ASSERT(key_ids[0] == 3);
139  ASSERT(key_ids[1] == 1);
140  ASSERT(key_ids[2] == 0);
141  ASSERT(key_ids[3] == 3);
142  ASSERT(key_ids[4] == 2);
143
144  for (i = 0; i < marisa_alpha_get_num_tries(trie); ++i) {
145    ASSERT(marisa_alpha_restore(trie,
146        key_ids[i], key_buf, sizeof(key_buf), &key_length) == MARISA_ALPHA_OK);
147    ASSERT(key_length == strlen(keys[i]));
148    ASSERT(strcmp(key_buf, keys[i]) == 0);
149
150    ASSERT(marisa_alpha_lookup(trie,
151        keys[i], MARISA_ALPHA_ZERO_TERMINATED, &key_id) == MARISA_ALPHA_OK);
152    ASSERT(key_id == key_ids[i]);
153
154    ASSERT(marisa_alpha_lookup(trie,
155        keys[i], strlen(keys[i]), &key_id) == MARISA_ALPHA_OK);
156    ASSERT(key_id == key_ids[i]);
157  }
158
159  ASSERT(marisa_alpha_clear(trie) == MARISA_ALPHA_OK);
160
161  ASSERT(marisa_alpha_get_num_tries(trie) == 0);
162  ASSERT(marisa_alpha_get_num_keys(trie) == 0);
163  ASSERT(marisa_alpha_get_num_nodes(trie) == 0);
164  ASSERT(marisa_alpha_get_total_size(trie) ==
165      (sizeof(marisa_alpha_uint32) * 23));
166
167  ASSERT(marisa_alpha_build(trie, keys, 5, NULL, NULL, key_ids,
168      1 | MARISA_ALPHA_WITHOUT_TAIL | MARISA_ALPHA_WEIGHT_ORDER) ==
169      MARISA_ALPHA_OK);
170
171  ASSERT(marisa_alpha_get_num_tries(trie) == 1);
172  ASSERT(marisa_alpha_get_num_keys(trie) == 4);
173  ASSERT(marisa_alpha_get_num_nodes(trie) == 11);
174
175  ASSERT(key_ids[0] == 3);
176  ASSERT(key_ids[1] == 1);
177  ASSERT(key_ids[2] == 2);
178  ASSERT(key_ids[3] == 3);
179  ASSERT(key_ids[4] == 0);
180
181  ASSERT(marisa_alpha_find(trie, "ap", MARISA_ALPHA_ZERO_TERMINATED,
182      found_key_ids, found_key_lengths, 8, &num_found_keys) ==
183      MARISA_ALPHA_OK);
184  ASSERT(num_found_keys == 0);
185
186  ASSERT(marisa_alpha_find(trie, "applex", MARISA_ALPHA_ZERO_TERMINATED,
187      found_key_ids, found_key_lengths, 8, &num_found_keys) ==
188      MARISA_ALPHA_OK);
189  ASSERT(num_found_keys == 2);
190  ASSERT(found_key_ids[0] == key_ids[4]);
191  ASSERT(found_key_lengths[0] == 3);
192  ASSERT(found_key_ids[1] == key_ids[0]);
193  ASSERT(found_key_lengths[1] == 5);
194
195  num_found_keys = 0;
196  ASSERT(marisa_alpha_find_callback(trie, "anderson",
197      MARISA_ALPHA_ZERO_TERMINATED,
198      callback_for_find, &num_found_keys) == MARISA_ALPHA_OK);
199  ASSERT(num_found_keys == 1);
200
201  ASSERT(marisa_alpha_predict(trie, "a", MARISA_ALPHA_ZERO_TERMINATED,
202      found_key_ids, 8, &num_found_keys) == MARISA_ALPHA_OK);
203  ASSERT(num_found_keys == 3);
204  ASSERT(found_key_ids[0] == key_ids[4]);
205  ASSERT(found_key_ids[1] == key_ids[1]);
206  ASSERT(found_key_ids[2] == key_ids[0]);
207
208  num_found_keys = 0;
209  ASSERT(marisa_alpha_predict_callback(trie, "app",
210      MARISA_ALPHA_ZERO_TERMINATED,
211      callback_for_predict, &num_found_keys) == MARISA_ALPHA_OK);
212
213  ASSERT(marisa_alpha_end(trie) == MARISA_ALPHA_OK);
214
215  TEST_END();
216}
217
218int main(void) {
219  TestHandle();
220  TestTrie();
221
222  return 0;
223}
224