tyler-trie 0.2.3 → 0.3.1
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/README.textile +3 -14
- data/VERSION.yml +2 -2
- data/ext/trie/Makefile +149 -0
- data/ext/trie/darray.c +673 -0
- data/ext/trie/darray.h +233 -0
- data/ext/trie/extconf.rb +0 -7
- data/ext/trie/fileutils.c +151 -0
- data/ext/trie/fileutils.h +36 -0
- data/ext/trie/tail.c +340 -0
- data/ext/trie/tail.h +207 -0
- data/ext/trie/trie-private.c +271 -0
- data/ext/trie/trie-private.h +31 -0
- data/ext/trie/trie.c +204 -301
- data/ext/trie/trie.h +40 -0
- data/ext/trie/triedefs.h +73 -0
- data/lib/trie.rb +1 -1
- data/spec/trie_spec.rb +31 -47
- metadata +14 -7
- data/spec/test-trie/README +0 -1
@@ -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
|
+
*/
|
data/ext/trie/trie.c
CHANGED
@@ -1,393 +1,298 @@
|
|
1
1
|
#include "ruby.h"
|
2
|
-
#include
|
2
|
+
#include "trie.h"
|
3
3
|
#include <stdlib.h>
|
4
4
|
#include <stdio.h>
|
5
5
|
#include <string.h>
|
6
6
|
|
7
7
|
VALUE cTrie, cTrieNode;
|
8
8
|
|
9
|
-
static
|
10
|
-
|
11
|
-
|
9
|
+
static VALUE rb_trie_alloc(VALUE klass) {
|
10
|
+
VALUE obj;
|
11
|
+
obj = Data_Wrap_Struct(klass, 0, trie_free, trie_new());
|
12
|
+
return obj;
|
12
13
|
}
|
13
14
|
|
14
|
-
static
|
15
|
-
|
16
|
-
|
17
|
-
}
|
18
|
-
|
19
|
-
static VALUE trie_alloc(VALUE klass) {
|
20
|
-
SBTrie *sb_trie;
|
21
|
-
VALUE obj;
|
22
|
-
|
23
|
-
obj = Data_Wrap_Struct(klass, 0, trie_free, sb_trie);
|
24
|
-
rb_iv_set(obj, "@open", Qfalse);
|
25
|
-
|
26
|
-
return obj;
|
27
|
-
}
|
28
|
-
|
29
|
-
static VALUE trie_initialize(VALUE self, VALUE path) {
|
30
|
-
SBTrie *sb_trie;
|
31
|
-
|
32
|
-
char *cpath = RSTRING(path)->ptr;
|
33
|
-
char *full_path = (char*)malloc(strlen(cpath) + 10);
|
34
|
-
sprintf(full_path, "%s/trie.sbm", cpath);
|
35
|
-
|
36
|
-
FILE *file;
|
37
|
-
|
38
|
-
file = fopen (full_path, "r");
|
39
|
-
if (!file) {
|
40
|
-
file = fopen (full_path, "w+");
|
41
|
-
fprintf(file,"[00,FF]\n");
|
42
|
-
}
|
43
|
-
fclose(file);
|
44
|
-
free (full_path);
|
45
|
-
|
46
|
-
// replace the pretend SBTrie created in alloc with a real one
|
47
|
-
RDATA(self)->data = sb_trie_open(cpath, "trie",
|
48
|
-
TRIE_IO_READ | TRIE_IO_WRITE | TRIE_IO_CREATE);
|
49
|
-
|
50
|
-
rb_iv_set(self, "@open", Qtrue);
|
51
|
-
rb_iv_set(self, "@path", path);
|
52
|
-
return self;
|
53
|
-
}
|
54
|
-
|
55
|
-
static VALUE trie_close(VALUE self) {
|
56
|
-
SBTrie *sb_trie;
|
57
|
-
Data_Get_Struct(self, SBTrie, sb_trie);
|
15
|
+
static VALUE rb_trie_has_key(VALUE self, VALUE key) {
|
16
|
+
Trie *trie;
|
17
|
+
Data_Get_Struct(self, Trie, trie);
|
58
18
|
|
59
|
-
|
60
|
-
|
61
|
-
return self;
|
62
|
-
}
|
63
|
-
|
64
|
-
static VALUE trie_has_key(VALUE self, VALUE key) {
|
65
|
-
SBTrie *sb_trie;
|
66
|
-
Data_Get_Struct(self, SBTrie, sb_trie);
|
67
|
-
|
68
|
-
const TrieChar *sb_key = (const TrieChar *)RSTRING(key)->ptr;
|
69
|
-
|
70
|
-
if(sb_trie_retrieve(sb_trie, sb_key, NULL))
|
71
|
-
return Qtrue;
|
19
|
+
if(trie_retrieve(trie, (TrieChar*)RSTRING(key)->ptr, NULL))
|
20
|
+
return Qtrue;
|
72
21
|
else
|
73
|
-
|
22
|
+
return Qnil;
|
74
23
|
}
|
75
24
|
|
76
|
-
static VALUE
|
77
|
-
|
78
|
-
|
79
|
-
Data_Get_Struct(self, SBTrie, sb_trie);
|
80
|
-
|
81
|
-
const TrieChar *sb_key = stringToTrieChar(key);
|
25
|
+
static VALUE rb_trie_get(VALUE self, VALUE key) {
|
26
|
+
Trie *trie;
|
27
|
+
Data_Get_Struct(self, Trie, trie);
|
82
28
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
29
|
+
TrieData data;
|
30
|
+
if(trie_retrieve(trie, (TrieChar*)RSTRING(key)->ptr, &data))
|
31
|
+
return INT2FIX(data);
|
32
|
+
else
|
33
|
+
return Qnil;
|
87
34
|
}
|
88
35
|
|
89
|
-
static VALUE
|
90
|
-
|
91
|
-
Data_Get_Struct(self,
|
36
|
+
static VALUE rb_trie_add(VALUE self, VALUE args) {
|
37
|
+
Trie *trie;
|
38
|
+
Data_Get_Struct(self, Trie, trie);
|
92
39
|
|
93
|
-
|
40
|
+
int size = RARRAY(args)->len;
|
94
41
|
if(size < 1 || size > 2)
|
95
|
-
|
42
|
+
return Qnil;
|
96
43
|
|
97
44
|
VALUE key;
|
98
45
|
key = RARRAY(args)->ptr[0];
|
99
46
|
TrieData value = size == 2 ? NUM2INT(RARRAY(args)->ptr[1]) : TRIE_DATA_ERROR;
|
100
47
|
|
101
|
-
|
102
|
-
|
103
|
-
if(sb_trie_store(sb_trie, sb_key, value))
|
104
|
-
return Qtrue;
|
48
|
+
if(trie_store(trie, (TrieChar*)RSTRING(key)->ptr, value))
|
49
|
+
return Qtrue;
|
105
50
|
else
|
106
|
-
|
51
|
+
return Qnil;
|
107
52
|
}
|
108
53
|
|
109
|
-
static VALUE
|
110
|
-
|
111
|
-
Data_Get_Struct(self,
|
112
|
-
|
113
|
-
const TrieChar *sb_key = stringToTrieChar(key);
|
54
|
+
static VALUE rb_trie_delete(VALUE self, VALUE key) {
|
55
|
+
Trie *trie;
|
56
|
+
Data_Get_Struct(self, Trie, trie);
|
114
57
|
|
115
|
-
if(
|
116
|
-
|
58
|
+
if(trie_delete(trie, (TrieChar*)RSTRING(key)->ptr))
|
59
|
+
return Qtrue;
|
117
60
|
else
|
118
|
-
|
61
|
+
return Qnil;
|
119
62
|
}
|
120
63
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
return
|
127
|
-
else
|
128
|
-
return Qtrue;
|
64
|
+
char* append_char(char* existing, int size, char c) {
|
65
|
+
char *new = (char*) malloc(size + 2);
|
66
|
+
memcpy(new, existing, size);
|
67
|
+
new[size] = c;
|
68
|
+
new[size + 1] = 0;
|
69
|
+
return new;
|
129
70
|
}
|
130
71
|
|
131
|
-
static VALUE walk_all_paths(VALUE children,
|
132
|
-
|
133
|
-
for(c = 1; c <
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
72
|
+
static VALUE walk_all_paths(Trie *trie, VALUE children, TrieState *state, char *prefix, int prefix_size) {
|
73
|
+
int c;
|
74
|
+
for(c = 1; c < 256; c++) {
|
75
|
+
if(trie_state_is_walkable(state,c)) {
|
76
|
+
TrieState *next_state = trie_state_clone(state);
|
77
|
+
trie_state_walk(next_state, c);
|
78
|
+
|
79
|
+
prefix[prefix_size] = c;
|
80
|
+
prefix[prefix_size + 1] = 0;
|
81
|
+
|
82
|
+
if(trie_state_is_terminal(next_state)) {
|
83
|
+
char *word = (char*) malloc(prefix_size + 2);
|
84
|
+
memcpy(word, prefix, prefix_size + 2);
|
85
|
+
rb_ary_push(children, rb_str_new2(word));
|
86
|
+
}
|
87
|
+
|
88
|
+
walk_all_paths(trie, children, next_state, prefix, prefix_size + 1);
|
89
|
+
|
90
|
+
prefix[prefix_size] = 0;
|
91
|
+
trie_state_free(next_state);
|
92
|
+
}
|
148
93
|
}
|
149
94
|
}
|
150
95
|
|
151
|
-
static VALUE
|
96
|
+
static VALUE rb_trie_children(VALUE self, VALUE prefix) {
|
152
97
|
if(NIL_P(prefix))
|
153
|
-
|
98
|
+
return rb_ary_new();
|
154
99
|
|
155
|
-
|
156
|
-
Data_Get_Struct(self,
|
100
|
+
Trie *trie;
|
101
|
+
Data_Get_Struct(self, Trie, trie);
|
157
102
|
|
158
|
-
|
159
|
-
|
103
|
+
int prefix_size = RSTRING(prefix)->len;
|
104
|
+
TrieState *state = trie_root(trie);
|
160
105
|
VALUE children = rb_ary_new();
|
161
|
-
|
162
|
-
SBTrieState *state = sb_trie_root(sb_trie);
|
106
|
+
TrieChar *char_prefix = (TrieChar*)RSTRING(prefix)->ptr;
|
163
107
|
|
164
|
-
TrieChar *iterator =
|
165
|
-
while(*iterator !=
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
108
|
+
const TrieChar *iterator = char_prefix;
|
109
|
+
while(*iterator != 0) {
|
110
|
+
if(!trie_state_is_walkable(state, *iterator))
|
111
|
+
return children;
|
112
|
+
trie_state_walk(state, *iterator);
|
113
|
+
iterator++;
|
170
114
|
}
|
171
115
|
|
172
|
-
if(
|
173
|
-
|
116
|
+
if(trie_state_is_terminal(state))
|
117
|
+
rb_ary_push(children, prefix);
|
118
|
+
|
119
|
+
char prefix_buffer[1024];
|
120
|
+
memcpy(prefix_buffer, char_prefix, prefix_size);
|
121
|
+
prefix_buffer[prefix_size] = 0;
|
174
122
|
|
175
|
-
walk_all_paths(children, state,
|
123
|
+
walk_all_paths(trie, children, state, prefix_buffer, prefix_size);
|
176
124
|
|
177
|
-
|
125
|
+
trie_state_free(state);
|
178
126
|
return children;
|
179
127
|
}
|
180
|
-
static VALUE walk_all_paths_with_values(VALUE children, SBTrieState *state, char *prefix) {
|
181
|
-
int c;
|
182
|
-
for(c = 1; c < TRIE_CHAR_MAX; c++) {
|
183
|
-
if(sb_trie_state_is_walkable(state,c)) {
|
184
|
-
SBTrieState *next_state = sb_trie_state_clone(state);
|
185
|
-
sb_trie_state_walk(next_state, (TrieChar)c);
|
186
128
|
|
187
|
-
char *word = (char*)malloc(strlen(prefix) + 2);
|
188
|
-
strcat(strcpy(word, prefix), (char*)&c);
|
189
129
|
|
190
|
-
|
191
|
-
|
192
|
-
|
130
|
+
static VALUE walk_all_paths_with_values(Trie *trie, VALUE children, TrieState *state, char *prefix, int prefix_size) {
|
131
|
+
int c;
|
132
|
+
for(c = 1; c < 256; c++) {
|
133
|
+
if(trie_state_is_walkable(state,c)) {
|
134
|
+
TrieState *next_state = trie_state_clone(state);
|
135
|
+
trie_state_walk(next_state, c);
|
193
136
|
|
194
|
-
|
195
|
-
|
196
|
-
TrieData trie_data = sb_trie_state_get_data(end_state);
|
197
|
-
rb_ary_push(tuple, INT2FIX(trie_data));
|
198
|
-
rb_ary_push(children, tuple);
|
137
|
+
prefix[prefix_size] = c;
|
138
|
+
prefix[prefix_size + 1] = 0;
|
199
139
|
|
200
|
-
|
201
|
-
|
140
|
+
if(trie_state_is_terminal(next_state)) {
|
141
|
+
TrieState *end_state = trie_state_clone(next_state);
|
142
|
+
trie_state_walk(end_state, '\0');
|
143
|
+
|
144
|
+
char *word = (char*) malloc(prefix_size + 2);
|
145
|
+
memcpy(word, prefix, prefix_size + 2);
|
202
146
|
|
203
|
-
|
147
|
+
VALUE tuple = rb_ary_new();
|
148
|
+
rb_ary_push(tuple, rb_str_new2(word));
|
204
149
|
|
205
|
-
|
206
|
-
|
150
|
+
TrieData trie_data = trie_state_get_data(end_state);
|
151
|
+
rb_ary_push(tuple, INT2FIX(trie_data));
|
152
|
+
rb_ary_push(children, tuple);
|
153
|
+
|
154
|
+
trie_state_free(end_state);
|
155
|
+
}
|
156
|
+
|
157
|
+
walk_all_paths_with_values(trie, children, next_state, prefix, prefix_size + 1);
|
158
|
+
|
159
|
+
prefix[prefix_size] = 0;
|
160
|
+
trie_state_free(next_state);
|
161
|
+
}
|
207
162
|
}
|
208
163
|
}
|
209
164
|
|
210
|
-
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
static VALUE rb_trie_children_with_values(VALUE self, VALUE prefix) {
|
211
169
|
if(NIL_P(prefix))
|
212
|
-
|
170
|
+
return rb_ary_new();
|
213
171
|
|
214
|
-
|
215
|
-
Data_Get_Struct(self,
|
172
|
+
Trie *trie;
|
173
|
+
Data_Get_Struct(self, Trie, trie);
|
216
174
|
|
217
|
-
|
175
|
+
int prefix_size = RSTRING(prefix)->len;
|
176
|
+
TrieChar *char_prefix = (TrieChar*)RSTRING(prefix)->ptr;
|
218
177
|
|
219
178
|
VALUE children = rb_ary_new();
|
220
179
|
|
221
|
-
|
180
|
+
TrieState *state = trie_root(trie);
|
222
181
|
|
223
|
-
TrieChar *iterator =
|
224
|
-
while(*iterator !=
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
}
|
230
|
-
|
231
|
-
if(sb_trie_state_is_terminal(state)) {
|
232
|
-
SBTrieState *end_state = sb_trie_state_clone(state);
|
233
|
-
sb_trie_state_walk(end_state, '\0');
|
234
|
-
|
235
|
-
VALUE tuple = rb_ary_new();
|
236
|
-
rb_ary_push(tuple, prefix);
|
237
|
-
TrieData trie_data = sb_trie_state_get_data(end_state);
|
238
|
-
rb_ary_push(tuple, INT2FIX(trie_data));
|
239
|
-
rb_ary_push(children, tuple);
|
240
|
-
|
241
|
-
sb_trie_state_free(end_state);
|
182
|
+
const TrieChar *iterator = char_prefix;
|
183
|
+
while(*iterator != 0) {
|
184
|
+
if(!trie_state_is_walkable(state, *iterator))
|
185
|
+
return rb_ary_new();
|
186
|
+
trie_state_walk(state, *iterator);
|
187
|
+
iterator++;
|
242
188
|
}
|
243
189
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
return children;
|
248
|
-
}
|
249
|
-
|
250
|
-
static VALUE trie_walk_to_terminal(VALUE self, VALUE args) {
|
251
|
-
SBTrie *sb_trie;
|
252
|
-
Data_Get_Struct(self, SBTrie, sb_trie);
|
190
|
+
if(trie_state_is_terminal(state)) {
|
191
|
+
TrieState *end_state = trie_state_clone(state);
|
192
|
+
trie_state_walk(end_state, '\0');
|
253
193
|
|
254
|
-
|
255
|
-
|
256
|
-
|
194
|
+
VALUE tuple = rb_ary_new();
|
195
|
+
rb_ary_push(tuple, prefix);
|
196
|
+
TrieData trie_data = trie_state_get_data(end_state);
|
197
|
+
rb_ary_push(tuple, INT2FIX(trie_data));
|
198
|
+
rb_ary_push(children, tuple);
|
257
199
|
|
258
|
-
|
259
|
-
rb_path = RARRAY(args)->ptr[0];
|
260
|
-
short include_value = size == 2 ? RTEST(RARRAY(args)->ptr[1]) : 0;
|
261
|
-
|
262
|
-
SBTrieState *state = sb_trie_root(sb_trie);
|
263
|
-
|
264
|
-
char *path = RSTRING(rb_path)->ptr;
|
265
|
-
|
266
|
-
TrieChar *iterator = (TrieChar*)path;
|
267
|
-
while(*iterator != '\0') {
|
268
|
-
if(sb_trie_state_is_terminal(state)) {
|
269
|
-
int word_length = (int)iterator - (int)path;
|
270
|
-
char *word = (char*)malloc(word_length + 1);
|
271
|
-
strncpy(word, path, word_length);
|
272
|
-
word[word_length] = '\0';
|
273
|
-
VALUE rb_word = rb_str_new2((const char*)word);
|
274
|
-
|
275
|
-
if(include_value) {
|
276
|
-
sb_trie_state_walk(state, (TrieChar)'\0');
|
277
|
-
|
278
|
-
VALUE return_ary = rb_ary_new();
|
279
|
-
rb_ary_push(return_ary, rb_word);
|
280
|
-
TrieData trie_data = sb_trie_state_get_data(state);
|
281
|
-
rb_ary_push(return_ary, INT2FIX(trie_data));
|
282
|
-
return return_ary;
|
283
|
-
} else
|
284
|
-
return rb_word;
|
285
|
-
}
|
286
|
-
|
287
|
-
if(!sb_trie_state_is_walkable(state, *iterator))
|
288
|
-
return Qnil;
|
289
|
-
|
290
|
-
sb_trie_state_walk(state, *iterator);
|
291
|
-
iterator++;
|
200
|
+
trie_state_free(end_state);
|
292
201
|
}
|
293
202
|
|
294
|
-
|
203
|
+
char prefix_buffer[1024];
|
204
|
+
memcpy(prefix_buffer, char_prefix, prefix_size);
|
205
|
+
prefix_buffer[prefix_size] = 0;
|
295
206
|
|
296
|
-
|
297
|
-
}
|
298
|
-
|
299
|
-
static VALUE trie_get_path(VALUE self) {
|
300
|
-
return rb_iv_get(self, "@path");
|
301
|
-
}
|
207
|
+
walk_all_paths_with_values(trie, children, state, prefix_buffer, prefix_size);
|
302
208
|
|
303
|
-
|
304
|
-
|
305
|
-
sb_trie_state_free(state);
|
209
|
+
trie_state_free(state);
|
210
|
+
return children;
|
306
211
|
}
|
307
212
|
|
308
|
-
static VALUE
|
309
|
-
SBTrieState *state;
|
213
|
+
static VALUE rb_trie_node_alloc(VALUE klass) {
|
310
214
|
VALUE obj;
|
311
|
-
|
312
|
-
obj = Data_Wrap_Struct(klass, 0, trie_node_free, state);
|
313
|
-
|
215
|
+
obj = Data_Wrap_Struct(klass, 0, trie_state_free, NULL);
|
314
216
|
return obj;
|
315
217
|
}
|
316
218
|
|
317
|
-
static VALUE
|
318
|
-
|
319
|
-
Data_Get_Struct(self,
|
219
|
+
static VALUE rb_trie_root(VALUE self) {
|
220
|
+
Trie *trie;
|
221
|
+
Data_Get_Struct(self, Trie, trie);
|
320
222
|
|
321
|
-
VALUE trie_node =
|
223
|
+
VALUE trie_node = rb_trie_node_alloc(cTrieNode);
|
322
224
|
|
323
|
-
|
324
|
-
|
225
|
+
TrieState *state = trie_root(trie);
|
226
|
+
RDATA(trie_node)->data = state;
|
325
227
|
|
326
228
|
rb_iv_set(trie_node, "@state", Qnil);
|
327
229
|
rb_iv_set(trie_node, "@full_state", rb_str_new2(""));
|
328
230
|
return trie_node;
|
329
231
|
}
|
330
232
|
|
331
|
-
static VALUE
|
233
|
+
static VALUE rb_trie_node_get_state(VALUE self) {
|
332
234
|
return rb_iv_get(self, "@state");
|
333
235
|
}
|
334
|
-
static VALUE
|
236
|
+
static VALUE rb_trie_node_get_full_state(VALUE self) {
|
335
237
|
return rb_iv_get(self, "@full_state");
|
336
238
|
}
|
337
239
|
|
338
|
-
static VALUE
|
339
|
-
|
340
|
-
Data_Get_Struct(self,
|
240
|
+
static VALUE rb_trie_node_walk_bang(VALUE self, VALUE rchar) {
|
241
|
+
TrieState *state;
|
242
|
+
Data_Get_Struct(self, TrieState, state);
|
341
243
|
|
342
244
|
if(RSTRING(rchar)->len != 1)
|
343
|
-
|
245
|
+
return Qnil;
|
344
246
|
|
345
|
-
|
346
|
-
int result = sb_trie_state_walk(state, (TrieChar)ch);
|
247
|
+
Bool result = trie_state_walk(state, *RSTRING(rchar)->ptr);
|
347
248
|
|
348
249
|
if(result) {
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
250
|
+
rb_iv_set(self, "@state", rchar);
|
251
|
+
VALUE full_state = rb_iv_get(self, "@full_state");
|
252
|
+
rb_str_append(full_state, rchar);
|
253
|
+
rb_iv_set(self, "@full_state", full_state);
|
254
|
+
return self;
|
354
255
|
} else
|
355
|
-
|
256
|
+
return Qnil;
|
356
257
|
}
|
357
258
|
|
358
|
-
static VALUE
|
359
|
-
|
360
|
-
|
259
|
+
static VALUE rb_trie_node_value(VALUE self) {
|
260
|
+
TrieState *state;
|
261
|
+
TrieState *dup;
|
262
|
+
Data_Get_Struct(self, TrieState, state);
|
361
263
|
|
362
|
-
dup =
|
264
|
+
dup = trie_state_clone(state);
|
363
265
|
|
364
|
-
|
365
|
-
TrieData trie_data =
|
366
|
-
|
266
|
+
trie_state_walk(dup, 0);
|
267
|
+
TrieData trie_data = trie_state_get_data(dup);
|
268
|
+
trie_state_free(dup);
|
367
269
|
|
368
270
|
return TRIE_DATA_ERROR == trie_data ? Qnil : INT2FIX(trie_data);
|
369
271
|
}
|
370
272
|
|
371
|
-
static VALUE
|
372
|
-
|
373
|
-
Data_Get_Struct(self,
|
273
|
+
static VALUE rb_trie_node_terminal(VALUE self) {
|
274
|
+
TrieState *state;
|
275
|
+
Data_Get_Struct(self, TrieState, state);
|
374
276
|
|
375
|
-
return
|
277
|
+
return trie_state_is_terminal(state) ? Qtrue : Qnil;
|
376
278
|
}
|
377
279
|
|
378
|
-
static VALUE
|
379
|
-
|
380
|
-
Data_Get_Struct(self,
|
280
|
+
static VALUE rb_trie_node_leaf(VALUE self) {
|
281
|
+
TrieState *state;
|
282
|
+
Data_Get_Struct(self, TrieState, state);
|
381
283
|
|
382
|
-
return
|
284
|
+
return trie_state_is_leaf(state) ? Qtrue : Qnil;
|
383
285
|
}
|
384
286
|
|
385
|
-
static VALUE
|
386
|
-
|
387
|
-
Data_Get_Struct(self,
|
287
|
+
static VALUE rb_trie_node_clone(VALUE self) {
|
288
|
+
TrieState *state;
|
289
|
+
Data_Get_Struct(self, TrieState, state);
|
388
290
|
|
389
|
-
VALUE new_node =
|
390
|
-
|
291
|
+
VALUE new_node = rb_trie_node_alloc(cTrieNode);
|
292
|
+
|
293
|
+
TrieState *new_state = trie_state_clone(state);
|
294
|
+
|
295
|
+
RDATA(new_node)->data = new_state;
|
391
296
|
|
392
297
|
rb_iv_set(new_node, "@state", rb_iv_get(self, "@state"));
|
393
298
|
rb_iv_set(new_node, "@full_state", rb_iv_get(self, "@full_state"));
|
@@ -398,27 +303,25 @@ static VALUE trie_node_clone(VALUE self) {
|
|
398
303
|
|
399
304
|
void Init_trie() {
|
400
305
|
cTrie = rb_define_class("Trie", rb_cObject);
|
401
|
-
rb_define_alloc_func(cTrie,
|
402
|
-
rb_define_method(cTrie, "initialize",
|
403
|
-
rb_define_method(cTrie, "path",
|
404
|
-
rb_define_method(cTrie, "has_key?",
|
405
|
-
rb_define_method(cTrie, "get",
|
406
|
-
rb_define_method(cTrie, "add",
|
407
|
-
rb_define_method(cTrie, "delete",
|
408
|
-
rb_define_method(cTrie, "
|
409
|
-
rb_define_method(cTrie, "
|
410
|
-
rb_define_method(cTrie, "
|
411
|
-
rb_define_method(cTrie, "
|
412
|
-
rb_define_method(cTrie, "root", trie_root, 0);
|
413
|
-
rb_define_method(cTrie, "save", trie_save, 0);
|
306
|
+
rb_define_alloc_func(cTrie, rb_trie_alloc);
|
307
|
+
//rb_define_method(cTrie, "initialize", rb_trie_initialize, -2);
|
308
|
+
//rb_define_method(cTrie, "path", rb_trie_get_path, 0);
|
309
|
+
rb_define_method(cTrie, "has_key?", rb_trie_has_key, 1);
|
310
|
+
rb_define_method(cTrie, "get", rb_trie_get, 1);
|
311
|
+
rb_define_method(cTrie, "add", rb_trie_add, -2);
|
312
|
+
rb_define_method(cTrie, "delete", rb_trie_delete, 1);
|
313
|
+
rb_define_method(cTrie, "children", rb_trie_children, 1);
|
314
|
+
rb_define_method(cTrie, "children_with_values", rb_trie_children_with_values, 1);
|
315
|
+
rb_define_method(cTrie, "root", rb_trie_root, 0);
|
316
|
+
//rb_define_method(cTrie, "save", rb_trie_save, 0);
|
414
317
|
|
415
318
|
cTrieNode = rb_define_class("TrieNode", rb_cObject);
|
416
|
-
rb_define_alloc_func(cTrieNode,
|
417
|
-
rb_define_method(cTrieNode, "state",
|
418
|
-
rb_define_method(cTrieNode, "full_state",
|
419
|
-
rb_define_method(cTrieNode, "walk!",
|
420
|
-
rb_define_method(cTrieNode, "value",
|
421
|
-
rb_define_method(cTrieNode, "terminal?",
|
422
|
-
rb_define_method(cTrieNode, "leaf?",
|
423
|
-
rb_define_method(cTrieNode, "clone",
|
319
|
+
rb_define_alloc_func(cTrieNode, rb_trie_node_alloc);
|
320
|
+
rb_define_method(cTrieNode, "state", rb_trie_node_get_state, 0);
|
321
|
+
rb_define_method(cTrieNode, "full_state", rb_trie_node_get_full_state, 0);
|
322
|
+
rb_define_method(cTrieNode, "walk!", rb_trie_node_walk_bang, 1);
|
323
|
+
rb_define_method(cTrieNode, "value", rb_trie_node_value, 0);
|
324
|
+
rb_define_method(cTrieNode, "terminal?", rb_trie_node_terminal, 0);
|
325
|
+
rb_define_method(cTrieNode, "leaf?", rb_trie_node_leaf, 0);
|
326
|
+
rb_define_method(cTrieNode, "clone", rb_trie_node_clone, 0);
|
424
327
|
}
|