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 17 namespace { 18 19 void 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 48 marisa::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 57 void 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 82 void 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 117 void 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 181 void 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 } 221 void 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 281 void 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 333 void 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 373 void 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 419 void 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 444 int 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