Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-hash.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2008-2012 Kouhei Sutou <kou@clear-code.com>
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 <math.h>
20 
21 #include "test-hash.h"
22 
23 void data_create(void);
24 void test_create(gconstpointer data);
25 void data_open(void);
26 void test_open(gconstpointer data);
27 void test_open_without_path(void);
28 void test_open_tiny_hash(void);
29 void data_lookup_add(void);
30 void test_lookup_add(gconstpointer data);
31 void data_delete_by_id(void);
32 void test_delete_by_id(gconstpointer data);
33 void data_delete(void);
34 void test_delete(gconstpointer data);
35 void data_get_key(void);
36 void test_get_key(gconstpointer data);
37 void data_get_value(void);
38 void test_get_value(gconstpointer data);
39 void data_set_value(void);
40 void test_set_value(gconstpointer data);
42 void test_set_value_with_null_value(gconstpointer data);
43 void data_add_and_delete(void);
44 void test_add_and_delete(gconstpointer data);
45 void data_truncate(void);
46 void test_truncate(gconstpointer data);
47 
48 static GArray *ids;
49 
50 void
52 {
53  startup_hash_common();
54 }
55 
56 void
58 {
59  shutdown_hash_common();
60 }
61 
62 void
63 cut_setup(void)
64 {
65  setup_hash_common("hash");
66  ids = NULL;
67 }
68 
69 static void
70 ids_free(void)
71 {
72  if (ids)
73  g_array_free(ids, TRUE);
74  ids = NULL;
75 }
76 
77 void
79 {
80  ids_free();
81  teardown_hash_common();
82 }
83 
84 static void
85 set_key_size_to_zero(void)
86 {
88 }
89 
90 static void
91 set_value_size_to_zero(void)
92 {
94 }
95 
96 static void
97 set_variable_size(void)
98 {
101 }
102 
103 static void
104 set_tiny_flags_and_variable_size(void)
105 {
106  set_tiny_flags();
107  set_variable_size();
108 }
109 
110 static void
111 set_not_uint32_key_size(void)
112 {
113  grn_test_hash_factory_set_key_size(factory, not_uint32_key_size);
114  key_size = not_uint32_key_size;
115 }
116 
117 static void
118 set_tiny_flags_and_not_uint32_key_size(void)
119 {
120  set_tiny_flags();
121  set_not_uint32_key_size();
122 }
123 
124 
125 void
127 {
128  cut_add_data("default", NULL, NULL,
129  "zero key size", set_key_size_to_zero, NULL,
130  "zero value size", set_value_size_to_zero, NULL);
131 }
132 
133 void
134 test_create(gconstpointer data)
135 {
136  const grn_test_set_parameters_func set_parameters = data;
137 
138  if (set_parameters)
139  set_parameters();
141 }
142 
143 void
145 {
146  cut_add_data("default", NULL, NULL,
147  "zero key size", set_key_size_to_zero, NULL,
148  "zero value size", set_value_size_to_zero, NULL);
149 }
150 
151 void
152 test_open(gconstpointer data)
153 {
154  const grn_test_set_parameters_func set_parameters = data;
155 
156  if (set_parameters)
157  set_parameters();
160 }
161 
162 void
164 {
165  const gchar *saved_default_path;
166 
168 
169  saved_default_path = cut_take_strdup(grn_test_hash_factory_get_path(factory));
170  grn_test_hash_factory_set_path(factory, NULL);
171 
172  cut_assert_path_not_exist(saved_default_path);
174  cut_assert_path_not_exist(saved_default_path);
176  cut_assert_path_not_exist(saved_default_path);
177 }
178 
179 void
181 {
182  set_tiny_flags();
183 
186 }
187 
189 
190 typedef void (*increment_key_func) (grn_test_data *test_data);
191 
193 {
194  gpointer key;
197 };
198 
199 static grn_test_data *
200 test_data_new(gpointer key, increment_key_func increment,
201  grn_test_set_parameters_func set_parameters)
202 {
203  grn_test_data *test_data;
204 
205  test_data = g_new0(grn_test_data, 1);
206  test_data->key = key;
207  test_data->increment = increment;
208  test_data->set_parameters = set_parameters;
209 
210  return test_data;
211 }
212 
213 static void
214 test_data_free(grn_test_data *test_data)
215 {
216  g_free(test_data->key);
217  g_free(test_data);
218 }
219 
220 static void
221 test_data_add_n_data(guint n, grn_test_data *test_data)
222 {
223  guint i;
224 
225  ids_free();
226  ids = g_array_new(TRUE, TRUE, sizeof(grn_id));
227  for (i = 0; i < n; i++) {
229  key_size = strlen(test_data->key);
230  cut_assert_lookup_add(test_data->key);
231  test_data->increment((grn_test_data *)test_data);
232  g_array_append_val(ids, id);
233  }
234 }
235 
236 static gpointer
237 uint32_key_new(uint32_t key)
238 {
239  uint32_t *key_pointer;
240 
241  key_pointer = g_new0(uint32_t, 1);
242  *key_pointer = key;
243 
244  return key_pointer;
245 }
246 
247 static void
248 uint32_increment(grn_test_data *test_data)
249 {
250  uint32_t *key_pointer = test_data->key;
251  (*key_pointer)++;
252 }
253 
254 static void
255 string_increment(grn_test_data *test_data)
256 {
257  gchar *original_string = test_data->key;
258  gchar *string;
259  gint last;
260 
261  last = strlen(original_string);
262  if (original_string[last - 1] < 'X') {
263  original_string[last - 1]++;
264  } else {
265  string = g_strconcat(test_data->key, "A", NULL);
266  g_free(test_data->key);
267  test_data->key = string;
268  }
269 }
270 
271 static void
272 not_uint32_size_key_increment(grn_test_data *test_data)
273 {
274  gchar *string = test_data->key;
275  gint i;
276 
277  for (i = 0; i < not_uint32_key_size; i++) {
278  if (string[i] < '~') {
279  string[i]++;
280  return;
281  }
282  }
283  cut_error("can't increment more!: %s", string);
284 }
285 
286 static void
287 add_variable_key_size_test_data(void)
288 {
289  cut_add_data("uint32 - default",
290  test_data_new(uint32_key_new(29), uint32_increment,
291  NULL),
292  test_data_free,
293  "uint32 - tiny",
294  test_data_new(uint32_key_new(29), uint32_increment,
295  set_tiny_flags),
296  test_data_free,
297  "variable size - short - default",
298  test_data_new(g_strdup("X"), string_increment,
299  set_variable_size),
300  test_data_free,
301  "variable size - short - tiny",
302  test_data_new(g_strdup("X"), string_increment,
303  set_tiny_flags_and_variable_size),
304  test_data_free,
305  "variable size - long - default",
306  test_data_new(g_strdup("must be long rather than sizeof(char *)"),
307  string_increment,
308  set_variable_size),
309  test_data_free,
310  "variable size - long - tiny",
311  test_data_new(g_strdup("must be long rather than sizeof(char *)"),
312  string_increment,
313  set_tiny_flags_and_variable_size),
314  test_data_free,
315  "not uint32 size - default",
316  test_data_new(g_strdup(not_uint32_size_key),
317  not_uint32_size_key_increment,
318  set_not_uint32_key_size),
319  test_data_free,
320  "not uint32 size - tiny",
321  test_data_new(g_strdup(not_uint32_size_key),
322  not_uint32_size_key_increment,
323  set_tiny_flags_and_not_uint32_key_size),
324  test_data_free);
325 }
326 
327 void
329 {
330  add_variable_key_size_test_data();
331 }
332 
333 void
334 test_lookup_add(gconstpointer data)
335 {
336  const grn_test_data *test_data = data;
337 
338  if (test_data->set_parameters)
339  test_data->set_parameters();
340 
342 
343  if (grn_test_hash_factory_get_flags(factory) & GRN_OBJ_KEY_VAR_SIZE)
344  key_size = strlen(test_data->key);
345  cut_assert_lookup_add(test_data->key);
346 }
347 
348 
349 #define put_sample_entry() do \
350 { \
351  grn_search_flags flags; \
352  \
353  flags = GRN_TABLE_ADD; \
354  cut_assert_lookup(&sample_key, &flags); \
355  cut_assert(flags & 1); \
356  sample_id = id; \
357 } while (0)
358 
359 #define cut_assert_delete_by_id() do \
360 { \
361  grn_search_flags flags; \
362  \
363  grn_test_assert_equal_rc(GRN_INVALID_ARGUMENT, \
364  grn_hash_delete_by_id(context, hash, 0, NULL)); \
365  \
366  put_sample_entry(); \
367  \
368  flags = 0; \
369  cut_assert_lookup(&sample_key, &flags); \
370  \
371  grn_test_assert_equal_rc(GRN_INVALID_ARGUMENT, \
372  grn_hash_delete_by_id(context, \
373  NULL, sample_id, NULL)); \
374  grn_test_assert(grn_hash_delete_by_id(context, hash, sample_id, NULL)); \
375  grn_test_assert_equal_rc(GRN_INVALID_ARGUMENT, \
376  grn_hash_delete_by_id(context, \
377  hash, sample_id, NULL)); \
378  \
379  flags = 0; \
380  cut_assert_lookup_failed(&sample_key, &flags); \
381 } while (0)
382 
383 void
385 {
386  cut_add_data("default", NULL, NULL,
387  "tiny", set_tiny_flags, NULL);
388 }
389 
390 void
391 test_delete_by_id(gconstpointer data)
392 {
393  const grn_test_set_parameters_func set_parameters = data;
394 
395  if (set_parameters)
396  set_parameters();
397 
400 }
401 
402 
403 #define cut_assert_delete(key) do \
404 { \
405  const void *_key; \
406  grn_search_flags flags; \
407  \
408  _key = (key); \
409  \
410  flags = GRN_TABLE_ADD; \
411  cut_assert_lookup(_key, &flags); \
412  \
413  grn_test_assert(grn_hash_delete(context, hash, _key, key_size, NULL)); \
414  grn_test_assert_equal_rc(GRN_INVALID_ARGUMENT, \
415  grn_hash_delete(context, \
416  hash, _key, key_size, NULL)); \
417  \
418  flags = 0; \
419  cut_assert_lookup_failed(_key, &flags); \
420 } while (0)
421 
422 void
423 data_delete(void)
424 {
425  add_variable_key_size_test_data();
426 }
427 
428 void
429 test_delete(gconstpointer data)
430 {
431  const grn_test_data *test_data = data;
432 
433  if (test_data->set_parameters)
434  test_data->set_parameters();
435 
437 
438  if (grn_test_hash_factory_get_flags(factory) & GRN_OBJ_KEY_VAR_SIZE)
439  key_size = strlen(test_data->key);
440  cut_assert_delete(test_data->key);
441 }
442 
443 void
445 {
446  cut_add_data("default", NULL, NULL,
447  "tiny", set_tiny_flags, NULL);
448 }
449 
450 void
451 test_get_key(gconstpointer data)
452 {
453  const grn_test_set_parameters_func set_parameters = data;
454  uint32_t key = 29;
455  uint32_t initial_key = 999999;
456  uint32_t got_key;
457  grn_search_flags flags;
458 
459  if (set_parameters)
460  set_parameters();
461 
463 
464  flags = GRN_TABLE_ADD;
465  cut_assert_lookup(&key, &flags);
466 
467  got_key = initial_key;
468  cut_assert_equal_int(key_size,
469  grn_hash_get_key(context, hash, id, &got_key, key_size));
470  cut_assert_equal_uint(key, got_key);
471 }
472 
473 void
475 {
476  cut_add_data("default", NULL, NULL,
477  "tiny", set_tiny_flags, NULL);
478 }
479 
480 void
481 test_get_value(gconstpointer data)
482 {
483  const grn_test_set_parameters_func set_parameters = data;
484  uint32_t key = 29;
485  gchar set_value[] = "ABCDE";
486  gchar initial_value[] = "XYZ";
488  grn_search_flags flags;
489 
490  if (set_parameters)
491  set_parameters();
492 
494 
495  flags = GRN_TABLE_ADD;
496  cut_assert_lookup(&key, &flags);
497  strcpy(value, set_value);
498 
499  strcpy(got_value, initial_value);
500  cut_assert_equal_int(GRN_TEST_HASH_FACTORY_DEFAULT_VALUE_SIZE,
501  grn_hash_get_value(context, hash, id, got_value));
502  cut_assert_equal_string(set_value, got_value);
503 }
504 
505 void
507 {
508  cut_add_data("default", NULL, NULL,
509  "tiny", set_tiny_flags, NULL);
510 }
511 
512 void
513 test_set_value(gconstpointer data)
514 {
515  const grn_test_set_parameters_func set_parameters = data;
517 
518  if (set_parameters)
519  set_parameters();
520 
522 
524 
526  sample_id, "XXX", GRN_OBJ_SET));
527  cut_assert_equal_int(GRN_TEST_HASH_FACTORY_DEFAULT_VALUE_SIZE,
528  grn_hash_get_value(context, hash, sample_id, got_value));
529  cut_assert_equal_string("XXX", got_value);
530 }
531 
532 void
534 {
535  cut_add_data("default", NULL, NULL,
536  "tiny", set_tiny_flags, NULL);
537 }
538 
539 void
541 {
542  const grn_test_set_parameters_func set_parameters = data;
543  grn_id nonexistence_id = 999;
544 
545  if (set_parameters)
546  set_parameters();
548 
550  grn_hash_set_value(context, hash, nonexistence_id,
551  NULL, GRN_OBJ_SET));
552 
555  grn_hash_set_value(context, hash, sample_id,
556  NULL, GRN_OBJ_SET));
557 }
558 
559 void
561 {
562  add_variable_key_size_test_data();
563 }
564 
565 void
566 test_add_and_delete(gconstpointer data)
567 {
568  grn_test_data *test_data;
569  guint i;
570  const guint n_operations = 750;
571 
572  test_data = (grn_test_data *)data;
573 
574  if (test_data->set_parameters)
575  test_data->set_parameters();
576 
578 
579  test_data_add_n_data(n_operations, test_data);
580 
581  cut_assert_equal_int(n_operations, GRN_HASH_SIZE(hash));
582  for (i = 0; i < ids->len; i++) {
583  grn_id delete_id;
584 
585  delete_id = g_array_index(ids, grn_id, i);
586  grn_test_assert(grn_hash_delete_by_id(context, hash, delete_id, NULL),
587  cut_message("i = %d; id = %d", i, delete_id));
588  }
589  cut_assert_equal_int(0, GRN_HASH_SIZE(hash));
590 }
591 
592 void
594 {
595  add_variable_key_size_test_data();
596 }
597 
598 void
599 test_truncate(gconstpointer data)
600 {
601  grn_test_data *test_data;
602  guint n_data = 100;
603 
604  test_data = (grn_test_data *)data;
605  if (test_data->set_parameters)
606  test_data->set_parameters();
607 
609 
610  cut_assert_equal_uint(0, GRN_HASH_SIZE(hash));
611  test_data_add_n_data(n_data, test_data);
612  cut_assert_equal_uint(n_data, GRN_HASH_SIZE(hash));
614  cut_assert_equal_uint(0, GRN_HASH_SIZE(hash));
615 }