tyler-trie 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/VERSION.yml +4 -0
  2. data/ext/libdatrie/AUTHORS +1 -0
  3. data/ext/libdatrie/COPYING +510 -0
  4. data/ext/libdatrie/ChangeLog +410 -0
  5. data/ext/libdatrie/INSTALL +236 -0
  6. data/ext/libdatrie/Makefile.am +5 -0
  7. data/ext/libdatrie/Makefile.in +661 -0
  8. data/ext/libdatrie/NEWS +27 -0
  9. data/ext/libdatrie/README +32 -0
  10. data/ext/libdatrie/aclocal.m4 +7431 -0
  11. data/ext/libdatrie/config.guess +1516 -0
  12. data/ext/libdatrie/config.h.in +74 -0
  13. data/ext/libdatrie/config.sub +1626 -0
  14. data/ext/libdatrie/configure +22008 -0
  15. data/ext/libdatrie/configure.ac +71 -0
  16. data/ext/libdatrie/datrie.pc.in +11 -0
  17. data/ext/libdatrie/datrie/Makefile.am +35 -0
  18. data/ext/libdatrie/datrie/Makefile.in +522 -0
  19. data/ext/libdatrie/datrie/alpha-map.c +170 -0
  20. data/ext/libdatrie/datrie/alpha-map.h +36 -0
  21. data/ext/libdatrie/datrie/darray.c +674 -0
  22. data/ext/libdatrie/datrie/darray.h +229 -0
  23. data/ext/libdatrie/datrie/fileutils.c +151 -0
  24. data/ext/libdatrie/datrie/fileutils.h +36 -0
  25. data/ext/libdatrie/datrie/libdatrie.def +31 -0
  26. data/ext/libdatrie/datrie/sb-trie.c +331 -0
  27. data/ext/libdatrie/datrie/sb-trie.h +279 -0
  28. data/ext/libdatrie/datrie/tail.c +344 -0
  29. data/ext/libdatrie/datrie/tail.h +200 -0
  30. data/ext/libdatrie/datrie/trie-private.h +31 -0
  31. data/ext/libdatrie/datrie/trie.c +413 -0
  32. data/ext/libdatrie/datrie/trie.h +270 -0
  33. data/ext/libdatrie/datrie/triedefs.h +63 -0
  34. data/ext/libdatrie/datrie/typedefs.h +113 -0
  35. data/ext/libdatrie/depcomp +530 -0
  36. data/ext/libdatrie/doc/Doxyfile.in +244 -0
  37. data/ext/libdatrie/doc/Makefile.am +29 -0
  38. data/ext/libdatrie/doc/Makefile.in +352 -0
  39. data/ext/libdatrie/install-sh +323 -0
  40. data/ext/libdatrie/ltmain.sh +6938 -0
  41. data/ext/libdatrie/man/Makefile.am +4 -0
  42. data/ext/libdatrie/man/Makefile.in +381 -0
  43. data/ext/libdatrie/man/trietool.1 +107 -0
  44. data/ext/libdatrie/missing +360 -0
  45. data/ext/libdatrie/tools/Makefile.am +7 -0
  46. data/ext/libdatrie/tools/Makefile.in +460 -0
  47. data/ext/libdatrie/tools/trietool.c +308 -0
  48. data/ext/trie/extconf.rb +12 -0
  49. data/ext/trie/trie.c +174 -0
  50. data/lib/trie.rb +1 -0
  51. data/spec/test-trie/README +1 -0
  52. data/spec/trie_spec.rb +79 -0
  53. metadata +139 -0
@@ -0,0 +1,31 @@
1
+ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ * trie-private.h - Private utilities for trie implementation
4
+ * Created: 2007-08-25
5
+ * Author: Theppitak Karoonboonyanan <thep@linux.thai.net>
6
+ */
7
+
8
+ #ifndef __TRIE_PRIVATE_H
9
+ #define __TRIE_PRIVATE_H
10
+
11
+ #include <datrie/typedefs.h>
12
+
13
+ /**
14
+ * @file trie-private.h
15
+ * @brief Private utilities for trie implementation
16
+ */
17
+
18
+ /**
19
+ * @brief Minimum value macro
20
+ */
21
+ #define MIN_VAL(a,b) ((a)<(b)?(a):(b))
22
+ /**
23
+ * @brief Maximum value macro
24
+ */
25
+ #define MAX_VAL(a,b) ((a)>(b)?(a):(b))
26
+
27
+ #endif /* __TRIE_PRIVATE_H */
28
+
29
+ /*
30
+ vi:ts=4:ai:expandtab
31
+ */
@@ -0,0 +1,413 @@
1
+ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ * trie.c - Trie data type and functions
4
+ * Created: 2006-08-11
5
+ * Author: Theppitak Karoonboonyanan <thep@linux.thai.net>
6
+ */
7
+
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+
11
+ #include "trie.h"
12
+ #include "darray.h"
13
+ #include "tail.h"
14
+
15
+ /**
16
+ * @brief Trie structure
17
+ */
18
+ struct _Trie {
19
+ DArray *da;
20
+ Tail *tail;
21
+ };
22
+
23
+ /**
24
+ * @brief TrieState structure
25
+ */
26
+ struct _TrieState {
27
+ Trie *trie; /**< the corresponding trie */
28
+ TrieIndex index; /**< index in double-array/tail structures */
29
+ short suffix_idx; /**< suffix character offset, if in suffix */
30
+ short is_suffix; /**< whether it is currently in suffix part */
31
+ };
32
+
33
+ /*------------------------*
34
+ * INTERNAL FUNCTIONS *
35
+ *------------------------*/
36
+
37
+ #define trie_da_is_separate(da,s) (da_get_base ((da), (s)) < 0)
38
+ #define trie_da_get_tail_index(da,s) (-da_get_base ((da), (s)))
39
+ #define trie_da_set_tail_index(da,s,v) (da_set_base ((da), (s), -(v)))
40
+
41
+ static TrieState * trie_state_new (Trie *trie,
42
+ TrieIndex index,
43
+ short suffix_idx,
44
+ short is_suffix);
45
+
46
+ static Bool trie_branch_in_branch (Trie *trie,
47
+ TrieIndex sep_node,
48
+ const TrieChar *suffix,
49
+ TrieData data);
50
+
51
+ static Bool trie_branch_in_tail (Trie *trie,
52
+ TrieIndex sep_node,
53
+ const TrieChar *suffix,
54
+ TrieData data);
55
+
56
+ /*-----------------------*
57
+ * GENERAL FUNCTIONS *
58
+ *-----------------------*/
59
+
60
+ Trie *
61
+ trie_open (const char *path, const char *name, TrieIOMode mode)
62
+ {
63
+ Trie *trie;
64
+
65
+ trie = (Trie *) malloc (sizeof (Trie));
66
+ if (!trie)
67
+ return NULL;
68
+
69
+ if (NULL == (trie->da = da_open (path, name, mode)))
70
+ goto exit1;
71
+ if (NULL == (trie->tail = tail_open (path, name, mode)))
72
+ goto exit2;
73
+
74
+ return trie;
75
+
76
+ exit2:
77
+ da_close (trie->da);
78
+ exit1:
79
+ free (trie);
80
+ return NULL;
81
+ }
82
+
83
+ int
84
+ trie_close (Trie *trie)
85
+ {
86
+ if (!trie)
87
+ return -1;
88
+
89
+ if (da_close (trie->da) != 0)
90
+ return -1;
91
+
92
+ if (tail_close (trie->tail) != 0)
93
+ return -1;
94
+
95
+ free (trie);
96
+
97
+ return 0;
98
+ }
99
+
100
+ int
101
+ trie_save (Trie *trie)
102
+ {
103
+ if (!trie)
104
+ return -1;
105
+
106
+ if (da_save (trie->da) != 0)
107
+ return -1;
108
+
109
+ if (tail_save (trie->tail) != 0)
110
+ return -1;
111
+
112
+ return 0;
113
+ }
114
+
115
+
116
+ /*------------------------------*
117
+ * GENERAL QUERY OPERATIONS *
118
+ *------------------------------*/
119
+
120
+ Bool
121
+ trie_retrieve (Trie *trie, const TrieChar *key, TrieData *o_data)
122
+ {
123
+ TrieIndex s;
124
+ short suffix_idx;
125
+ const TrieChar *p;
126
+ size_t len;
127
+
128
+ /* walk through branches */
129
+ s = da_get_root (trie->da);
130
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
131
+ if (!da_walk (trie->da, &s, *p))
132
+ return FALSE;
133
+ if ('\0' == *p)
134
+ break;
135
+ }
136
+
137
+ /* walk through tail */
138
+ s = trie_da_get_tail_index (trie->da, s);
139
+ suffix_idx = 0;
140
+ len = strlen ((const char *) p) + 1; /* including null-terminator */
141
+ if (tail_walk_str (trie->tail, s, &suffix_idx, p, len) != len)
142
+ return FALSE;
143
+
144
+ /* found, set the val and return */
145
+ if (o_data)
146
+ *o_data = tail_get_data (trie->tail, s);
147
+ return TRUE;
148
+ }
149
+
150
+ Bool
151
+ trie_store (Trie *trie, const TrieChar *key, TrieData data)
152
+ {
153
+ TrieIndex s, t;
154
+ short suffix_idx;
155
+ const TrieChar *p;
156
+ size_t len;
157
+
158
+ /* walk through branches */
159
+ s = da_get_root (trie->da);
160
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
161
+ if (!da_walk (trie->da, &s, *p))
162
+ return trie_branch_in_branch (trie, s, p, data);
163
+ if ('\0' == *p)
164
+ break;
165
+ }
166
+
167
+ /* walk through tail */
168
+ t = trie_da_get_tail_index (trie->da, s);
169
+ suffix_idx = 0;
170
+ len = strlen ((const char *) p) + 1; /* including null-terminator */
171
+ if (tail_walk_str (trie->tail, t, &suffix_idx, p, len) != len)
172
+ return trie_branch_in_tail (trie, s, p, data);
173
+
174
+ /* duplicated key, overwrite val */
175
+ tail_set_data (trie->tail, t, data);
176
+ return TRUE;
177
+ }
178
+
179
+ static Bool
180
+ trie_branch_in_branch (Trie *trie,
181
+ TrieIndex sep_node,
182
+ const TrieChar *suffix,
183
+ TrieData data)
184
+ {
185
+ TrieIndex new_da, new_tail;
186
+
187
+ new_da = da_insert_branch (trie->da, sep_node, *suffix);
188
+ if (TRIE_INDEX_ERROR == new_da)
189
+ return FALSE;
190
+
191
+ if ('\0' != *suffix)
192
+ ++suffix;
193
+
194
+ new_tail = tail_add_suffix (trie->tail, suffix);
195
+ tail_set_data (trie->tail, new_tail, data);
196
+ trie_da_set_tail_index (trie->da, new_da, new_tail);
197
+
198
+ return TRUE;
199
+ }
200
+
201
+ static Bool
202
+ trie_branch_in_tail (Trie *trie,
203
+ TrieIndex sep_node,
204
+ const TrieChar *suffix,
205
+ TrieData data)
206
+ {
207
+ TrieIndex old_tail, old_da, s;
208
+ const TrieChar *old_suffix, *p;
209
+
210
+ /* adjust separate point in old path */
211
+ old_tail = trie_da_get_tail_index (trie->da, sep_node);
212
+ old_suffix = tail_get_suffix (trie->tail, old_tail);
213
+ if (!old_suffix)
214
+ return FALSE;
215
+
216
+ for (p = old_suffix, s = sep_node; *p == *suffix; p++, suffix++) {
217
+ TrieIndex t = da_insert_branch (trie->da, s, *p);
218
+ if (TRIE_INDEX_ERROR == t)
219
+ goto fail;
220
+ s = t;
221
+ }
222
+
223
+ old_da = da_insert_branch (trie->da, s, *p);
224
+ if (TRIE_INDEX_ERROR == old_da)
225
+ goto fail;
226
+
227
+ if ('\0' != *p)
228
+ ++p;
229
+ tail_set_suffix (trie->tail, old_tail, p);
230
+ trie_da_set_tail_index (trie->da, old_da, old_tail);
231
+
232
+ /* insert the new branch at the new separate point */
233
+ return trie_branch_in_branch (trie, s, suffix, data);
234
+
235
+ fail:
236
+ /* failed, undo previous insertions and return error */
237
+ da_prune_upto (trie->da, sep_node, s);
238
+ trie_da_set_tail_index (trie->da, sep_node, old_tail);
239
+ return FALSE;
240
+ }
241
+
242
+ Bool
243
+ trie_delete (Trie *trie, const TrieChar *key)
244
+ {
245
+ TrieIndex s, t;
246
+ short suffix_idx;
247
+ const TrieChar *p;
248
+ size_t len;
249
+
250
+ /* walk through branches */
251
+ s = da_get_root (trie->da);
252
+ for (p = key; !trie_da_is_separate (trie->da, s); p++) {
253
+ if (!da_walk (trie->da, &s, *p))
254
+ return FALSE;
255
+ if ('\0' == *p)
256
+ break;
257
+ }
258
+
259
+ /* walk through tail */
260
+ t = trie_da_get_tail_index (trie->da, s);
261
+ suffix_idx = 0;
262
+ len = strlen ((const char *) p) + 1; /* including null-terminator */
263
+ if (tail_walk_str (trie->tail, t, &suffix_idx, p, len) != len)
264
+ return FALSE;
265
+
266
+ tail_delete (trie->tail, t);
267
+ da_set_base (trie->da, s, TRIE_INDEX_ERROR);
268
+ da_prune (trie->da, s);
269
+
270
+ return TRUE;
271
+ }
272
+
273
+ typedef struct {
274
+ Trie *trie;
275
+ TrieEnumFunc enum_func;
276
+ void *user_data;
277
+ } _TrieEnumData;
278
+
279
+ static Bool
280
+ trie_da_enum_func (const TrieChar *key, TrieIndex sep_node, void *user_data)
281
+ {
282
+ _TrieEnumData *enum_data;
283
+ TrieIndex t;
284
+ const TrieChar *suffix;
285
+ TrieChar *full_key;
286
+ Bool ret;
287
+
288
+ enum_data = (_TrieEnumData *) user_data;
289
+
290
+ t = trie_da_get_tail_index (enum_data->trie->da, sep_node);
291
+ suffix = tail_get_suffix (enum_data->trie->tail, t);
292
+
293
+ full_key = (TrieChar *) malloc (strlen ((const char *)key)
294
+ + strlen ((const char *)suffix) + 1);
295
+ strcat (strcpy ((char *)full_key, (const char *)key), (const char *)suffix);
296
+
297
+ ret = (*enum_data->enum_func) (full_key,
298
+ tail_get_data (enum_data->trie->tail, t),
299
+ enum_data->user_data);
300
+
301
+ free (full_key);
302
+ return ret;
303
+ }
304
+
305
+ Bool
306
+ trie_enumerate (Trie *trie, TrieEnumFunc enum_func, void *user_data)
307
+ {
308
+ _TrieEnumData enum_data;
309
+
310
+ enum_data.trie = trie;
311
+ enum_data.enum_func = enum_func;
312
+ enum_data.user_data = user_data;
313
+
314
+ return da_enumerate (trie->da, trie_da_enum_func, &enum_data);
315
+ }
316
+
317
+
318
+ /*-------------------------------*
319
+ * STEPWISE QUERY OPERATIONS *
320
+ *-------------------------------*/
321
+
322
+ TrieState *
323
+ trie_root (Trie *trie)
324
+ {
325
+ return trie_state_new (trie, da_get_root (trie->da), 0, FALSE);
326
+ }
327
+
328
+ /*----------------*
329
+ * TRIE STATE *
330
+ *----------------*/
331
+
332
+ static TrieState *
333
+ trie_state_new (Trie *trie, TrieIndex index, short suffix_idx, short is_suffix)
334
+ {
335
+ TrieState *s;
336
+
337
+ s = (TrieState *) malloc (sizeof (TrieState));
338
+ if (!s)
339
+ return NULL;
340
+
341
+ s->trie = trie;
342
+ s->index = index;
343
+ s->suffix_idx = suffix_idx;
344
+ s->is_suffix = is_suffix;
345
+
346
+ return s;
347
+ }
348
+
349
+ TrieState *
350
+ trie_state_clone (const TrieState *s)
351
+ {
352
+ return trie_state_new (s->trie, s->index, s->suffix_idx, s->is_suffix);
353
+ }
354
+
355
+ void
356
+ trie_state_free (TrieState *s)
357
+ {
358
+ free (s);
359
+ }
360
+
361
+ void
362
+ trie_state_rewind (TrieState *s)
363
+ {
364
+ s->index = da_get_root (s->trie->da);
365
+ s->is_suffix = FALSE;
366
+ }
367
+
368
+ Bool
369
+ trie_state_walk (TrieState *s, TrieChar c)
370
+ {
371
+ if (!s->is_suffix) {
372
+ Bool ret;
373
+
374
+ ret = da_walk (s->trie->da, &s->index, c);
375
+
376
+ if (ret && trie_da_is_separate (s->trie->da, s->index)) {
377
+ s->index = trie_da_get_tail_index (s->trie->da, s->index);
378
+ s->suffix_idx = 0;
379
+ s->is_suffix = TRUE;
380
+ }
381
+
382
+ return ret;
383
+ } else {
384
+ return tail_walk_char (s->trie->tail, s->index, &s->suffix_idx, c);
385
+ }
386
+ }
387
+
388
+ Bool
389
+ trie_state_is_walkable (const TrieState *s, TrieChar c)
390
+ {
391
+ if (!s->is_suffix)
392
+ return da_is_walkable (s->trie->da, s->index, c);
393
+ else
394
+ return tail_is_walkable_char (s->trie->tail, s->index, s->suffix_idx,
395
+ c);
396
+ }
397
+
398
+ Bool
399
+ trie_state_is_leaf (const TrieState *s)
400
+ {
401
+ return s->is_suffix && trie_state_is_terminal (s);
402
+ }
403
+
404
+ TrieData
405
+ trie_state_get_data (const TrieState *s)
406
+ {
407
+ return s->is_suffix ? tail_get_data (s->trie->tail, s->index)
408
+ : TRIE_DATA_ERROR;
409
+ }
410
+
411
+ /*
412
+ vi:ts=4:ai:expandtab
413
+ */
@@ -0,0 +1,270 @@
1
+ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ * trie.h - Trie data type and functions
4
+ * Created: 2006-08-11
5
+ * Author: Theppitak Karoonboonyanan <thep@linux.thai.net>
6
+ */
7
+
8
+ #ifndef __TRIE_H
9
+ #define __TRIE_H
10
+
11
+ #include <datrie/triedefs.h>
12
+
13
+ #ifdef __cplusplus
14
+ extern "C" {
15
+ #endif
16
+
17
+ /**
18
+ * @file trie.h
19
+ * @brief Trie data type and functions
20
+ */
21
+
22
+ /**
23
+ * @brief Trie data type
24
+ */
25
+ typedef struct _Trie Trie;
26
+
27
+ /**
28
+ * @brief Trie enumeration function
29
+ *
30
+ * @param key : the key of the entry
31
+ * @param data : the data of the entry
32
+ *
33
+ * @return TRUE to continue enumeration, FALSE to stop
34
+ */
35
+ typedef Bool (*TrieEnumFunc) (const TrieChar *key,
36
+ TrieData key_data,
37
+ void *user_data);
38
+
39
+ /**
40
+ * @brief Trie walking state
41
+ */
42
+ typedef struct _TrieState TrieState;
43
+
44
+ /*-----------------------*
45
+ * GENERAL FUNCTIONS *
46
+ *-----------------------*/
47
+
48
+ /**
49
+ * @brief Open a trie
50
+ *
51
+ * @param path : the path that stores the trie files
52
+ * @param name : the name of the trie (not actual file name)
53
+ * @param mode : openning mode, read or write
54
+ *
55
+ * @return a pointer to the openned trie, NULL on failure
56
+ *
57
+ * Open a trie of given name. Note that @a name here does not mean the
58
+ * actual file name. Rather, the file name will be inferred by the name.
59
+ */
60
+ Trie * trie_open (const char *path, const char *name, TrieIOMode mode);
61
+
62
+ /**
63
+ * @brief Close a trie
64
+ *
65
+ * @param trie: the trie
66
+ *
67
+ * @return 0 on success, non-zero on failure
68
+ *
69
+ * Close the given trie. If @a trie was openned for writing, all pending
70
+ * changes will be saved to file.
71
+ */
72
+ int trie_close (Trie *trie);
73
+
74
+ /**
75
+ * @brief Save a trie
76
+ *
77
+ * @param trie: the trie
78
+ *
79
+ * @return 0 on success, non-zero on failure
80
+ *
81
+ * If @a trie was openned for writing, save all pending data to file.
82
+ */
83
+ int trie_save (Trie *trie);
84
+
85
+
86
+ /*------------------------------*
87
+ * GENERAL QUERY OPERATIONS *
88
+ *------------------------------*/
89
+
90
+ /**
91
+ * @brief Retrieve an entry from trie
92
+ *
93
+ * @param trie : the trie
94
+ * @param key : the key for the entry to retrieve
95
+ * @param o_data : the storage for storing the entry data on return
96
+ *
97
+ * @return boolean value indicating the existence of the entry.
98
+ *
99
+ * Retrieve an entry for the given @a key from @a trie. On return,
100
+ * if @a key is found and @a o_val is not NULL, @a *o_val is set
101
+ * to the data associated to @a key.
102
+ */
103
+ Bool trie_retrieve (Trie *trie, const TrieChar *key, TrieData *o_data);
104
+
105
+ /**
106
+ * @brief Store a value for an entry to trie
107
+ *
108
+ * @param trie : the trie
109
+ * @param key : the key for the entry to retrieve
110
+ * @param data : the data associated to the entry
111
+ *
112
+ * @return boolean value indicating the success of the process
113
+ *
114
+ * Store a data @a data for the given @a key in @a trie. If @a key does not
115
+ * exist in @a trie, it will be appended.
116
+ */
117
+ Bool trie_store (Trie *trie, const TrieChar *key, TrieData data);
118
+
119
+ /**
120
+ * @brief Delete an entry from trie
121
+ *
122
+ * @param trie : the trie
123
+ * @param key : the key for the entry to delete
124
+ *
125
+ * @return boolean value indicating whether the key exists and is removed
126
+ *
127
+ * Delete an entry for the given @a key from @a trie.
128
+ */
129
+ Bool trie_delete (Trie *trie, const TrieChar *key);
130
+
131
+ /**
132
+ * @brief Enumerate entries in trie
133
+ *
134
+ * @param trie : the trie
135
+ * @param enum_func : the callback function to be called on each key
136
+ * @param user_data : user-supplied data to send as an argument to @a enum_func
137
+ *
138
+ * @return boolean value indicating whether all the keys are visited
139
+ *
140
+ * Enumerate all entries in trie. For each entry, the user-supplied
141
+ * @a enum_func callback function is called, with the entry key and data.
142
+ * Returning FALSE from such callback will stop enumeration and return FALSE.
143
+ */
144
+ Bool trie_enumerate (Trie *trie, TrieEnumFunc enum_func, void *user_data);
145
+
146
+
147
+ /*-------------------------------*
148
+ * STEPWISE QUERY OPERATIONS *
149
+ *-------------------------------*/
150
+
151
+ /**
152
+ * @brief Get root state of a trie
153
+ *
154
+ * @param trie : the trie
155
+ *
156
+ * @return the root state of the trie
157
+ *
158
+ * Get root state of @a trie, for stepwise walking.
159
+ *
160
+ * The returned state is allocated and must be freed with trie_state_free()
161
+ */
162
+ TrieState * trie_root (Trie *trie);
163
+
164
+
165
+ /*----------------*
166
+ * TRIE STATE *
167
+ *----------------*/
168
+
169
+ /**
170
+ * @brief Clone a trie state
171
+ *
172
+ * @param s : the state to clone
173
+ *
174
+ * @return an duplicated instance of @a s
175
+ *
176
+ * Make a copy of trie state.
177
+ *
178
+ * The returned state is allocated and must be freed with trie_state_free()
179
+ */
180
+ TrieState * trie_state_clone (const TrieState *s);
181
+
182
+ /**
183
+ * @brief Free a trie state
184
+ *
185
+ * @param s : the state to free
186
+ *
187
+ * Free the trie state.
188
+ */
189
+ void trie_state_free (TrieState *s);
190
+
191
+ /**
192
+ * @brief Rewind a trie state
193
+ *
194
+ * @param s : the state to rewind
195
+ *
196
+ * Put the state at root.
197
+ */
198
+ void trie_state_rewind (TrieState *s);
199
+
200
+ /**
201
+ * @brief Walk the trie from the state
202
+ *
203
+ * @param s : current state
204
+ * @param c : key character for walking
205
+ *
206
+ * @return boolean value indicating the success of the walk
207
+ *
208
+ * Walk the trie stepwise, using a given character @a c.
209
+ * On return, the state @a s is updated to the new state if successfully walked.
210
+ */
211
+ Bool trie_state_walk (TrieState *s, TrieChar c);
212
+
213
+ /**
214
+ * @brief Test walkability of character from state
215
+ *
216
+ * @param s : the state to check
217
+ * @param c : the input character
218
+ *
219
+ * @return boolean indicating walkability
220
+ *
221
+ * Test if there is a transition from state @a s with input character @a c.
222
+ */
223
+ Bool trie_state_is_walkable (const TrieState *s, TrieChar c);
224
+
225
+ /**
226
+ * @brief Check for terminal state
227
+ *
228
+ * @param s : the state to check
229
+ *
230
+ * @return boolean value indicating whether it is a terminal state
231
+ *
232
+ * Check if the given state is a terminal state. A leaf state is a trie state
233
+ * that terminates a key, and stores a value associated with the key.
234
+ */
235
+ #define trie_state_is_terminal(s) trie_state_is_walkable((s),TRIE_CHAR_TERM)
236
+
237
+ /**
238
+ * @brief Check for leaf state
239
+ *
240
+ * @param s : the state to check
241
+ *
242
+ * @return boolean value indicating whether it is a leaf state
243
+ *
244
+ * Check if the given state is a leaf state. A leaf state is a terminal state
245
+ * that has no other branch.
246
+ */
247
+ Bool trie_state_is_leaf (const TrieState *s);
248
+
249
+ /**
250
+ * @brief Get data from leaf state
251
+ *
252
+ * @param s : the leaf state
253
+ *
254
+ * @return the data associated with the leaf state @a s,
255
+ * or TRIE_DATA_ERROR if @a s is not a leaf state
256
+ *
257
+ * Get value from a leaf state of trie. Getting the value from leaf state
258
+ * will result in TRIE_DATA_ERROR.
259
+ */
260
+ TrieData trie_state_get_data (const TrieState *s);
261
+
262
+ #ifdef __cplusplus
263
+ }
264
+ #endif
265
+
266
+ #endif /* __TRIE_H */
267
+
268
+ /*
269
+ vi:ts=4:ai:expandtab
270
+ */