tyler-trie 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION.yml +1 -1
  2. data/ext/trie/trie.c +60 -4
  3. data/spec/trie_spec.rb +23 -0
  4. metadata +1 -1
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- patch: 2
2
+ patch: 3
3
3
  major: 0
4
4
  minor: 1
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 key) {
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, TRIE_DATA_ERROR))
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*) malloc(strlen(prefix) + 2);
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, 1);
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tyler-trie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler McMullen