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.
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