tyler-trie 0.1.2 → 0.1.3
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 +1 -1
- data/ext/trie/trie.c +60 -4
- data/spec/trie_spec.rb +23 -0
- metadata +1 -1
data/VERSION.yml
CHANGED
data/ext/trie/trie.c
CHANGED
@@ -83,13 +83,21 @@ static VALUE trie_get(VALUE self, VALUE key) {
|
|
83
83
|
return Qnil;
|
84
84
|
}
|
85
85
|
|
86
|
-
static VALUE trie_add(VALUE self, VALUE
|
86
|
+
static VALUE trie_add(VALUE self, VALUE args) {
|
87
87
|
SBTrie *sb_trie;
|
88
88
|
Data_Get_Struct(self, SBTrie, sb_trie);
|
89
89
|
|
90
|
+
long size = RARRAY(args)->len;
|
91
|
+
if(size < 1 || size > 2)
|
92
|
+
return Qnil;
|
93
|
+
|
94
|
+
VALUE key;
|
95
|
+
key = RARRAY(args)->ptr[0];
|
96
|
+
short value = size == 2 ? NUM2INT(RARRAY(args)->ptr[1]) : TRIE_DATA_ERROR;
|
97
|
+
|
90
98
|
const TrieChar *sb_key = stringToTrieChar(key);
|
91
99
|
|
92
|
-
if(sb_trie_store(sb_trie, sb_key,
|
100
|
+
if(sb_trie_store(sb_trie, sb_key, value))
|
93
101
|
return Qtrue;
|
94
102
|
else
|
95
103
|
return Qnil;
|
@@ -114,7 +122,7 @@ static VALUE walk_all_paths(VALUE children, SBTrieState *state, char *prefix) {
|
|
114
122
|
SBTrieState *next_state = sb_trie_state_clone(state);
|
115
123
|
sb_trie_state_walk(next_state, (TrieChar)c);
|
116
124
|
|
117
|
-
char *word = (char*)
|
125
|
+
char *word = (char*)malloc(strlen(prefix) + 2);
|
118
126
|
strcat(strcpy(word, prefix), (char*)&c);
|
119
127
|
|
120
128
|
if(sb_trie_state_is_terminal(next_state))
|
@@ -154,6 +162,53 @@ static VALUE trie_children(VALUE self, VALUE prefix) {
|
|
154
162
|
return children;
|
155
163
|
}
|
156
164
|
|
165
|
+
static VALUE trie_walk_to_terminal(VALUE self, VALUE args) {
|
166
|
+
SBTrie *sb_trie;
|
167
|
+
Data_Get_Struct(self, SBTrie, sb_trie);
|
168
|
+
|
169
|
+
long size = RARRAY(args)->len;
|
170
|
+
if(size < 1 || size > 2)
|
171
|
+
return Qnil;
|
172
|
+
|
173
|
+
VALUE rb_path;
|
174
|
+
rb_path = RARRAY(args)->ptr[0];
|
175
|
+
short include_value = size == 2 ? RTEST(RARRAY(args)->ptr[1]) : 0;
|
176
|
+
|
177
|
+
SBTrieState *state = sb_trie_root(sb_trie);
|
178
|
+
|
179
|
+
char *path = RSTRING(rb_path)->ptr;
|
180
|
+
|
181
|
+
TrieChar *iterator = (TrieChar*)path;
|
182
|
+
while(*iterator != '\0') {
|
183
|
+
if(sb_trie_state_is_terminal(state)) {
|
184
|
+
int word_length = (int)iterator - (int)path;
|
185
|
+
char *word = (char*)malloc(word_length + 1);
|
186
|
+
strncpy(word, path, word_length);
|
187
|
+
word[word_length] = '\0';
|
188
|
+
VALUE rb_word = rb_str_new2((const char*)word);
|
189
|
+
|
190
|
+
if(include_value) {
|
191
|
+
sb_trie_state_walk(state, (TrieChar)'\0');
|
192
|
+
|
193
|
+
VALUE return_ary = rb_ary_new();
|
194
|
+
rb_ary_push(return_ary, rb_word);
|
195
|
+
TrieData trie_data = sb_trie_state_get_data(state);
|
196
|
+
rb_ary_push(return_ary, INT2FIX(trie_data));
|
197
|
+
return return_ary;
|
198
|
+
} else
|
199
|
+
return rb_word;
|
200
|
+
}
|
201
|
+
|
202
|
+
if(!sb_trie_state_is_walkable(state, *iterator))
|
203
|
+
return Qnil;
|
204
|
+
|
205
|
+
sb_trie_state_walk(state, *iterator);
|
206
|
+
iterator++;
|
207
|
+
}
|
208
|
+
|
209
|
+
return Qnil;
|
210
|
+
}
|
211
|
+
|
157
212
|
static VALUE trie_get_path(VALUE self) {
|
158
213
|
return rb_iv_get(self, "@path");
|
159
214
|
}
|
@@ -167,8 +222,9 @@ void Init_trie() {
|
|
167
222
|
rb_define_method(cTrie, "path", trie_get_path, 0);
|
168
223
|
rb_define_method(cTrie, "has_key?", trie_has_key, 1);
|
169
224
|
rb_define_method(cTrie, "get", trie_get, 1);
|
170
|
-
rb_define_method(cTrie, "add", trie_add,
|
225
|
+
rb_define_method(cTrie, "add", trie_add, -2);
|
171
226
|
rb_define_method(cTrie, "delete", trie_delete, 1);
|
172
227
|
rb_define_method(cTrie, "close", trie_close, 0);
|
173
228
|
rb_define_method(cTrie, "children", trie_children, 1);
|
229
|
+
rb_define_method(cTrie, "walk_to_terminal", trie_walk_to_terminal, -2);
|
174
230
|
}
|
data/spec/trie_spec.rb
CHANGED
@@ -48,6 +48,11 @@ describe Trie do
|
|
48
48
|
@trie.add('forsooth').should == true
|
49
49
|
@trie.get('forsooth').should == -1
|
50
50
|
end
|
51
|
+
|
52
|
+
it 'adds a word with a weight to the trie' do
|
53
|
+
@trie.add('chicka',123).should == true
|
54
|
+
@trie.get('chicka').should == 123
|
55
|
+
end
|
51
56
|
end
|
52
57
|
|
53
58
|
describe :delete do
|
@@ -76,4 +81,22 @@ describe Trie do
|
|
76
81
|
children.should include('rocket')
|
77
82
|
end
|
78
83
|
end
|
84
|
+
|
85
|
+
describe :walk_to_terminal do
|
86
|
+
it 'returns the first word found along a path' do
|
87
|
+
@trie.add 'anderson'
|
88
|
+
@trie.add 'andreas'
|
89
|
+
@trie.add 'and'
|
90
|
+
|
91
|
+
@trie.walk_to_terminal('anderson').should == 'and'
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns the first word and value along a path' do
|
95
|
+
@trie.add 'anderson'
|
96
|
+
@trie.add 'andreas'
|
97
|
+
@trie.add 'and', 15
|
98
|
+
|
99
|
+
@trie.walk_to_terminal('anderson',true).should == ['and', 15]
|
100
|
+
end
|
101
|
+
end
|
79
102
|
end
|