tyler-trie 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION.yml +4 -0
- data/ext/libdatrie/AUTHORS +1 -0
- data/ext/libdatrie/COPYING +510 -0
- data/ext/libdatrie/ChangeLog +410 -0
- data/ext/libdatrie/INSTALL +236 -0
- data/ext/libdatrie/Makefile.am +5 -0
- data/ext/libdatrie/Makefile.in +661 -0
- data/ext/libdatrie/NEWS +27 -0
- data/ext/libdatrie/README +32 -0
- data/ext/libdatrie/aclocal.m4 +7431 -0
- data/ext/libdatrie/config.guess +1516 -0
- data/ext/libdatrie/config.h.in +74 -0
- data/ext/libdatrie/config.sub +1626 -0
- data/ext/libdatrie/configure +22008 -0
- data/ext/libdatrie/configure.ac +71 -0
- data/ext/libdatrie/datrie.pc.in +11 -0
- data/ext/libdatrie/datrie/Makefile.am +35 -0
- data/ext/libdatrie/datrie/Makefile.in +522 -0
- data/ext/libdatrie/datrie/alpha-map.c +170 -0
- data/ext/libdatrie/datrie/alpha-map.h +36 -0
- data/ext/libdatrie/datrie/darray.c +674 -0
- data/ext/libdatrie/datrie/darray.h +229 -0
- data/ext/libdatrie/datrie/fileutils.c +151 -0
- data/ext/libdatrie/datrie/fileutils.h +36 -0
- data/ext/libdatrie/datrie/libdatrie.def +31 -0
- data/ext/libdatrie/datrie/sb-trie.c +331 -0
- data/ext/libdatrie/datrie/sb-trie.h +279 -0
- data/ext/libdatrie/datrie/tail.c +344 -0
- data/ext/libdatrie/datrie/tail.h +200 -0
- data/ext/libdatrie/datrie/trie-private.h +31 -0
- data/ext/libdatrie/datrie/trie.c +413 -0
- data/ext/libdatrie/datrie/trie.h +270 -0
- data/ext/libdatrie/datrie/triedefs.h +63 -0
- data/ext/libdatrie/datrie/typedefs.h +113 -0
- data/ext/libdatrie/depcomp +530 -0
- data/ext/libdatrie/doc/Doxyfile.in +244 -0
- data/ext/libdatrie/doc/Makefile.am +29 -0
- data/ext/libdatrie/doc/Makefile.in +352 -0
- data/ext/libdatrie/install-sh +323 -0
- data/ext/libdatrie/ltmain.sh +6938 -0
- data/ext/libdatrie/man/Makefile.am +4 -0
- data/ext/libdatrie/man/Makefile.in +381 -0
- data/ext/libdatrie/man/trietool.1 +107 -0
- data/ext/libdatrie/missing +360 -0
- data/ext/libdatrie/tools/Makefile.am +7 -0
- data/ext/libdatrie/tools/Makefile.in +460 -0
- data/ext/libdatrie/tools/trietool.c +308 -0
- data/ext/trie/extconf.rb +12 -0
- data/ext/trie/trie.c +174 -0
- data/lib/trie.rb +1 -0
- data/spec/test-trie/README +1 -0
- data/spec/trie_spec.rb +79 -0
- 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
|
+
*/
|