1#include <cstdlib>
2#include <ctime>
3
4#include <marisa/base.h>
5#include <marisa/popcount.h>
6#include <marisa/rank.h>
7#include <marisa/string.h>
8#include <marisa/key.h>
9#include <marisa/progress.h>
10#include <marisa/range.h>
11#include <marisa/query.h>
12#include <marisa/container.h>
13#include <marisa/cell.h>
14
15#include "assert.h"
16
17namespace {
18
19void TestBase() {
20  TEST_START();
21
22  ASSERT(sizeof(marisa_uint8) == 1);
23  ASSERT(sizeof(marisa_uint16) == 2);
24  ASSERT(sizeof(marisa_uint32) == 4);
25  ASSERT(sizeof(marisa_uint64) == 8);
26
27  ASSERT(MARISA_UINT8_MAX == 0xFFU);
28  ASSERT(MARISA_UINT16_MAX == 0xFFFFU);
29  ASSERT(MARISA_UINT32_MAX == 0xFFFFFFFFU);
30  ASSERT(MARISA_UINT64_MAX == 0xFFFFFFFFFFFFFFFFULL);
31
32  ASSERT(sizeof(marisa::UInt8) == 1);
33  ASSERT(sizeof(marisa::UInt16) == 2);
34  ASSERT(sizeof(marisa::UInt32) == 4);
35  ASSERT(sizeof(marisa::UInt64) == 8);
36
37  int x = 100, y = 200;
38  marisa::Swap(&x, &y);
39  ASSERT(x == 200);
40  ASSERT(y == 100);
41
42  EXCEPT(marisa::Swap(static_cast<int *>(NULL), &y), MARISA_PARAM_ERROR);
43  EXCEPT(marisa::Swap(&x, static_cast<int *>(NULL)), MARISA_PARAM_ERROR);
44
45  TEST_END();
46}
47
48marisa::UInt32 NaivePopCount(marisa::UInt32 x) {
49  marisa::UInt32 count = 0;
50  while (x) {
51    count += x & 1;
52    x >>= 1;
53  }
54  return count;
55}
56
57void TestPopCount() {
58  TEST_START();
59
60  ASSERT(marisa::PopCount(0).lo8() == 0);
61  ASSERT(marisa::PopCount(0).lo16() == 0);
62  ASSERT(marisa::PopCount(0).lo24() == 0);
63  ASSERT(marisa::PopCount(0).lo32() == 0);
64
65  ASSERT(marisa::PopCount(0xFFFFFFFFU).lo8() == 8);
66  ASSERT(marisa::PopCount(0xFFFFFFFFU).lo16() == 16);
67  ASSERT(marisa::PopCount(0xFFFFFFFFU).lo24() == 24);
68  ASSERT(marisa::PopCount(0xFFFFFFFFU).lo32() == 32);
69
70  for (std::size_t i = 0; i < 1024; ++i) {
71    marisa::UInt32 value = std::rand();
72    marisa::PopCount popcount(value);
73    ASSERT(popcount.lo8() == NaivePopCount(value & 0xFFU));
74    ASSERT(popcount.lo16() == NaivePopCount(value & 0xFFFFU));
75    ASSERT(popcount.lo24() == NaivePopCount(value & 0xFFFFFFU));
76    ASSERT(popcount.lo32() == NaivePopCount(value));
77  }
78
79  TEST_END();
80}
81
82void TestRank() {
83  TEST_START();
84
85  marisa::Rank rank;
86
87  ASSERT(rank.abs() == 0);
88  ASSERT(rank.rel1() == 0);
89  ASSERT(rank.rel2() == 0);
90  ASSERT(rank.rel3() == 0);
91  ASSERT(rank.rel4() == 0);
92  ASSERT(rank.rel5() == 0);
93  ASSERT(rank.rel6() == 0);
94  ASSERT(rank.rel7() == 0);
95
96  rank.set_abs(0xFFFFFFFFU);
97  rank.set_rel1(64);
98  rank.set_rel2(128);
99  rank.set_rel3(192);
100  rank.set_rel4(256);
101  rank.set_rel5(320);
102  rank.set_rel6(384);
103  rank.set_rel7(448);
104
105  ASSERT(rank.abs() == 0xFFFFFFFFU);
106  ASSERT(rank.rel1() == 64);
107  ASSERT(rank.rel2() == 128);
108  ASSERT(rank.rel3() == 192);
109  ASSERT(rank.rel4() == 256);
110  ASSERT(rank.rel5() == 320);
111  ASSERT(rank.rel6() == 384);
112  ASSERT(rank.rel7() == 448);
113
114  TEST_END();
115}
116
117void TestString() {
118  TEST_START();
119
120  marisa::String str;
121
122  ASSERT(str.ptr() == NULL);
123  ASSERT(str.length() == 0);
124
125  marisa::RString rstr;
126
127  ASSERT(rstr.ptr() == NULL);
128  ASSERT(rstr.length() == 0);
129
130  const char *s = "ab";
131  str = marisa::String(s);
132
133  ASSERT(str.ptr() == s);
134  ASSERT(str.length() == 2);
135  ASSERT(str[0] == s[0]);
136  ASSERT(str[1] == s[1]);
137
138  rstr = marisa::RString(str);
139  ASSERT(rstr.ptr() == s);
140  ASSERT(rstr.length() == 2);
141  ASSERT(rstr[0] == s[1]);
142  ASSERT(rstr[1] == s[0]);
143
144  std::string s2 = "xyz";
145  str = marisa::String(s2.c_str(), s2.length());
146
147  ASSERT(str.ptr() == s2.c_str());
148  ASSERT(str.length() == 3);
149  ASSERT(str[0] == s2[0]);
150  ASSERT(str[1] == s2[1]);
151  ASSERT(str[2] == s2[2]);
152
153  ASSERT(str.substr(0, 2).length() == 2);
154  ASSERT(str.substr(0, 2)[0] == 'x');
155  ASSERT(str.substr(0, 2)[1] == 'y');
156
157  rstr = marisa::RString(str);
158
159  ASSERT(rstr.ptr() == s2.c_str());
160  ASSERT(rstr.length() == 3);
161  ASSERT(rstr[0] == s2[2]);
162  ASSERT(rstr[1] == s2[1]);
163  ASSERT(rstr[2] == s2[0]);
164
165  ASSERT(rstr.substr(1, 2).length() == 2);
166  ASSERT(rstr.substr(1, 2)[0] == 'y');
167  ASSERT(rstr.substr(1, 2)[1] == 'x');
168
169  ASSERT(marisa::String("abc") == marisa::String("abc"));
170  ASSERT(marisa::String("abc") != marisa::String("bcd"));
171  ASSERT(marisa::String("abc") < marisa::String("bcd"));
172  ASSERT(marisa::String("ab") < marisa::String("abc"));
173  ASSERT(marisa::String("bcd") > marisa::String("abc"));
174  ASSERT(marisa::String("abc") > marisa::String("ab"));
175
176  ASSERT(marisa::String("abcde").substr(1, 2) == marisa::String("bc"));
177
178  TEST_END();
179}
180
181void TestKey() {
182  TEST_START();
183
184  marisa::Key<marisa::String> key;
185
186  ASSERT(key.str().length() == 0);
187  ASSERT(key.weight() == 0.0);
188  ASSERT(key.id() == 0);
189  ASSERT(key.terminal() == 0);
190
191  key.set_str(marisa::String("abc"));
192  key.set_weight(1.0);
193  key.set_id(2);
194  key.set_terminal(3);
195
196  ASSERT(key.str() == marisa::String("abc"));
197  ASSERT(key.weight() == 1.0);
198  ASSERT(key.id() == 2);
199  ASSERT(key.terminal() == 3);
200
201  marisa::String str("string");
202  marisa::Key<marisa::RString> rkey;
203
204  ASSERT(rkey.str().length() == 0);
205  ASSERT(rkey.weight() == 0.0);
206  ASSERT(rkey.id() == 0);
207  ASSERT(rkey.terminal() == 0);
208
209  rkey.set_str(marisa::RString(str));
210  rkey.set_weight(4.0);
211  rkey.set_id(5);
212  rkey.set_terminal(6);
213
214  ASSERT(rkey.str() == marisa::RString(str));
215  ASSERT(rkey.weight() == 4.0);
216  ASSERT(rkey.id() == 5);
217  ASSERT(rkey.terminal() == 6);
218
219  TEST_END();
220}
221void TestProgress() {
222  TEST_START();
223
224  {
225    marisa::Progress progress(0);
226
227    ASSERT(progress.is_valid());
228    while (!progress.is_last()) {
229      ++progress;
230    }
231    ASSERT(progress.is_last());
232    ASSERT(progress.flags() == MARISA_DEFAULT_FLAGS);
233    ASSERT(progress.trie_id() == progress.num_tries() - 1);
234    ASSERT(progress.total_size() == 0);
235
236    progress.test_total_size(0);
237    progress.test_total_size(1);
238    EXCEPT(progress.test_total_size(MARISA_UINT32_MAX), MARISA_SIZE_ERROR);
239    progress.test_total_size(MARISA_UINT32_MAX - 1);
240    progress.test_total_size(0);
241    EXCEPT(progress.test_total_size(1), MARISA_SIZE_ERROR);
242
243    ASSERT(progress.num_tries() == MARISA_DEFAULT_NUM_TRIES);
244    ASSERT(progress.trie() == MARISA_DEFAULT_TRIE);
245    ASSERT(progress.tail() == MARISA_DEFAULT_TAIL);
246    ASSERT(progress.order() == MARISA_DEFAULT_ORDER);
247  }
248
249  {
250    marisa::Progress progress(MARISA_DEFAULT_FLAGS);
251
252    ASSERT(progress.is_valid());
253    ASSERT(!progress.is_last());
254    ASSERT(progress.num_tries() == MARISA_DEFAULT_NUM_TRIES);
255    ASSERT(progress.trie() == MARISA_DEFAULT_TRIE);
256    ASSERT(progress.tail() == MARISA_DEFAULT_TAIL);
257    ASSERT(progress.order() == MARISA_DEFAULT_ORDER);
258  }
259
260  {
261    marisa::Progress progress(255 | MARISA_PREFIX_TRIE
262        | MARISA_BINARY_TAIL | MARISA_LABEL_ORDER);
263
264    ASSERT(progress.is_valid());
265    ASSERT(!progress.is_last());
266    ASSERT(progress.num_tries() == 255);
267    ASSERT(progress.trie() == MARISA_PREFIX_TRIE);
268    ASSERT(progress.tail() == MARISA_BINARY_TAIL);
269    ASSERT(progress.order() == MARISA_LABEL_ORDER);
270  }
271
272  {
273    marisa::Progress progress(~MARISA_FLAGS_MASK);
274
275    ASSERT(!progress.is_valid());
276  }
277
278  TEST_END();
279}
280
281void TestRange() {
282  TEST_START();
283
284  marisa::Range range;
285
286  ASSERT(range.begin() == 0);
287  ASSERT(range.end() == 0);
288  ASSERT(range.pos() == 0);
289
290  range.set_begin(1);
291  range.set_end(2);
292  range.set_pos(3);
293
294  ASSERT(range.begin() == 1);
295  ASSERT(range.end() == 2);
296  ASSERT(range.pos() == 3);
297
298  marisa::WRange wrange;
299
300  ASSERT(wrange.range().begin() == 0);
301  ASSERT(wrange.range().end() == 0);
302  ASSERT(wrange.range().pos() == 0);
303
304  ASSERT(wrange.begin() == 0);
305  ASSERT(wrange.end() == 0);
306  ASSERT(wrange.pos() == 0);
307  ASSERT(wrange.weight() == 0.0);
308
309  wrange = marisa::WRange(range, 4.0);
310
311  ASSERT(wrange.range().begin() == 1);
312  ASSERT(wrange.range().end() == 2);
313  ASSERT(wrange.range().pos() == 3);
314
315  ASSERT(wrange.begin() == 1);
316  ASSERT(wrange.end() == 2);
317  ASSERT(wrange.pos() == 3);
318  ASSERT(wrange.weight() == 4.0);
319
320  wrange.set_begin(5);
321  wrange.set_end(6);
322  wrange.set_pos(7);
323  wrange.set_weight(8.0);
324
325  ASSERT(wrange.begin() == 5);
326  ASSERT(wrange.end() == 6);
327  ASSERT(wrange.pos() == 7);
328  ASSERT(wrange.weight() == 8.0);
329
330  TEST_END();
331}
332
333void TestQuery() {
334  TEST_START();
335
336  marisa::Query query("abc", 3);
337
338  ASSERT(query[0] == 'a');
339  ASSERT(!query.ends_at(0));
340
341  ASSERT(query[1] == 'b');
342  ASSERT(!query.ends_at(1));
343
344  ASSERT(query[2] == 'c');
345  ASSERT(!query.ends_at(2));
346
347  ASSERT(query.ends_at(3));
348
349  std::string str("str");
350
351  query.insert(&str);
352  ASSERT(str == "abcstr");
353
354  marisa::CQuery cquery("xyz");
355
356  ASSERT(cquery[0] == 'x');
357  ASSERT(!cquery.ends_at(0));
358
359  ASSERT(cquery[1] == 'y');
360  ASSERT(!cquery.ends_at(1));
361
362  ASSERT(cquery[2] == 'z');
363  ASSERT(!cquery.ends_at(2));
364
365  ASSERT(cquery.ends_at(3));
366
367  cquery.insert(&str);
368  ASSERT(str == "xyzabcstr");
369
370  TEST_END();
371}
372
373void TestContainer() {
374  TEST_START();
375
376  int array[1024];
377  marisa::Container<int *> array_container(array);
378
379  ASSERT(array_container.is_valid());
380  for (int i = 0; i < 1024; ++i) {
381    int value = std::rand();
382    array_container.insert(i, value);
383    ASSERT(array[i] == value);
384  }
385
386  marisa::Container<int *> array_container2(NULL);
387
388  ASSERT(!array_container2.is_valid());
389
390  std::vector<int> vec;
391  marisa::Container<std::vector<int> *> vec_container(&vec);
392
393  ASSERT(vec_container.is_valid());
394  for (int i = 0; i < 1024; ++i) {
395    int value = std::rand();
396    vec_container.insert(i, value);
397    ASSERT(vec.back() == value);
398    ASSERT(vec[i] == value);
399  }
400  ASSERT(vec.size() == 1024);
401
402  marisa::Container<std::vector<int> *> vec_container2(&vec);
403
404  ASSERT(vec_container2.is_valid());
405  for (int i = 0; i < 1024; ++i) {
406    int value = std::rand();
407    vec_container2.insert(i, value);
408    ASSERT(vec.back() == value);
409    ASSERT(vec[i + 1024] == value);
410  }
411  ASSERT(vec.size() == 2048);
412
413  marisa::Container<std::vector<int> *> vec_container3(NULL);
414  ASSERT(!vec_container3.is_valid());
415
416  TEST_END();
417}
418
419void TestCell() {
420  TEST_START();
421
422  marisa::Cell cell;
423
424  ASSERT(cell.louds_pos() == 0);
425  ASSERT(cell.node() == 0);
426  ASSERT(cell.key_id() == 0);
427  ASSERT(cell.length() == 0);
428
429  cell.set_louds_pos(1);
430  cell.set_node(2);
431  cell.set_key_id(3);
432  cell.set_length(4);
433
434  ASSERT(cell.louds_pos() == 1);
435  ASSERT(cell.node() == 2);
436  ASSERT(cell.key_id() == 3);
437  ASSERT(cell.length() == 4);
438
439  TEST_END();
440}
441
442}  // namespace
443
444int main() {
445  std::srand((unsigned int)time(NULL));
446
447  TestBase();
448  TestPopCount();
449  TestRank();
450  TestString();
451  TestKey();
452  TestProgress();
453  TestRange();
454  TestQuery();
455  TestContainer();
456  TestCell();
457
458  return 0;
459}
460