Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-dat.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2011-2012 Brazil
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License version 2.1 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <dat.h>
20 
21 #include <gcutter.h>
22 #include <glib/gstdio.h>
23 #include <cppcutter.h>
24 
25 #include <grn-assertions.h>
26 
27 #include <algorithm>
28 #include <cstdio>
29 #include <cstdlib>
30 #include <ctime>
31 #include <set>
32 #include <string>
33 #include <vector>
34 
35 namespace
36 {
37  void enter_api(grn_ctx *ctx) {
39  }
40 
41  int leave_api(grn_ctx *ctx) {
42  GRN_API_RETURN(0);
43  }
44 
45  void create_key(std::string *key, std::size_t min_length,
46  std::size_t max_length)
47  {
48  key->resize(min_length + (std::rand() % (max_length - min_length + 1)));
49  for (std::size_t i = 0; i < key->size(); ++i) {
50  (*key)[i] = '0' + (std::rand() % 10);
51  }
52  }
53 
54  void create_keys(std::vector<std::string> *keys, std::size_t num_keys,
55  std::size_t min_length, std::size_t max_length)
56  {
57  std::string key;
58  std::set<std::string> keyset;
59  while (keyset.size() < num_keys) {
60  create_key(&key, min_length, max_length);
61  keyset.insert(key);
62  }
63  std::vector<std::string>(keyset.begin(), keyset.end()).swap(*keys);
64  std::random_shuffle(keys->begin(), keys->end());
65  }
66 }
67 
68 #define ENABLE_API APIScope api_scope(&ctx);
69 
70 namespace test_dat
71 {
72  const char *base_dir;
75 
76  void cut_setup(void)
77  {
78  std::srand(static_cast<unsigned int>(std::time(NULL)));
79 
80  base_dir = grn_test_get_tmp_dir();
81  cut_remove_path(base_dir, NULL);
82  g_mkdir_with_parents(base_dir, 0755);
83 
84  grn_ctx_init(&ctx, 0);
85  database = grn_db_create(&ctx, NULL, NULL);
86  enter_api(&ctx);
87  }
88 
89  void cut_teardown(void)
90  {
91  leave_api(&ctx);
93  grn_ctx_fin(&ctx);
94 
95  if (base_dir) {
96  cut_remove_path(base_dir, NULL);
97  }
98  }
99 
100  grn_dat *create_trie(const std::vector<std::string> &keys, const char *path,
101  unsigned int flags = 0) {
102  flags |= GRN_OBJ_KEY_VAR_SIZE;
103  grn_dat * const dat = grn_dat_create(&ctx, path, 0, 0, flags);
104  cppcut_assert_not_null(dat);
105  for (std::size_t i = 0; i < keys.size(); ++i) {
106  const char * const ptr = keys[i].c_str();
107  const uint32_t length = static_cast<uint32_t>(keys[i].length());
108  int added;
109  const grn_id key_id = grn_dat_add(&ctx, dat, ptr, length, NULL, &added);
110  cppcut_assert_not_equal(static_cast<const grn_id>(GRN_ID_NIL),
111  key_id);
112  cut_assert_true(added);
113  }
114  return dat;
115  }
116 
118  {
119  std::vector<std::string> keys;
120  create_keys(&keys, 1000, 6, 15);
121 
122  grn_dat *dat = create_trie(keys, NULL);
124 
125  dat = create_trie(keys, "");
127  }
128 
130  {
131  char dat_path[PATH_MAX];
132  std::sprintf(dat_path, "%s/%s", base_dir, "test_create_with_path.tmp");
133 
134  std::vector<std::string> keys;
135  create_keys(&keys, 1000, 6, 15);
136 
137  grn_dat * const dat = create_trie(keys, dat_path);
139  }
140 
141  void test_open(void)
142  {
143  char dat_path[PATH_MAX];
144  std::sprintf(dat_path, "%s/%s", base_dir, "test_open.tmp");
145 
146  std::vector<std::string> keys;
147  create_keys(&keys, 1000, 6, 15);
148 
149  grn_dat * const dat = create_trie(keys, dat_path);
150  grn_dat * const dat2 = grn_dat_open(&ctx, dat_path);
151  cppcut_assert_not_null(dat2);
152  for (std::size_t i = 0; i < keys.size(); ++i) {
153  const char * const ptr = keys[i].c_str();
154  const uint32_t length = static_cast<uint32_t>(keys[i].length());
155  cppcut_assert_equal(static_cast<grn_id>(i + 1),
156  grn_dat_get(&ctx, dat2, ptr, length, NULL));
157  }
160 
161  cppcut_assert_null(grn_dat_open(&ctx, NULL));
162  cppcut_assert_null(grn_dat_open(&ctx, ""));
163  }
164 
165  void test_remove(void)
166  {
167  char dat_path[PATH_MAX];
168  std::sprintf(dat_path, "%s/%s", base_dir, "test_remove.tmp");
169 
171  grn_dat_remove(&ctx, dat_path));
173  ctx.rc = GRN_SUCCESS;
174 
175  std::vector<std::string> keys;
176  create_keys(&keys, 1000, 6, 15);
177 
178  grn_dat * const dat = create_trie(keys, dat_path);
182  const uint32_t last_file_id = dat->file_id;
183  cppcut_assert_equal(static_cast<uint32_t>(4), last_file_id);
185 
187  cut_assert_not_exist_path(dat_path);
188  char trie_path[PATH_MAX];
189  for (uint32_t i = 1; i <= last_file_id; ++i) {
190  std::sprintf(trie_path, "%s.%03d", dat_path, i);
191  cut_assert_not_exist_path(trie_path);
192  }
194 
196  grn_dat_remove(&ctx, NULL));
197  }
198 
199  void test_get(void)
200  {
201  std::vector<std::string> keys;
202  create_keys(&keys, 1000, 6, 15);
203 
204  grn_dat * const dat = create_trie(keys, NULL);
205  for (std::size_t i = 0; i < keys.size(); ++i) {
206  const char * const ptr = keys[i].c_str();
207  const uint32_t length = static_cast<uint32_t>(keys[i].length());
208  cppcut_assert_equal(static_cast<grn_id>(i + 1),
209  grn_dat_get(&ctx, dat, ptr, length, NULL));
210  }
212  }
213 
214  void test_add(void)
215  {
216  std::vector<std::string> keys;
217  create_keys(&keys, 1000, 6, 15);
218 
219  grn_dat * const dat = create_trie(keys, NULL);
220  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
221  grn_dat_add(&ctx, dat, "", 0, NULL, NULL));
222 
224  }
225 
226  void test_get_key(void)
227  {
228  std::vector<std::string> keys;
229  create_keys(&keys, 1000, 6, 15);
230 
231  grn_dat * const dat = create_trie(keys, NULL);
232  for (std::size_t i = 0; i < keys.size(); ++i) {
233  const grn_id key_id = static_cast<grn_id>(i + 1);
234  const int length = static_cast<int>(keys[i].length());
235  cppcut_assert_equal(length, grn_dat_get_key(&ctx, dat, key_id, NULL, 0));
236  char key_buf[16];
237  const int key_length =
238  grn_dat_get_key(&ctx, dat, key_id, key_buf, sizeof(key_buf));
239  cppcut_assert_equal(length, key_length);
240  cppcut_assert_equal(keys[i], std::string(key_buf, key_length));
241  }
242  cppcut_assert_equal(0, grn_dat_get_key(&ctx, dat, GRN_ID_NIL, NULL, 0));
244  }
245 
247  {
248  grn_obj bulk;
249  GRN_OBJ_INIT(&bulk, 0, GRN_OBJ_REFER, 0);
250 
251  std::vector<std::string> keys;
252  create_keys(&keys, 1000, 6, 15);
253 
254  grn_dat * const dat = create_trie(keys, NULL);
255  for (std::size_t i = 0; i < keys.size(); ++i) {
256  const grn_id key_id = static_cast<grn_id>(i + 1);
257  const int length = static_cast<int>(keys[i].length());
258 
259  uint32_t key_length;
260  const char * const key_ptr =
261  _grn_dat_key(&ctx, dat, key_id, &key_length);
262  cppcut_assert_not_null(key_ptr);
263  cppcut_assert_equal(length, static_cast<int>(key_length));
264 
265  cppcut_assert_equal(length, grn_dat_get_key2(&ctx, dat, key_id, &bulk));
266  cppcut_assert_equal(key_ptr, bulk.u.b.head);
267  cppcut_assert_equal(length,
268  static_cast<int>(bulk.u.b.curr - bulk.u.b.head));
269  }
270  cppcut_assert_equal(0, grn_dat_get_key2(&ctx, dat, GRN_ID_NIL, &bulk));
272 
273  GRN_OBJ_FIN(&ctx, &bulk);
274  }
275 
277  {
278  grn_obj bulk;
279  GRN_TEXT_INIT(&bulk, 0);
280 
281  std::vector<std::string> keys;
282  create_keys(&keys, 1000, 6, 15);
283 
284  grn_dat * const dat = create_trie(keys, NULL);
285  for (std::size_t i = 0; i < keys.size(); ++i) {
286  const grn_id key_id = static_cast<grn_id>(i + 1);
287  const int length = static_cast<int>(keys[i].length());
288 
289  uint32_t key_length;
290  const char * const key_ptr =
291  _grn_dat_key(&ctx, dat, key_id, &key_length);
292  cppcut_assert_not_null(key_ptr);
293  cppcut_assert_equal(length, static_cast<int>(key_length));
294 
295  GRN_BULK_REWIND(&bulk);
296  cppcut_assert_equal(length, grn_dat_get_key2(&ctx, dat, key_id, &bulk));
297  cppcut_assert_equal(length, static_cast<int>(GRN_TEXT_LEN(&bulk)));
298  cppcut_assert_equal(keys[i],
299  std::string(GRN_TEXT_VALUE(&bulk), GRN_TEXT_LEN(&bulk)));
300  }
301  cppcut_assert_equal(0, grn_dat_get_key2(&ctx, dat, GRN_ID_NIL, &bulk));
303 
304  GRN_OBJ_FIN(&ctx, &bulk);
305  }
306 
307  void test_delete_by_id(void)
308  {
309  std::vector<std::string> keys;
310  create_keys(&keys, 1000, 6, 15);
311 
312  grn_dat * const dat = create_trie(keys, NULL);
313  for (std::size_t i = 0; i < keys.size(); ++i) {
314  const grn_id key_id = static_cast<grn_id>(i + 1);
316  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
318  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
319  }
320  for (std::size_t i = 0; i < keys.size(); ++i) {
321  const char * const ptr = keys[i].c_str();
322  const uint32_t length = static_cast<uint32_t>(keys[i].length());
323  int added;
324  cppcut_assert_equal(static_cast<grn_id>(keys.size() - i),
325  grn_dat_add(&ctx, dat, ptr, length, NULL, &added));
326  cut_assert_true(added);
327  }
328  for (std::size_t i = 0; i < keys.size(); ++i) {
329  const grn_id key_id = static_cast<grn_id>(i + 1);
331  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
333  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
334  }
336  }
337 
338  void test_delete(void)
339  {
340  std::vector<std::string> keys;
341  create_keys(&keys, 1000, 6, 15);
342 
343  grn_dat * const dat = create_trie(keys, NULL);
344  for (std::size_t i = 0; i < keys.size(); ++i) {
345  const char * const ptr = keys[i].c_str();
346  const uint32_t length = static_cast<uint32_t>(keys[i].length());
348  grn_dat_delete(&ctx, dat, ptr, length, NULL));
350  grn_dat_delete(&ctx, dat, ptr, length, NULL));
351  }
352  for (std::size_t i = 0; i < keys.size(); ++i) {
353  const char * const ptr = keys[i].c_str();
354  const uint32_t length = static_cast<uint32_t>(keys[i].length());
355  int added;
356  cppcut_assert_equal(static_cast<grn_id>(keys.size() - i),
357  grn_dat_add(&ctx, dat, ptr, length, NULL, &added));
358  cut_assert_true(added);
359  }
360  for (std::size_t i = 0; i < keys.size(); ++i) {
361  const char * const ptr = keys[i].c_str();
362  const uint32_t length = static_cast<uint32_t>(keys[i].length());
364  grn_dat_delete(&ctx, dat, ptr, length, NULL));
366  grn_dat_delete(&ctx, dat, ptr, length, NULL));
367  }
369  }
370 
371  void test_update_by_id(void)
372  {
373  std::vector<std::string> keys;
374  create_keys(&keys, 1000, 6, 15);
375 
376  grn_dat * const dat =
377  grn_dat_create(&ctx, NULL, 0, 0, GRN_OBJ_KEY_VAR_SIZE);
378  cppcut_assert_not_null(dat);
379  for (std::size_t i = 0; i < (keys.size() / 2); ++i) {
380  const char * const ptr = keys[i].c_str();
381  const uint32_t length = static_cast<uint32_t>(keys[i].length());
382  cppcut_assert_equal(static_cast<grn_id>(i + 1),
383  grn_dat_add(&ctx, dat, ptr, length, NULL, NULL));
384  }
386  grn_dat_update_by_id(&ctx, dat, 1, "", 0));
387  for (std::size_t i = (keys.size() / 2); i < keys.size(); ++i) {
388  const grn_id key_id = static_cast<grn_id>(i + 1 - (keys.size() / 2));
389  const char * const src_ptr = keys[i - (keys.size() / 2)].c_str();
390  const uint32_t src_length =
391  static_cast<uint32_t>(keys[i - (keys.size() / 2)].length());
392  const char * const dest_ptr = keys[i].c_str();
393  const uint32_t dest_length = static_cast<uint32_t>(keys[i].length());
395  grn_dat_update_by_id(&ctx, dat, key_id, dest_ptr, dest_length));
396  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
397  grn_dat_get(&ctx, dat, src_ptr, src_length, NULL));
398  cppcut_assert_equal(key_id,
399  grn_dat_get(&ctx, dat, dest_ptr, dest_length, NULL));
401  grn_dat_update_by_id(&ctx, dat, key_id, dest_ptr, dest_length));
402  }
403  for (std::size_t i = 0; i < (keys.size() / 2); ++i) {
404  const grn_id key_id = static_cast<grn_id>(i + 1);
405  const char *src_ptr = keys[i + (keys.size() / 2)].c_str();
406  const uint32_t src_length =
407  static_cast<uint32_t>(keys[i + (keys.size() / 2)].length());
408  const char * const dest_ptr = keys[i].c_str();
409  const uint32_t dest_length = static_cast<uint32_t>(keys[i].length());
411  grn_dat_update_by_id(&ctx, dat, key_id, dest_ptr, dest_length));
412  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
413  grn_dat_get(&ctx, dat, src_ptr, src_length, NULL));
414  cppcut_assert_equal(key_id,
415  grn_dat_get(&ctx, dat, dest_ptr, dest_length, NULL));
417  grn_dat_update_by_id(&ctx, dat, key_id, dest_ptr, dest_length));
418  }
420  }
421 
422  void test_update(void)
423  {
424  std::vector<std::string> keys;
425  create_keys(&keys, 1000, 6, 15);
426 
427  grn_dat * const dat =
428  grn_dat_create(&ctx, NULL, 0, 0, GRN_OBJ_KEY_VAR_SIZE);
429  cppcut_assert_not_null(dat);
430  for (std::size_t i = 0; i < (keys.size() / 2); ++i) {
431  const char * const ptr = keys[i].c_str();
432  const uint32_t length = static_cast<uint32_t>(keys[i].length());
433  cppcut_assert_equal(static_cast<grn_id>(i + 1),
434  grn_dat_add(&ctx, dat, ptr, length, NULL, NULL));
435  }
437  grn_dat_update(&ctx, dat, keys[1].c_str(), keys[1].length(), "", 0));
438  for (std::size_t i = (keys.size() / 2); i < keys.size(); ++i) {
439  const grn_id key_id = static_cast<grn_id>(i + 1 - (keys.size() / 2));
440  const char * const src_ptr = keys[i - (keys.size() / 2)].c_str();
441  const uint32_t src_length =
442  static_cast<uint32_t>(keys[i - (keys.size() / 2)].length());
443  const char * const dest_ptr = keys[i].c_str();
444  const uint32_t dest_length = static_cast<uint32_t>(keys[i].length());
446  grn_dat_update(&ctx, dat, src_ptr, src_length,
447  dest_ptr, dest_length));
448  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
449  grn_dat_get(&ctx, dat, src_ptr, src_length, NULL));
450  cppcut_assert_equal(key_id,
451  grn_dat_get(&ctx, dat, dest_ptr, dest_length, NULL));
453  grn_dat_update(&ctx, dat, src_ptr, src_length,
454  dest_ptr, dest_length));
455  }
456  for (std::size_t i = 0; i < (keys.size() / 2); ++i) {
457  const grn_id key_id = static_cast<grn_id>(i + 1);
458  const char *src_ptr = keys[i + (keys.size() / 2)].c_str();
459  const uint32_t src_length =
460  static_cast<uint32_t>(keys[i + (keys.size() / 2)].length());
461  const char * const dest_ptr = keys[i].c_str();
462  const uint32_t dest_length = static_cast<uint32_t>(keys[i].length());
464  grn_dat_update(&ctx, dat, src_ptr, src_length,
465  dest_ptr, dest_length));
466  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
467  grn_dat_get(&ctx, dat, src_ptr, src_length, NULL));
468  cppcut_assert_equal(key_id,
469  grn_dat_get(&ctx, dat, dest_ptr, dest_length, NULL));
471  grn_dat_update(&ctx, dat, src_ptr, src_length,
472  dest_ptr, dest_length));
473  }
475  }
476 
477  void test_scan(void)
478  {
479  {
480  std::vector<std::string> keys;
481  keys.push_back("12");
482  keys.push_back("234");
483  keys.push_back("45");
484  keys.push_back("789");
485 
486  const char text[] = "0123456789X";
487  const unsigned int text_size = sizeof(text) - 1;
488  grn_dat_scan_hit scan_hits[4];
489  const unsigned int max_num_scan_hits =
490  sizeof(scan_hits) / sizeof(scan_hits[0]);
491 
492  grn_dat * const dat = create_trie(keys, NULL);
493 
494  const char *text_rest;
495  cppcut_assert_equal(3,
496  grn_dat_scan(&ctx, dat, text, text_size,
497  scan_hits, max_num_scan_hits, &text_rest));
498  cppcut_assert_equal(text + text_size, text_rest);
499  cppcut_assert_equal(static_cast<grn_id>(1), scan_hits[0].id);
500  cppcut_assert_equal(1U, scan_hits[0].offset);
501  cppcut_assert_equal(2U, scan_hits[0].length);
502  cppcut_assert_equal(static_cast<grn_id>(3), scan_hits[1].id);
503  cppcut_assert_equal(4U, scan_hits[1].offset);
504  cppcut_assert_equal(2U, scan_hits[1].length);
505  cppcut_assert_equal(static_cast<grn_id>(4), scan_hits[2].id);
506  cppcut_assert_equal(7U, scan_hits[2].offset);
507  cppcut_assert_equal(3U, scan_hits[2].length);
508 
509  cppcut_assert_equal(1,
510  grn_dat_scan(&ctx, dat, text, text_size, scan_hits, 1, &text_rest));
511  cppcut_assert_equal(static_cast<std::ptrdiff_t>(3), text_rest - text);
512  cppcut_assert_equal(1,
513  grn_dat_scan(&ctx, dat, text_rest, text_size - (text_rest - text),
514  scan_hits, 1, &text_rest));
515  cppcut_assert_equal(static_cast<std::ptrdiff_t>(6), text_rest - text);
516  cppcut_assert_equal(1,
517  grn_dat_scan(&ctx, dat, text_rest, text_size - (text_rest - text),
518  scan_hits, 1, &text_rest));
519  cppcut_assert_equal(static_cast<std::ptrdiff_t>(10), text_rest - text);
520  cppcut_assert_equal(0,
521  grn_dat_scan(&ctx, dat, text_rest, text_size - (text_rest - text),
522  scan_hits, 1, &text_rest));
523 
525  }
526 
527  {
528  std::vector<std::string> keys;
529  keys.push_back("ユニグラム");
530  keys.push_back("グラム");
531 
532  const char text[] = "ユニ㌘…ハ゛イク゛ラム";
533  const unsigned int text_size = sizeof(text) - 1;
534  grn_dat_scan_hit scan_hits[4];
535  const unsigned int max_num_scan_hits =
536  sizeof(scan_hits) / sizeof(scan_hits[0]);
537 
538  grn_dat * const dat = create_trie(keys, NULL, GRN_OBJ_KEY_NORMALIZE);
539 
540  const char *text_rest;
541  cppcut_assert_equal(2,
542  grn_dat_scan(&ctx, dat, text, text_size,
543  scan_hits, max_num_scan_hits, &text_rest));
544  cppcut_assert_equal(text + text_size, text_rest);
545  cppcut_assert_equal(static_cast<grn_id>(1), scan_hits[0].id);
546  cppcut_assert_equal(0U, scan_hits[0].offset);
547  cppcut_assert_equal(9U, scan_hits[0].length);
548  cppcut_assert_equal(static_cast<grn_id>(2), scan_hits[1].id);
549  cppcut_assert_equal(21U, scan_hits[1].offset);
550  cppcut_assert_equal(12U, scan_hits[1].length);
551 
552  cppcut_assert_equal(1,
553  grn_dat_scan(&ctx, dat, text, text_size, scan_hits, 1, &text_rest));
554  cppcut_assert_equal(static_cast<std::ptrdiff_t>(9), text_rest - text);
555  cppcut_assert_equal(1,
556  grn_dat_scan(&ctx, dat, text_rest, text_size - (text_rest - text),
557  scan_hits, 1, &text_rest));
558  cppcut_assert_equal(static_cast<std::ptrdiff_t>(33), text_rest - text);
559  cppcut_assert_equal(0,
560  grn_dat_scan(&ctx, dat, text_rest, text_size - (text_rest - text),
561  scan_hits, 1, &text_rest));
562 
564  }
565 
566  {
567  std::vector<std::string> keys;
568  create_keys(&keys, 1000, 6, 15);
569 
570  grn_dat * const dat = create_trie(keys, NULL);
571  for (std::size_t i = 0; i < keys.size(); ++i) {
572  const grn_id key_id = static_cast<grn_id>(i + 1);
573  const char * const ptr = keys[i].c_str();
574  const uint32_t length = static_cast<uint32_t>(keys[i].length());
575  grn_dat_scan_hit scan_hits[2];
576  cppcut_assert_equal(1,
577  grn_dat_scan(&ctx, dat, ptr, length, scan_hits, 2, NULL));
578  cppcut_assert_equal(key_id, scan_hits[0].id);
579  cppcut_assert_equal(0U, scan_hits[0].offset);
580  cppcut_assert_equal(length, scan_hits[0].length);
581  }
583  }
584  }
585 
586  void test_lcp_search(void)
587  {
588  {
589  std::vector<std::string> keys;
590  keys.push_back("012");
591  keys.push_back("01234");
592  keys.push_back("0123456");
593 
594  grn_dat * const dat = create_trie(keys, NULL);
595  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
596  grn_dat_lcp_search(&ctx, dat, "01", 2));
597  cppcut_assert_equal(static_cast<grn_id>(1),
598  grn_dat_lcp_search(&ctx, dat, "012", 3));
599  cppcut_assert_equal(static_cast<grn_id>(1),
600  grn_dat_lcp_search(&ctx, dat, "0123", 4));
601  cppcut_assert_equal(static_cast<grn_id>(2),
602  grn_dat_lcp_search(&ctx, dat, "01234", 5));
603  cppcut_assert_equal(static_cast<grn_id>(2),
604  grn_dat_lcp_search(&ctx, dat, "012345", 6));
605  cppcut_assert_equal(static_cast<grn_id>(3),
606  grn_dat_lcp_search(&ctx, dat, "0123456", 7));
607  cppcut_assert_equal(static_cast<grn_id>(3),
608  grn_dat_lcp_search(&ctx, dat, "0123456789", 10));
609  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
610  grn_dat_lcp_search(&ctx, dat, "013", 3));
611  }
612 
613  {
614  std::vector<std::string> keys;
615  create_keys(&keys, 1000, 6, 15);
616 
617  grn_dat * const dat = create_trie(keys, NULL);
618  for (std::size_t i = 0; i < keys.size(); ++i) {
619  const grn_id key_id = static_cast<grn_id>(i + 1);
620  const char * const ptr = keys[i].c_str();
621  const uint32_t length = static_cast<uint32_t>(keys[i].length());
622  cppcut_assert_equal(key_id,
623  grn_dat_lcp_search(&ctx, dat, ptr, length));
624  }
626  }
627  }
628 
629  void test_size(void)
630  {
631  std::vector<std::string> keys;
632  create_keys(&keys, 1000, 6, 15);
633 
634  grn_dat * const dat = create_trie(keys, NULL);
635  cppcut_assert_equal(static_cast<unsigned int>(keys.size()),
636  grn_dat_size(&ctx, dat));
638  }
639 
640  void test_curr_id(void)
641  {
642  grn_dat * const dat =
643  grn_dat_create(&ctx, NULL, 0, 0, GRN_OBJ_KEY_VAR_SIZE);
644  cppcut_assert_not_null(dat);
645 
646  grn_id max_key_id = 0;
647  std::string key;
648  for (uint32_t i = 1; i <= 1000; ++i) {
649  cppcut_assert_equal(max_key_id, grn_dat_curr_id(&ctx, dat));
650  create_key(&key, 1, 3);
651  int added;
652  const grn_id key_id =
653  grn_dat_add(&ctx, dat, key.c_str(), key.length(), NULL, &added);
654  if (added) {
655  ++max_key_id;
656  cppcut_assert_equal(max_key_id, key_id);
657  }
658  }
660  }
661 
662  void test_truncate(void)
663  {
664  char dat_path[PATH_MAX];
665  std::sprintf(dat_path, "%s/%s", base_dir, "test_truncate");
666 
667  std::vector<std::string> keys;
668  create_keys(&keys, 1000, 6, 15);
669 
670  grn_dat * const dat = create_trie(keys, dat_path);
672  cppcut_assert_equal(static_cast<unsigned int>(0), grn_dat_size(&ctx, dat));
673  cppcut_assert_equal(static_cast<grn_id>(0), grn_dat_curr_id(&ctx, dat));
674  for (std::size_t i = 0; i < keys.size(); ++i) {
675  const char * const ptr = keys[i].c_str();
676  const uint32_t length = static_cast<uint32_t>(keys[i].length());
677  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
678  grn_dat_get(&ctx, dat, ptr, length, NULL));
679  }
681  }
682 
683  void test_key(void)
684  {
685  std::vector<std::string> keys;
686  create_keys(&keys, 1000, 6, 15);
687 
688  grn_dat * const dat = create_trie(keys, NULL);
689  for (std::size_t i = 0; i < keys.size(); ++i) {
690  const grn_id key_id = static_cast<grn_id>(i + 1);
691  const uint32_t length = static_cast<uint32_t>(keys[i].length());
692  uint32_t key_length;
693  const char * const key_ptr =
694  _grn_dat_key(&ctx, dat, key_id, &key_length);
695  cppcut_assert_not_null(key_ptr);
696  cppcut_assert_equal(length, key_length);
697  cppcut_assert_equal(keys[i], std::string(key_ptr, key_length));
698  }
699  cppcut_assert_null(_grn_dat_key(&ctx, dat, GRN_ID_NIL, NULL));
701  }
702 
703  void test_next(void)
704  {
705  std::vector<std::string> keys;
706  create_keys(&keys, 1000, 6, 15);
707 
708  grn_dat * const dat = create_trie(keys, NULL);
709  for (std::size_t i = 0; i < keys.size(); i += 2) {
710  const grn_id key_id = static_cast<grn_id>(i + 1);
712  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
713  }
714  for (std::size_t i = 0; i < (keys.size() - 1); ++i) {
715  const grn_id key_id = static_cast<grn_id>(i + 1);
716  if (!(i & 1)) {
717  cppcut_assert_equal(key_id + 1, grn_dat_next(&ctx, dat, key_id));
718  } else {
719  cppcut_assert_equal(key_id + 2, grn_dat_next(&ctx, dat, key_id));
720  }
721  }
722  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
723  grn_dat_next(&ctx, dat, keys.size()));
725  }
726 
727  void test_at(void)
728  {
729  std::vector<std::string> keys;
730  create_keys(&keys, 1000, 6, 15);
731 
732  grn_dat * const dat = create_trie(keys, NULL);
733  for (std::size_t i = 0; i < keys.size(); i += 2) {
734  const grn_id key_id = static_cast<grn_id>(i + 1);
736  grn_dat_delete_by_id(&ctx, dat, key_id, NULL));
737  }
738  for (std::size_t i = 0; i < keys.size(); ++i) {
739  const grn_id key_id = static_cast<grn_id>(i + 1);
740  if (!(i & 1)) {
741  cppcut_assert_equal(static_cast<grn_id>(GRN_ID_NIL),
742  grn_dat_at(&ctx, dat, key_id));
743  } else {
744  cppcut_assert_equal(key_id, grn_dat_at(&ctx, dat, key_id));
745  }
746  }
748  }
749 
750  void test_repair(void)
751  {
752  char dat_path[PATH_MAX];
753  std::sprintf(dat_path, "%s/%s", base_dir, "test_repair");
754 
755  std::vector<std::string> keys;
756  create_keys(&keys, 1000, 6, 15);
757 
758  grn_dat * const dat = create_trie(keys, dat_path);
759 
761  cppcut_assert_equal(static_cast<unsigned int>(keys.size()),
762  grn_dat_size(&ctx, dat));
763  cppcut_assert_equal(static_cast<grn_id>(keys.size()),
764  grn_dat_curr_id(&ctx, dat));
765 
766  for (std::size_t i = 0; i < keys.size(); ++i) {
767  const char * const ptr = keys[i].c_str();
768  const uint32_t length = static_cast<uint32_t>(keys[i].length());
769  cppcut_assert_equal(static_cast<grn_id>(i + 1),
770  grn_dat_get(&ctx, dat, ptr, length, NULL));
771  }
772 
773  for (std::size_t i = 0; i < keys.size(); i += 2) {
775  grn_dat_delete_by_id(&ctx, dat, i + 1, NULL));
776  }
778  cppcut_assert_equal(static_cast<unsigned int>(keys.size() / 2),
779  grn_dat_size(&ctx, dat));
780 
781  for (std::size_t i = 0; i < keys.size(); i += 2) {
782  const char * const ptr = keys[i].c_str();
783  const uint32_t length = static_cast<uint32_t>(keys[i].length());
784  int added;
785  cppcut_assert_equal(static_cast<grn_id>(i + 1),
786  grn_dat_add(&ctx, dat, ptr, length, NULL, &added));
787  cppcut_assert_equal(1, added);
788  }
790  cppcut_assert_equal(static_cast<unsigned int>(keys.size()),
791  grn_dat_size(&ctx, dat));
792 
793  for (std::size_t i = 0; i < keys.size(); ++i) {
794  const char * const ptr = keys[i].c_str();
795  const uint32_t length = static_cast<uint32_t>(keys[i].length());
796  cppcut_assert_equal(static_cast<grn_id>(i + 1),
797  grn_dat_get(&ctx, dat, ptr, length, NULL));
798  }
799 
801  }
802 }