Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-patricia-trie-search.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 "test-patricia-trie.h"
20 
21 void data_lcp_search(void);
22 void test_lcp_search(gconstpointer data);
23 void data_prefix_search(void);
24 void test_prefix_search(gconstpointer data);
25 void data_suffix_search(void);
26 void test_suffix_search(gconstpointer data);
27 
28 static GList *keys;
29 
30 static grn_hash *hash;
31 
32 void
33 cut_setup(void)
34 {
35  setup_trie_common("patricia-trie-search");
36 
37  hash = NULL;
38 
39  keys = NULL;
40 
41  default_encoding = GRN_ENC_UTF8;
42 }
43 
44 static void
45 keys_free(void)
46 {
47  if (keys) {
48  gcut_list_string_free(keys);
49  keys = NULL;
50  }
51 }
52 
53 static void
54 hash_free(void)
55 {
56  if (context && hash) {
57  grn_hash_close(context, hash);
58  hash = NULL;
59  }
60 }
61 
62 void
64 {
65  keys_free();
66  hash_free();
67  teardown_trie_common();
68 }
69 
70 #define create_hash() \
71  hash = grn_hash_create(context, NULL, sizeof(grn_id), \
72  0, GRN_HASH_TINY)
73 
74 #define cut_assert_create_hash() do \
75 { \
76  clear_messages(); \
77  hash_free(); \
78  create_hash(); \
79  cut_assert_equal_g_list_string(NULL, messages()); \
80  cut_assert(hash); \
81 } while (0)
82 
83 
84 static GList *
85 retrieve_all_keys(void)
86 {
87  grn_id hash_id;
88  grn_hash_cursor *cursor;
89 
90  keys_free();
91 
92  cursor = grn_hash_cursor_open(context, hash,
93  NULL, 0, NULL, 0, 0, -1,
95  hash_id = grn_hash_cursor_next(context, cursor);
96  while (hash_id != GRN_ID_NIL) {
97  grn_id *trie_id;
98  void *hash_key;
99  GString *null_terminated_key;
100  gchar key[GRN_PAT_MAX_KEY_SIZE];
101  int size;
102 
103  grn_hash_cursor_get_key(context, cursor, &hash_key);
104  trie_id = hash_key;
105  size = grn_pat_get_key(context, trie, *trie_id, key, sizeof(key));
106  null_terminated_key = g_string_new_len(key, size);
107  keys = g_list_append(keys, g_string_free(null_terminated_key, FALSE));
108  hash_id = grn_hash_cursor_next(context, cursor);
109  }
111 
112  return keys;
113 }
114 
115 static grn_trie_test_data *lcp_test_data_new(const gchar *expected_key,
116  const gchar *search_key,
117  grn_test_set_parameters_func set_parameters,
118  ...) G_GNUC_NULL_TERMINATED;
119 static grn_trie_test_data *
120 lcp_test_data_new(const gchar *expected_key, const gchar *search_key,
121  grn_test_set_parameters_func set_parameters, ...)
122 {
123  grn_trie_test_data *test_data;
124  va_list args;
125 
126  va_start(args, set_parameters);
127  test_data = trie_test_data_newv(NULL, search_key, expected_key,
128  GRN_SUCCESS, NULL, NULL,
129  set_parameters, &args);
130  va_end(args);
131 
132  return test_data;
133 }
134 
135 static void
136 lcp_test_data_free(grn_trie_test_data *test_data)
137 {
138  trie_test_data_free(test_data);
139 }
140 
141 void
143 {
144  cut_add_data("default - nonexistence",
145  lcp_test_data_new(NULL, "カッター", NULL, NULL),
146  lcp_test_data_free,
147  "default - short",
148  lcp_test_data_new(NULL, "セ", NULL, NULL),
149  lcp_test_data_free,
150  "default - exact",
151  lcp_test_data_new("セナ", "セナ", NULL, NULL),
152  lcp_test_data_free,
153  "default - long",
154  lcp_test_data_new("セナセナ", "セナセナセナ", NULL, NULL),
155  lcp_test_data_free,
156  "sis - nonexistence",
157  lcp_test_data_new(NULL, "カッター", set_sis, NULL),
158  lcp_test_data_free,
159  "sis - short",
160  lcp_test_data_new("セ", "セ", set_sis, NULL),
161  lcp_test_data_free,
162  "sis - exact",
163  lcp_test_data_new("セナ", "セナ", set_sis, NULL),
164  lcp_test_data_free,
165  "sis - long",
166  lcp_test_data_new("セナセナ", "セナセナセナ",
167  set_sis, NULL),
168  lcp_test_data_free);
169 }
170 
171 void
172 test_lcp_search(gconstpointer data)
173 {
174  const grn_trie_test_data *test_data = data;
175  gchar key[GRN_PAT_MAX_KEY_SIZE];
176  const gchar key1[] = "セナ";
177  const gchar key2[] = "ナセナセ";
178  const gchar key3[] = "Groonga";
179  const gchar key4[] = "セナ + Ruby";
180  const gchar key5[] = "セナセナ";
181 
182  trie_test_data_set_parameters(test_data);
183 
185 
186  cut_assert_lookup_add(key1);
187  cut_assert_lookup_add(key2);
188  cut_assert_lookup_add(key3);
189  cut_assert_lookup_add(key4);
190  cut_assert_lookup_add(key5);
191 
192  id = grn_pat_lcp_search(context, trie,
193  test_data->search_key,
194  strlen(test_data->search_key));
195  if (test_data->expected_key) {
196  int size;
197  const gchar *null_terminated_key;
198 
200  size = grn_pat_get_key(context, trie, id, key, sizeof(key));
201  null_terminated_key = cut_take_strndup(key, size);
202  cut_assert_equal_string(test_data->expected_key, null_terminated_key);
203  } else {
205  }
206 }
207 
208 static grn_trie_test_data *xfix_test_data_new(grn_rc expected_rc,
209  GList *expected_keys,
210  const gchar *search_key,
211  grn_test_set_parameters_func set_parameters,
212  ...) G_GNUC_NULL_TERMINATED;
213 static grn_trie_test_data *
214 xfix_test_data_new(grn_rc expected_rc, GList *expected_keys,
215  const gchar *search_key,
216  grn_test_set_parameters_func set_parameters, ...)
217 {
218  grn_trie_test_data *test_data;
219  va_list args;
220 
221  va_start(args, set_parameters);
222  test_data = trie_test_data_newv(NULL, search_key, NULL, expected_rc,
223  expected_keys, NULL,
224  set_parameters, &args);
225  va_end(args);
226 
227  return test_data;
228 }
229 
230 static void
231 xfix_test_data_free(grn_trie_test_data *test_data)
232 {
233  trie_test_data_free(test_data);
234 }
235 
236 void
238 {
239  cut_add_data("default - nonexistence",
240  xfix_test_data_new(GRN_END_OF_DATA, NULL, "カッター", NULL, NULL),
241  xfix_test_data_free,
242  "default - short",
243  xfix_test_data_new(GRN_SUCCESS,
244  gcut_list_string_new("セナ", "セナ + Ruby",
245  "セナセナ", NULL),
246  "セ", NULL, NULL),
247  xfix_test_data_free,
248  "default - exact",
249  xfix_test_data_new(GRN_SUCCESS,
250  gcut_list_string_new("セナ", "セナ + Ruby",
251  "セナセナ", NULL),
252  "セナ", NULL, NULL),
253  xfix_test_data_free,
254  "default - long",
255  xfix_test_data_new(GRN_END_OF_DATA, NULL, "セナセナセナ",
256  NULL, NULL),
257  xfix_test_data_free,
258  "sis - nonexistence",
259  xfix_test_data_new(GRN_END_OF_DATA, NULL, "カッター",
260  set_sis, NULL),
261  xfix_test_data_free,
262  "sis - short",
263  xfix_test_data_new(GRN_SUCCESS,
264  gcut_list_string_new("セ", "セナ",
265  "セナ + Ruby",
266  "セナセ", "セナセナ",
267  NULL),
268  "セ", set_sis, NULL),
269  xfix_test_data_free,
270  "sis - exact",
271  xfix_test_data_new(GRN_SUCCESS,
272  gcut_list_string_new("セナ",
273  "セナ + Ruby",
274  "セナセ", "セナセナ",
275  NULL),
276  "セナ", set_sis, NULL),
277  xfix_test_data_free,
278  "sis - long",
279  xfix_test_data_new(GRN_END_OF_DATA, NULL, "セナセナセナ",
280  set_sis, NULL),
281  xfix_test_data_free);
282 }
283 
284 void
285 test_prefix_search(gconstpointer data)
286 {
287  const grn_trie_test_data *test_data = data;
288  const gchar key1[] = "セナ";
289  const gchar key2[] = "ナセナセ";
290  const gchar key3[] = "Groonga";
291  const gchar key4[] = "セナ + Ruby";
292  const gchar key5[] = "セナセナ";
293 
294  trie_test_data_set_parameters(test_data);
295 
297 
298  cut_assert_lookup_add(key1);
299  cut_assert_lookup_add(key2);
300  cut_assert_lookup_add(key3);
301  cut_assert_lookup_add(key4);
302  cut_assert_lookup_add(key5);
303 
307  test_data->search_key,
308  strlen(test_data->search_key),
309  hash));
310  gcut_assert_equal_list_string(test_data->expected_strings,
311  retrieve_all_keys());
312 }
313 
314 void
316 {
317  cut_add_data("default - nonexistence",
318  xfix_test_data_new(GRN_END_OF_DATA, NULL, "カッター", NULL, NULL),
319  xfix_test_data_free,
320  "default - short",
321  xfix_test_data_new(GRN_END_OF_DATA, NULL, "ナ", NULL, NULL),
322  xfix_test_data_free,
323  "default - exact",
324  xfix_test_data_new(GRN_SUCCESS,
325  gcut_list_string_new("セナ", NULL),
326  "セナ", NULL, NULL),
327  xfix_test_data_free,
328  "default - long",
329  xfix_test_data_new(GRN_END_OF_DATA, NULL, "セナセナセナ",
330  NULL, NULL),
331  xfix_test_data_free,
332  "sis - nonexistence",
333  xfix_test_data_new(GRN_END_OF_DATA, NULL, "カッター",
334  set_sis, NULL),
335  xfix_test_data_free,
336  "sis - short",
337  xfix_test_data_new(GRN_SUCCESS,
338  gcut_list_string_new("セナセナ",
339  "ナセナ",
340  "セナ",
341  "ナ",
342  NULL),
343  "ナ", set_sis, NULL),
344  xfix_test_data_free,
345  "sis - exact",
346  xfix_test_data_new(GRN_SUCCESS,
347  gcut_list_string_new("セナセナ",
348  "ナセナ",
349  "セナ",
350  NULL),
351  "セナ", set_sis, NULL),
352  xfix_test_data_free,
353  "sis - long",
354  xfix_test_data_new(GRN_END_OF_DATA, NULL, "セナセナセナ",
355  set_sis, NULL),
356  xfix_test_data_free);
357 }
358 
359 void
360 test_suffix_search(gconstpointer data)
361 {
362  const grn_trie_test_data *test_data = data;
363  const gchar key1[] = "セナ";
364  const gchar key2[] = "ナセナセ";
365  const gchar key3[] = "Groonga";
366  const gchar key4[] = "セナ + Ruby";
367  const gchar key5[] = "セナセナ";
368 
369  trie_test_data_set_parameters(test_data);
370 
372 
373  cut_assert_lookup_add(key1);
374  cut_assert_lookup_add(key2);
375  cut_assert_lookup_add(key3);
376  cut_assert_lookup_add(key4);
377  cut_assert_lookup_add(key5);
378 
382  test_data->search_key,
383  strlen(test_data->search_key),
384  hash));
385  gcut_assert_equal_list_string(test_data->expected_strings,
386  retrieve_all_keys());
387 }