20 #include <glib/gstdio.h>
21 #include <cppcutter.h>
42 Thread() : thread_(NULL) {}
47 void create(GThreadFunc func, gpointer data) {
55 g_thread_join(thread_);
64 Thread(
const Thread &);
65 Thread &operator=(
const Thread &);
69 CutTestContext *cut_test_context;
74 void create_key(std::string *key, std::size_t min_length,
75 std::size_t max_length)
77 key->resize(min_length + (std::rand() % (max_length - min_length + 1)));
78 for (std::size_t
i = 0;
i < key->size(); ++
i) {
79 (*key)[
i] =
'0' + (std::rand() % 10);
83 void create_keys(std::vector<std::string> *keys, std::size_t num_keys,
84 std::size_t min_length, std::size_t max_length)
87 std::set<std::string> keyset;
88 while (keyset.size() < num_keys) {
89 create_key(&key, min_length, max_length);
92 std::vector<std::string>(keyset.begin(), keyset.end()).swap(*keys);
93 std::random_shuffle(keys->begin(), keys->end());
97 namespace test_dat_trie
103 std::srand(static_cast<unsigned int>(std::time(NULL)));
107 g_mkdir_with_parents(
base_dir, 0755);
143 std::vector<std::string> keys;
144 create_keys(&keys, 1000, 1, 16);
149 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
150 cppcut_assert_equal(
true,
151 trie.
insert(keys[
i].c_str(), keys[
i].length()));
152 cppcut_assert_equal(
true,
153 trie.
search(keys[
i].c_str(), keys[
i].length()));
161 std::strcat(trie_path,
"/test_trie_on_file.dat");
163 std::vector<std::string> keys;
164 create_keys(&keys, 1000, 1, 16);
169 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
170 cppcut_assert_equal(
true,
171 trie.
insert(keys[
i].c_str(), keys[
i].length()));
172 cppcut_assert_equal(
true,
173 trie.
search(keys[
i].c_str(), keys[
i].length()));
177 new_trie.
open(trie_path);
179 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
180 cppcut_assert_equal(
false,
181 new_trie.
insert(keys[
i].c_str(), keys[
i].length()));
182 cppcut_assert_equal(
true,
183 new_trie.
search(keys[
i].c_str(), keys[
i].length()));
189 std::vector<std::string> keys;
190 create_keys(&keys, 1000, 1, 16);
195 std::size_t total_key_length = 0;
196 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
198 cppcut_assert_equal(
true,
199 trie.
insert(keys[
i].c_str(), keys[
i].length(), &key_pos));
202 cppcut_assert_equal(
true, key.
is_valid());
203 cppcut_assert_equal(static_cast<grn::dat::UInt32>(
i + 1), key.
id());
204 cppcut_assert_equal(static_cast<grn::dat::UInt32>(keys[
i].length()),
206 cppcut_assert_equal(0,
207 std::memcmp(key.
ptr(), keys[
i].c_str(), key.
length()));
210 cppcut_assert_equal(
false,
211 trie.
insert(keys[
i].c_str(), keys[
i].length(), &key_pos_again));
212 cppcut_assert_equal(key_pos, key_pos_again);
214 total_key_length += keys[
i].length();
215 cppcut_assert_equal(total_key_length,
222 std::vector<std::string> keys;
223 create_keys(&keys, 1000, 1, 16);
228 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
232 cppcut_assert_equal(
true,
233 trie.
insert(keys[
i].c_str(), keys[
i].length(), &key_pos));
237 cppcut_assert_equal(&key_by_pos, &key_by_id);
243 std::vector<std::string> keys;
244 create_keys(&keys, 1000, 1, 16);
249 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
250 cppcut_assert_equal(
false,
251 trie.
search(keys[
i].c_str(), keys[
i].length()));
254 cppcut_assert_equal(
true,
255 trie.
insert(keys[
i].c_str(), keys[
i].length(), &key_pos_inserted));
258 cppcut_assert_equal(
true,
259 trie.
search(keys[
i].c_str(), keys[
i].length(), &key_pos_found));
260 cppcut_assert_equal(key_pos_inserted, key_pos_found);
269 cppcut_assert_equal(
true, trie.
insert(
"012", 3));
270 cppcut_assert_equal(
true, trie.
insert(
"01234", 5));
271 cppcut_assert_equal(
true, trie.
insert(
"0123456", 7));
273 cppcut_assert_equal(
false, trie.
lcp_search(
"01", 2));
274 cppcut_assert_equal(
true, trie.
lcp_search(
"012", 3));
275 cppcut_assert_equal(
true, trie.
lcp_search(
"0123", 4));
276 cppcut_assert_equal(
false, trie.
lcp_search(
"12345", 5));
280 cppcut_assert_equal(
false, trie.
lcp_search(
"01", 2, &key_pos));
283 cppcut_assert_equal(
true, trie.
lcp_search(
"012", 3, &key_pos));
285 cppcut_assert_equal(static_cast<grn::dat::UInt32>(1),
288 cppcut_assert_equal(
true, trie.
lcp_search(
"012345", 6, &key_pos));
290 cppcut_assert_equal(static_cast<grn::dat::UInt32>(2),
293 cppcut_assert_equal(
true, trie.
lcp_search(
"0123456789", 10, &key_pos));
295 cppcut_assert_equal(static_cast<grn::dat::UInt32>(3),
298 std::vector<std::string> keys;
299 create_keys(&keys, 1000, 1, 16);
301 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
302 const char *
const ptr = keys[
i].c_str();
303 const uint32_t length =
static_cast<uint32_t
>(keys[
i].length());
305 trie.
insert(ptr, length, &key_pos_inserted);
308 cppcut_assert_equal(
true,
309 trie.
lcp_search(ptr, length, &key_pos_found));
310 cppcut_assert_equal(key_pos_inserted, key_pos_found);
316 std::vector<std::string> keys;
317 create_keys(&keys, 1000, 1, 16);
322 std::size_t total_key_length = 0;
323 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
324 cppcut_assert_equal(
true,
325 trie.
insert(keys[
i].c_str(), keys[
i].length()));
326 total_key_length += keys[
i].length();
328 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
329 cppcut_assert_equal(static_cast<grn::dat::UInt32>(keys.size() -
i),
331 cppcut_assert_equal(
true, trie.
remove(
i + 1));
333 cppcut_assert_equal(
false,
334 trie.
search(keys[
i].c_str(), keys[
i].length()));
335 cppcut_assert_equal(
false, trie.
remove(
i + 1));
337 total_key_length -= keys[
i].length();
338 cppcut_assert_equal(total_key_length, static_cast<std::size_t>(trie.
total_key_length()));
341 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
342 cppcut_assert_equal(
true,
343 trie.
insert(keys[
i].c_str(), keys[
i].length()));
345 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
346 cppcut_assert_equal(
true,
347 trie.
remove(keys[
i].c_str(), keys[
i].length()));
348 cppcut_assert_equal(
false, trie.
ith_key(keys.size() -
i).is_valid());
349 cppcut_assert_equal(
false,
350 trie.
search(keys[
i].c_str(), keys[
i].length()));
351 cppcut_assert_equal(
false,
352 trie.
remove(keys[
i].c_str(), keys[
i].length()));
358 std::vector<std::string> keys;
359 create_keys(&keys, 1000, 1, 16);
364 std::size_t total_key_length = 0;
365 for (std::size_t
i = 0;
i < (keys.size() / 2); ++
i) {
366 cppcut_assert_equal(
true,
367 trie.
insert(keys[
i].c_str(), keys[
i].length()));
368 total_key_length += keys[
i].length();
370 for (std::size_t
i = (keys.size() / 2);
i < keys.size(); ++
i) {
372 const std::string &src_key = keys[
i - (keys.size() / 2)];
373 cppcut_assert_equal(
true,
374 trie.
update(key_id, keys[
i].c_str(), keys[
i].length()));
376 cppcut_assert_equal(
true,
377 trie.
search(keys[
i].c_str(), keys[
i].length()));
378 cppcut_assert_equal(
false,
379 trie.
search(src_key.c_str(), src_key.length()));
381 total_key_length += keys[
i].length() - src_key.length();
382 cppcut_assert_equal(total_key_length, static_cast<std::size_t>(trie.
total_key_length()));
384 for (std::size_t
i = 0;
i < (keys.size() / 2); ++
i) {
385 const std::string &src_key = keys[
i + (keys.size() / 2)];
386 cppcut_assert_equal(
true,
387 trie.
update(src_key.c_str(), src_key.length(),
388 keys[
i].c_str(), keys[
i].length()));
390 cppcut_assert_equal(
true,
391 trie.
search(keys[
i].c_str(), keys[
i].length()));
392 cppcut_assert_equal(
false,
393 trie.
search(src_key.c_str(), src_key.length()));
395 total_key_length += keys[
i].length() - src_key.length();
396 cppcut_assert_equal(total_key_length,
403 std::vector<std::string> keys;
404 create_keys(&keys, 1000, 1, 16);
409 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
410 cppcut_assert_equal(
true,
411 src_trie.
insert(keys[
i].c_str(), keys[
i].length()));
415 dest_trie.
create(src_trie);
417 for (std::size_t
i = 0;
i < keys.size(); ++
i) {
418 cppcut_assert_equal(
true,
419 dest_trie.
search(keys[
i].c_str(), keys[
i].length()));
438 typedef std::stack<grn::dat::UInt32> Stack;
439 typedef std::map<std::string, grn::dat::UInt32> Keyset;
442 trie.
create(NULL, 1 << 16);
447 for (std::size_t
i = 0;
i < 1000; ++
i) {
448 create_key(&str, 2, 3);
449 switch (static_cast<int>(4.0 * std::rand() / RAND_MAX)) {
451 const Keyset::const_iterator it = keyset.find(str);
452 const bool to_be_found = (it != keyset.end());
454 const bool is_found =
455 trie.
search(str.c_str(), str.length(), &key_pos);
456 cppcut_assert_equal(to_be_found, is_found);
459 cppcut_assert_equal(it->second, key.
id());
460 cppcut_assert_equal(static_cast<grn::dat::UInt32>(str.length()),
468 const Keyset::iterator it = keyset.find(str);
469 const bool to_be_removed = (it != keyset.end());
470 const bool is_removed = trie.
remove(str.c_str(), str.length());
471 cppcut_assert_equal(to_be_removed, is_removed);
473 stack.push(it->second);
480 stack.empty() ? (keyset.size() + 1) : stack.top();
481 const std::pair<Keyset::iterator, bool> it_bool_pair =
482 keyset.insert(std::make_pair(str, key_id));
483 const bool to_be_inserted = it_bool_pair.second;
484 if (!stack.empty() && to_be_inserted) {
488 bool is_inserted = !to_be_inserted;
490 is_inserted = trie.
insert(str.c_str(), str.length(), &key_pos);
493 is_inserted = trie.
insert(str.c_str(), str.length(), &key_pos);
495 cppcut_assert_equal(to_be_inserted, is_inserted);
505 const Keyset::iterator src_it = !src_key.
is_valid() ? keyset.end() :
506 keyset.find(std::string(
507 static_cast<const char *>(src_key.
ptr()), src_key.
length()));
508 cppcut_assert_equal(src_it != keyset.end(), src_key.
is_valid());
509 const bool to_be_updated = src_key.
is_valid() &&
510 (keyset.find(str) == keyset.end());
512 bool is_updated = !to_be_updated;
514 is_updated = trie.
update(key_id, str.c_str(), str.length(),
518 is_updated = trie.
update(key_id, str.c_str(), str.length(),
521 cppcut_assert_equal(to_be_updated, is_updated);
524 cppcut_assert_equal(key_id, key.
id());
527 keyset.erase(src_it);
528 keyset.insert(std::make_pair(str, key_id));
538 volatile Context *
const context =
static_cast<Context *
>(data);
539 cut_set_current_test_context(context->cut_test_context);
542 while (context->continue_flag)
try {
544 create_key(&str, 2, 3);
546 if (trie->
search(str.c_str(), str.length(), &key_pos)) {
548 cppcut_assert_equal(str.length(),
549 static_cast<std::size_t
>(key.
length()));
554 cut_fail(
"sub_test_multi_threaded_random_queries() failed.");
561 typedef std::stack<grn::dat::UInt32> Stack;
562 typedef std::map<std::string, grn::dat::UInt32> Keyset;
566 trie->
create(NULL, 1 << 16);
569 context.cut_test_context = cut_get_current_test_context();
571 context.continue_flag =
true;
574 for (std::size_t
i = 0;
i < (
sizeof(threads) /
sizeof(*threads)); ++
i) {
581 for (std::size_t
i = 0;
i < 1000; ++
i) {
582 create_key(&str, 2, 3);
583 switch (static_cast<int>(4.0 * std::rand() / RAND_MAX)) {
585 const Keyset::const_iterator it = keyset.find(str);
586 const bool to_be_found = (it != keyset.end());
588 const bool is_found =
589 trie->
search(str.c_str(), str.length(), &key_pos);
590 cppcut_assert_equal(to_be_found, is_found);
593 cppcut_assert_equal(it->second, key.
id());
594 cppcut_assert_equal(static_cast<grn::dat::UInt32>(str.length()),
602 const Keyset::iterator it = keyset.find(str);
603 const bool to_be_removed = (it != keyset.end());
604 const bool is_removed = trie->
remove(str.c_str(), str.length());
605 cppcut_assert_equal(to_be_removed, is_removed);
607 stack.push(it->second);
614 stack.empty() ? (keyset.size() + 1) : stack.top();
615 const std::pair<Keyset::iterator, bool> it_bool_pair =
616 keyset.insert(std::make_pair(str, key_id));
617 const bool to_be_inserted = it_bool_pair.second;
618 if (!stack.empty() && to_be_inserted) {
622 bool is_inserted = !to_be_inserted;
624 is_inserted = trie->
insert(str.c_str(), str.length(), &key_pos);
626 (trie + 1)->create(*trie, NULL, trie->
file_size() * 2);
627 context.trie = ++trie;
628 is_inserted = trie->
insert(str.c_str(), str.length(), &key_pos);
630 cppcut_assert_equal(to_be_inserted, is_inserted);
640 const Keyset::iterator src_it = !src_key.
is_valid() ? keyset.end() :
641 keyset.find(std::string(
642 static_cast<const char *>(src_key.
ptr()), src_key.
length()));
643 cppcut_assert_equal(src_it != keyset.end(), src_key.
is_valid());
644 const bool to_be_updated = src_key.
is_valid() &&
645 (keyset.find(str) == keyset.end());
647 bool is_updated = !to_be_updated;
649 is_updated = trie->
update(key_id, str.c_str(), str.length(),
652 (trie + 1)->create(*trie, NULL, trie->
file_size() * 2);
653 context.trie = ++trie;
654 is_updated = trie->
update(key_id, str.c_str(), str.length(),
657 cppcut_assert_equal(to_be_updated, is_updated);
660 cppcut_assert_equal(key_id, key.
id());
663 keyset.erase(src_it);
664 keyset.insert(std::make_pair(str, key_id));
670 context.continue_flag =
false;