Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-patricia-trie.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2008-2009 Kouhei Sutou <kou@cozmixng.org>
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 <pat.h>
20 
21 #include <gcutter.h>
22 #include <glib/gstdio.h>
23 
24 #include "../lib/grn-assertions.h"
25 
26 #define DEFAULT_VALUE_SIZE 64
27 
28 static grn_logger_info *logger;
29 
30 static GList *expected_messages;
31 
32 static grn_ctx *context;
33 static grn_pat *trie;
34 static grn_pat_cursor *cursor;
35 static grn_id id;
36 static void *value;
37 
38 static gchar *sample_key;
39 static const gchar *sample_value;
40 static grn_id sample_id;
41 
42 static const gchar *base_dir;
43 
44 static gchar *default_path;
45 static uint32_t default_key_size;
46 static uint32_t default_value_size;
47 static uint32_t default_flags;
48 static grn_encoding default_encoding;
49 
50 static gchar *default_cursor_min;
51 static uint32_t default_cursor_min_size;
52 static gchar *default_cursor_max;
53 static uint32_t default_cursor_max_size;
54 static int default_cursor_offset;
55 static int default_cursor_limit;
56 static int default_cursor_flags;
57 
58 static uint32_t default_context_flags;
59 
60 static void
61 setup_trie_common(const gchar *default_path_component)
62 {
63  logger = setup_grn_logger();
64 
65  expected_messages = NULL;
66 
67  context = NULL;
68  trie = NULL;
69  cursor = NULL;
70  id = GRN_ID_NIL;
71 
72  sample_key = g_strdup("sample-key");
73  sample_value = cut_take_string(g_strdup("patricia trie test"));
74  sample_id = GRN_ID_NIL;
75 
76  base_dir = grn_test_get_tmp_dir();
77  default_path = g_build_filename(base_dir, default_path_component, NULL);
78  default_key_size = GRN_PAT_MAX_KEY_SIZE / 2;
79  default_value_size = DEFAULT_VALUE_SIZE;
80  default_flags = GRN_OBJ_KEY_VAR_SIZE;
81  default_encoding = GRN_ENC_DEFAULT;
82 
83  default_cursor_min = NULL;
84  default_cursor_min_size = 0;
85  default_cursor_max = NULL;
86  default_cursor_max_size = 0;
87  default_cursor_offset = 0;
88  default_cursor_limit = -1;
89  default_cursor_flags = 0;
90 
91  default_context_flags = GRN_CTX_USE_QL;
92 
93  cut_remove_path(base_dir, NULL);
94  g_mkdir_with_parents(base_dir, 0755);
95 }
96 
97 static void
98 expected_messages_free(void)
99 {
100  if (expected_messages) {
101  gcut_list_string_free(expected_messages);
102  expected_messages = NULL;
103  }
104 }
105 
106 static void
107 cursor_free(void)
108 {
109  if (context && cursor) {
110  grn_pat_cursor_close(context, cursor);
111  cursor = NULL;
112  }
113 }
114 
115 static void
116 trie_free(void)
117 {
118  if (context && trie) {
119  grn_pat_close(context, trie);
120  trie = NULL;
121  }
122 }
123 
124 static void
125 context_free(void)
126 {
127  if (context) {
128  cursor_free();
129  trie_free();
130  grn_ctx_fin(context);
131  context = NULL;
132  }
133 }
134 
135 static void
136 teardown_trie_common(void)
137 {
138  expected_messages_free();
139  context_free();
140 
141  if (sample_key) {
142  g_free(sample_key);
143  }
144 
145  if (default_path) {
146  g_free(default_path);
147  }
148 
149  if (base_dir) {
150  cut_remove_path(base_dir, NULL);
151  }
152 
153  teardown_grn_logger(logger);
154 }
155 
156 #define clear_messages() \
157  grn_collect_logger_clear_messages(logger)
158 
159 #define messages() \
160  grn_collect_logger_get_messages(logger)
161 
162 #define open_context() do \
163 { \
164  context = g_new0(grn_ctx, 1); \
165  grn_test_assert(grn_ctx_init(context, \
166  default_context_flags)); \
167  GRN_CTX_SET_ENCODING(context, default_encoding); \
168 } while (0)
169 
170 #define cut_assert_open_context() do \
171 { \
172  context_free(); \
173  open_context(); \
174  cut_assert(context); \
175 } while (0)
176 
177 #define create_trie() do \
178 { \
179  GRN_CTX_SET_ENCODING(context, default_encoding); \
180  trie = grn_pat_create(context, default_path, default_key_size, \
181  default_value_size, default_flags); \
182 } while (0)
183 
184 #define cut_assert_create_trie() do \
185 { \
186  cut_assert_open_context(); \
187  trie_free(); \
188  create_trie(); \
189  grn_test_assert_context(context); \
190  cut_assert(trie); \
191 } while (0)
192 
193 #define open_trie() \
194  trie = grn_pat_open(context, default_path)
195 
196 #define cut_assert_open_trie() do \
197 { \
198  clear_messages(); \
199  cut_assert_open_context(); \
200  trie_free(); \
201  open_trie(); \
202  gcut_assert_equal_list_string(NULL, messages()); \
203  cut_assert(trie); \
204 } while (0)
205 
206 #define cut_assert_fail_open_trie() do \
207 { \
208  cut_assert_open_context(); \
209  trie_free(); \
210  open_trie(); \
211  cut_assert_null(trie); \
212 } while (0)
213 
214 typedef int grn_search_flags;
215 
216 #define GRN_TABLE_ADD (0x01<<6)
217 
218 #define lookup(key, key_size, flags) \
219  (((*(flags) & GRN_TABLE_ADD)) \
220  ? grn_pat_add(context, trie, key, key_size, &value, flags) \
221  : grn_pat_get(context, trie, key, key_size, &value))
222 
223 #define cut_assert_lookup(key, key_size, flags) do \
224 { \
225  grn_test_assert_not_nil((id = lookup(key, key_size, (flags))), \
226  cut_message("flags: <%d>", *(flags))); \
227 } while (0)
228 
229 #define cut_assert_lookup_failed(key, key_size, flags) do \
230 { \
231  grn_test_assert_nil(lookup(key, key_size, (flags)), \
232  cut_message("flags: <%d>", *(flags))); \
233 } while (0)
234 
235 #define cut_assert_lookup_add(key) do \
236 { \
237  const gchar *_key; \
238  uint32_t key_size; \
239  grn_search_flags flags; \
240  grn_id found_id; \
241  \
242  _key = (key); \
243  if (_key) { \
244  key_size = strlen(_key); \
245  } else { \
246  key_size = 0; \
247  } \
248  \
249  flags = 0; \
250  cut_assert_lookup_failed(_key, key_size, &flags); \
251  \
252  flags = GRN_TABLE_ADD; \
253  cut_assert_lookup(_key, key_size, &flags); \
254  cut_assert_equal_int(1, flags & 1); \
255  found_id = id; \
256  if (sample_value) { \
257  strcpy(value, sample_value); \
258  value = NULL; \
259  } \
260  \
261  flags = 0; \
262  cut_assert_lookup(_key, key_size, &flags); \
263  cut_assert_equal_int(found_id, id); \
264  if (sample_value) { \
265  cut_assert_equal_string(sample_value, value); \
266  value = NULL; \
267  } \
268  \
269  flags = GRN_TABLE_ADD; \
270  cut_assert_lookup(_key, key_size, &flags); \
271  cut_assert_equal_uint(0, flags & 1); \
272  cut_assert_equal_uint(found_id, id); \
273  if (sample_value) { \
274  cut_assert_equal_string(sample_value, value); \
275  } \
276 } while (0)
277 
278 #define put_sample_entry() do \
279 { \
280  cut_assert_lookup_add(sample_key); \
281  sample_id = id; \
282 } while (0)
283 
284 #define open_cursor() \
285  cursor = grn_pat_cursor_open(context, trie, \
286  default_cursor_min, \
287  default_cursor_min_size, \
288  default_cursor_max, \
289  default_cursor_max_size, \
290  default_cursor_offset, \
291  default_cursor_limit, \
292  default_cursor_flags)
293 
294 #define cut_assert_open_cursor() do \
295 { \
296  clear_messages(); \
297  cursor_free(); \
298  open_cursor(); \
299  cut_assert_equal_g_list_string(NULL, messages()); \
300  cut_assert(cursor); \
301 } while (0)
302 
304 typedef void (*increment_key_func) (grn_trie_test_data *test_data);
305 
307  gchar *key;
308  gchar *search_key;
310  gchar *expected_key;
314 };
315 
316 static grn_trie_test_data *
317 trie_test_data_newv(const gchar *key,
318  const gchar *search_key,
319  const gchar *expected_key,
320  grn_rc expected_rc,
321  GList *expected_strings,
322  increment_key_func increment,
323  grn_test_set_parameters_func set_parameters,
324  va_list *args)
325 {
326  grn_trie_test_data *test_data;
327 
328  test_data = g_new0(grn_trie_test_data, 1);
329  test_data->key = g_strdup(key);
330  test_data->search_key = g_strdup(search_key);
331  test_data->expected_key = g_strdup(expected_key);
332  test_data->expected_rc = expected_rc;
333  test_data->expected_strings = expected_strings;
334  test_data->increment = increment;
335  test_data->set_parameters_funcs = NULL;
336  while (set_parameters) {
337  test_data->set_parameters_funcs =
338  g_list_append(test_data->set_parameters_funcs, set_parameters);
339  if (args && *args)
340  set_parameters = va_arg(*args, grn_test_set_parameters_func);
341  else
342  set_parameters = NULL;
343  }
344 
345  return test_data;
346 }
347 
348 static void
349 trie_test_data_free(grn_trie_test_data *test_data)
350 {
351  if (test_data->key)
352  g_free(test_data->key);
353  if (test_data->search_key)
354  g_free(test_data->search_key);
355  if (test_data->expected_key)
356  g_free(test_data->expected_key);
357  if (test_data->expected_strings)
358  gcut_list_string_free(test_data->expected_strings);
359  g_list_free(test_data->set_parameters_funcs);
360  g_free(test_data);
361 }
362 
363 static void
364 trie_test_data_set_parameters(const grn_trie_test_data *data)
365 {
366  GList *node;
367 
368  for (node = data->set_parameters_funcs; node; node = g_list_next(node)) {
369  grn_test_set_parameters_func set_parameters = node->data;
370  set_parameters();
371  }
372 }
373 
374 static void
375 set_sis(void)
376 {
377  default_flags |= GRN_OBJ_KEY_WITH_SIS;
378 }