rambling-trie 0.9.1 → 0.9.2
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.
- checksums.yaml +4 -4
- data/lib/rambling/trie/compressed_node.rb +2 -3
- data/lib/rambling/trie/container.rb +10 -3
- data/lib/rambling/trie/raw_node.rb +4 -12
- data/lib/rambling/trie/version.rb +1 -1
- data/reports/0.8.1/benchmark +1 -0
- data/reports/0.9.2/benchmark +58 -0
- data/spec/lib/rambling/trie/compressed_node_spec.rb +120 -0
- data/spec/lib/rambling/trie/container_spec.rb +67 -7
- data/spec/lib/rambling/trie/raw_node_spec.rb +31 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9db4c20b2cd932bc23376649e312e566eb43e227
|
4
|
+
data.tar.gz: 40e5584acca19930a92cd894e43a51dccca4d1f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0e1a3166c876d3d3730dd439563567fbeb2108b33b908152c1a388daf2edf75cfbc250f67a7c0d00ec3dd923be3e71f770b3d3ff28bbd0ecaeadb3fe3fe162c
|
7
|
+
data.tar.gz: 9f0decef0f2d1dd386677a8631888b4744315ede61b5f5957fd51ebf98b845a4564ea3ada4df60590ffcc8a82a27f5904d7261bd3dc21cf7f422c184932b8781
|
@@ -29,8 +29,7 @@ module Rambling
|
|
29
29
|
# @param [Array] chars the characters to look for in the trie.
|
30
30
|
# @return [Array] all the words contained in the trie that start with the specified characters.
|
31
31
|
def scan chars
|
32
|
-
|
33
|
-
node.to_a
|
32
|
+
chars.empty? ? self : closest_node(chars)
|
34
33
|
end
|
35
34
|
|
36
35
|
# Always return `true` for a raw (compressed) node.
|
@@ -73,7 +72,7 @@ module Rambling
|
|
73
72
|
begin
|
74
73
|
current_length += 1
|
75
74
|
|
76
|
-
if
|
75
|
+
if current_key && (current_key.length == current_length || chars.empty?)
|
77
76
|
return children_tree[current_key.to_sym].send method, chars
|
78
77
|
end
|
79
78
|
end while current_key && current_key[current_length] == chars.slice!(0)
|
@@ -7,11 +7,18 @@ module Rambling
|
|
7
7
|
include ::Enumerable
|
8
8
|
|
9
9
|
delegate [
|
10
|
-
:each,
|
11
|
-
:compressed?,
|
12
10
|
:[],
|
11
|
+
:as_word,
|
12
|
+
:children,
|
13
|
+
:children_tree,
|
14
|
+
:compressed?,
|
15
|
+
:each,
|
16
|
+
:has_key?,
|
17
|
+
:inspect,
|
13
18
|
:letter,
|
14
|
-
:
|
19
|
+
:parent,
|
20
|
+
:size,
|
21
|
+
:to_s
|
15
22
|
] => :root
|
16
23
|
|
17
24
|
# Creates a new Trie.
|
@@ -45,7 +45,7 @@ module Rambling
|
|
45
45
|
# @param [Array] chars the characters to look for in the trie.
|
46
46
|
# @return [Array] all the words contained in the trie that start with the specified characters.
|
47
47
|
def scan chars
|
48
|
-
closest_node
|
48
|
+
chars.empty? ? self : closest_node(chars)
|
49
49
|
end
|
50
50
|
|
51
51
|
# Always return `false` for a raw (uncompressed) node.
|
@@ -57,18 +57,10 @@ module Rambling
|
|
57
57
|
protected
|
58
58
|
|
59
59
|
def closest_node chars
|
60
|
-
|
61
|
-
|
62
|
-
else
|
63
|
-
letter = chars.slice!(0).to_sym
|
64
|
-
child = children_tree[letter]
|
60
|
+
letter = chars.slice!(0).to_sym
|
61
|
+
child = children_tree[letter]
|
65
62
|
|
66
|
-
|
67
|
-
child.closest_node chars
|
68
|
-
else
|
69
|
-
Rambling::Trie::MissingNode.new
|
70
|
-
end
|
71
|
-
end
|
63
|
+
child ? child.scan(chars) : Rambling::Trie::MissingNode.new
|
72
64
|
end
|
73
65
|
|
74
66
|
private
|
data/reports/0.8.1/benchmark
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
Benchmark for rambling-trie version 0.9.2
|
3
|
+
==> Creation
|
4
|
+
`Rambling::Trie.create`
|
5
|
+
8.970000 0.200000 9.170000 ( 9.283692)
|
6
|
+
|
7
|
+
Benchmark for rambling-trie version 0.9.2
|
8
|
+
==> Compression
|
9
|
+
`compress!`
|
10
|
+
1.720000 0.030000 1.750000 ( 1.753067)
|
11
|
+
1.660000 0.000000 1.660000 ( 1.671923)
|
12
|
+
1.430000 0.010000 1.440000 ( 1.446879)
|
13
|
+
1.240000 0.060000 1.300000 ( 1.313478)
|
14
|
+
1.230000 0.060000 1.290000 ( 1.299892)
|
15
|
+
|
16
|
+
Benchmark for rambling-trie version 0.9.2
|
17
|
+
==> Uncompressed
|
18
|
+
`word?`
|
19
|
+
hi true 0.230000 0.000000 0.230000 ( 0.233806)
|
20
|
+
help true 0.390000 0.000000 0.390000 ( 0.388282)
|
21
|
+
beautiful true 0.810000 0.000000 0.810000 ( 0.818193)
|
22
|
+
impressionism true 1.050000 0.010000 1.060000 ( 1.047699)
|
23
|
+
anthropological true 1.150000 0.000000 1.150000 ( 1.158661)
|
24
|
+
`partial_word?`
|
25
|
+
hi true 0.210000 0.000000 0.210000 ( 0.212588)
|
26
|
+
help true 0.410000 0.000000 0.410000 ( 0.409012)
|
27
|
+
beautiful true 0.770000 0.000000 0.770000 ( 0.778091)
|
28
|
+
impressionism true 0.990000 0.010000 1.000000 ( 0.997804)
|
29
|
+
anthropological true 1.140000 0.000000 1.140000 ( 1.142530)
|
30
|
+
==> Compressed
|
31
|
+
`word?`
|
32
|
+
hi true 0.240000 0.000000 0.240000 ( 0.235445)
|
33
|
+
help true 0.390000 0.000000 0.390000 ( 0.397614)
|
34
|
+
beautiful true 0.760000 0.000000 0.760000 ( 0.757404)
|
35
|
+
impressionism true 1.030000 0.000000 1.030000 ( 1.036627)
|
36
|
+
anthropological true 1.290000 0.000000 1.290000 ( 1.291476)
|
37
|
+
`partial_word?`
|
38
|
+
hi true 1.070000 0.010000 1.080000 ( 1.084173)
|
39
|
+
help true 2.170000 0.010000 2.180000 ( 2.183891)
|
40
|
+
beautiful true 2.920000 0.000000 2.920000 ( 2.941010)
|
41
|
+
impressionism true 4.520000 0.010000 4.530000 ( 4.542043)
|
42
|
+
anthropological true 4.350000 0.010000 4.360000 ( 4.362716)
|
43
|
+
|
44
|
+
Benchmark for rambling-trie version 0.9.2
|
45
|
+
==> Uncompressed
|
46
|
+
`scan`
|
47
|
+
hi 495 2.010000 0.010000 2.020000 ( 2.020800)
|
48
|
+
help 20 6.800000 0.050000 6.850000 ( 6.870425)
|
49
|
+
beautiful 6 2.600000 0.010000 2.610000 ( 2.618016)
|
50
|
+
impressionism 2 2.410000 0.000000 2.410000 ( 2.423997)
|
51
|
+
anthropological 2 2.820000 0.010000 2.830000 ( 2.825191)
|
52
|
+
==> Compressed
|
53
|
+
`scan`
|
54
|
+
hi 495 1.180000 0.000000 1.180000 ( 1.191953)
|
55
|
+
help 20 5.350000 0.010000 5.360000 ( 5.360441)
|
56
|
+
beautiful 6 3.190000 0.010000 3.200000 ( 3.224402)
|
57
|
+
impressionism 2 5.790000 0.040000 5.830000 ( 5.892171)
|
58
|
+
anthropological 2 5.580000 0.020000 5.600000 ( 5.629519)
|
@@ -32,4 +32,124 @@ describe Rambling::Trie::CompressedNode do
|
|
32
32
|
expect { node.add 'restaurant' }.to raise_error Rambling::Trie::InvalidOperation
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
describe '#partial_word?' do
|
37
|
+
let(:raw_node) { Rambling::Trie::RawNode.new }
|
38
|
+
let(:compressor) { Rambling::Trie::Compressor.new }
|
39
|
+
let(:node) { compressor.compress raw_node }
|
40
|
+
|
41
|
+
context 'when the chars array is empty' do
|
42
|
+
it 'returns true' do
|
43
|
+
expect(node.partial_word? []).to be true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the chars array is not empty' do
|
48
|
+
context 'when the node has a tree that matches the characters' do
|
49
|
+
before do
|
50
|
+
raw_node.add 'abc'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns true' do
|
54
|
+
expect(node.partial_word? %w(a)).to be true
|
55
|
+
expect(node.partial_word? %w(a b)).to be true
|
56
|
+
expect(node.partial_word? %w(a b c)).to be true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when the node has a tree that does not match the characters' do
|
61
|
+
before do
|
62
|
+
raw_node.add 'cba'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns false' do
|
66
|
+
expect(node.partial_word? %w(a)).to be false
|
67
|
+
expect(node.partial_word? %w(a b)).to be false
|
68
|
+
expect(node.partial_word? %w(a b c)).to be false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#word?' do
|
75
|
+
let(:raw_node) { Rambling::Trie::RawNode.new }
|
76
|
+
let(:compressor) { Rambling::Trie::Compressor.new }
|
77
|
+
let(:node) { compressor.compress raw_node }
|
78
|
+
|
79
|
+
context 'when the chars array is empty' do
|
80
|
+
context 'when the node is terminal' do
|
81
|
+
before do
|
82
|
+
node.terminal!
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns true' do
|
86
|
+
expect(node.word? []).to be true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the node is not terminal' do
|
91
|
+
it 'returns false' do
|
92
|
+
expect(node.word? []).to be false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when the chars array is not empty' do
|
98
|
+
context 'when the node has a tree that matches all the characters' do
|
99
|
+
before do
|
100
|
+
raw_node.add 'abc'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns true' do
|
104
|
+
expect(node.word? %w(a b c)).to be true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when the node has a tree that does not match all the characters' do
|
109
|
+
before do
|
110
|
+
raw_node.add 'abc'
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'returns false' do
|
114
|
+
expect(node.word? %w(a)).to be false
|
115
|
+
expect(node.word? %w(a b)).to be false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#scan' do
|
122
|
+
let(:raw_node) { Rambling::Trie::RawNode.new }
|
123
|
+
let(:compressor) { Rambling::Trie::Compressor.new }
|
124
|
+
let(:node) { compressor.compress raw_node }
|
125
|
+
|
126
|
+
context 'when the chars array is empty' do
|
127
|
+
it 'returns itself' do
|
128
|
+
expect(node.scan []).to eq node
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when the chars array is not empty' do
|
133
|
+
before do
|
134
|
+
raw_node.add 'cba'
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'when the chars are found' do
|
138
|
+
it 'returns the found child' do
|
139
|
+
expect(node.scan %w(c)).to eq node[:cba]
|
140
|
+
expect(node.scan %w(c b)).to eq node[:cba]
|
141
|
+
expect(node.scan %w(c b a)).to eq node[:cba]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when the chars are not found' do
|
146
|
+
it 'returns a MissingNode' do
|
147
|
+
expect(node.scan %w(a)).to be_a Rambling::Trie::MissingNode
|
148
|
+
expect(node.scan %w(a b)).to be_a Rambling::Trie::MissingNode
|
149
|
+
expect(node.scan %w(a b c)).to be_a Rambling::Trie::MissingNode
|
150
|
+
expect(node.scan %w(c b a d)).to be_a Rambling::Trie::MissingNode
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
35
155
|
end
|
@@ -152,12 +152,22 @@ describe Rambling::Trie::Container do
|
|
152
152
|
describe 'delegates and aliases' do
|
153
153
|
before do
|
154
154
|
allow(root).to receive_messages(
|
155
|
-
|
156
|
-
partial_word?: nil,
|
157
|
-
scan: nil,
|
155
|
+
:[] => nil,
|
158
156
|
add: nil,
|
157
|
+
as_word: nil,
|
158
|
+
children: nil,
|
159
|
+
children_tree: nil,
|
160
|
+
compressed?: nil,
|
159
161
|
each: nil,
|
160
|
-
|
162
|
+
has_key?: nil,
|
163
|
+
inspect: nil,
|
164
|
+
letter: nil,
|
165
|
+
parent: nil,
|
166
|
+
partial_word?: nil,
|
167
|
+
scan: nil,
|
168
|
+
size: nil,
|
169
|
+
to_s: nil,
|
170
|
+
word?: nil,
|
161
171
|
)
|
162
172
|
end
|
163
173
|
|
@@ -181,15 +191,65 @@ describe Rambling::Trie::Container do
|
|
181
191
|
expect(root).to have_received(:add).with 'words'
|
182
192
|
end
|
183
193
|
|
184
|
-
it 'delegates `#
|
185
|
-
container.
|
186
|
-
expect(root).to have_received :
|
194
|
+
it 'delegates `#[]` to the root node' do
|
195
|
+
container.[]
|
196
|
+
expect(root).to have_received :[]
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'delegates `#as_word` to the root node' do
|
200
|
+
container.as_word
|
201
|
+
expect(root).to have_received :as_word
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'delegates `#children` to the root node' do
|
205
|
+
container.children
|
206
|
+
expect(root).to have_received :children
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'delegates `#children_tree` to the root node' do
|
210
|
+
container.children_tree
|
211
|
+
expect(root).to have_received :children_tree
|
187
212
|
end
|
188
213
|
|
189
214
|
it 'delegates `#compressed?` to the root node' do
|
190
215
|
container.compressed?
|
191
216
|
expect(root).to have_received :compressed?
|
192
217
|
end
|
218
|
+
|
219
|
+
it 'delegates `#each` to the root node' do
|
220
|
+
container.each
|
221
|
+
expect(root).to have_received :each
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'delegates `#has_key?` to the root node' do
|
225
|
+
container.has_key?
|
226
|
+
expect(root).to have_received :has_key?
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'delegates `#inspect` to the root node' do
|
230
|
+
container.inspect
|
231
|
+
expect(root).to have_received :inspect
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'delegates `#letter` to the root node' do
|
235
|
+
container.letter
|
236
|
+
expect(root).to have_received :letter
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'delegates `#parent` to the root node' do
|
240
|
+
container.parent
|
241
|
+
expect(root).to have_received :parent
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'delegates `#size` to the root node' do
|
245
|
+
container.size
|
246
|
+
expect(root).to have_received :size
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'delegates `#to_s` to the root node' do
|
250
|
+
container.to_s
|
251
|
+
expect(root).to have_received :to_s
|
252
|
+
end
|
193
253
|
end
|
194
254
|
|
195
255
|
describe '#compress!' do
|
@@ -316,6 +316,37 @@ describe Rambling::Trie::RawNode do
|
|
316
316
|
end
|
317
317
|
end
|
318
318
|
|
319
|
+
describe '#scan' do
|
320
|
+
context 'when the chars array is empty' do
|
321
|
+
it 'returns itself' do
|
322
|
+
expect(node.scan []).to eq node
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context 'when the chars array is not empty' do
|
327
|
+
before do
|
328
|
+
node.add 'cba'
|
329
|
+
end
|
330
|
+
|
331
|
+
context 'when the chars are found' do
|
332
|
+
it 'returns the found child' do
|
333
|
+
expect(node.scan %w(c)).to eq node[:c]
|
334
|
+
expect(node.scan %w(c b)).to eq node[:c][:b]
|
335
|
+
expect(node.scan %w(c b a)).to eq node[:c][:b][:a]
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context 'when the chars are not found' do
|
340
|
+
it 'returns a MissingNode' do
|
341
|
+
expect(node.scan %w(a)).to be_a Rambling::Trie::MissingNode
|
342
|
+
expect(node.scan %w(a b)).to be_a Rambling::Trie::MissingNode
|
343
|
+
expect(node.scan %w(a b c)).to be_a Rambling::Trie::MissingNode
|
344
|
+
expect(node.scan %w(c b a d)).to be_a Rambling::Trie::MissingNode
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
319
350
|
describe '#as_word' do
|
320
351
|
let(:node) { Rambling::Trie::RawNode.new }
|
321
352
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rambling-trie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edgar Gonzalez
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- reports/0.8.1/benchmark
|
174
174
|
- reports/0.9.0/benchmark
|
175
175
|
- reports/0.9.1/benchmark
|
176
|
+
- reports/0.9.2/benchmark
|
176
177
|
- spec/assets/test_words.txt
|
177
178
|
- spec/integration/rambling/trie_spec.rb
|
178
179
|
- spec/lib/rambling/trie/compressed_node_spec.rb
|
@@ -205,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
206
|
version: '0'
|
206
207
|
requirements: []
|
207
208
|
rubyforge_project:
|
208
|
-
rubygems_version: 2.
|
209
|
+
rubygems_version: 2.6.8
|
209
210
|
signing_key:
|
210
211
|
specification_version: 4
|
211
212
|
summary: A custom implementation of the trie data structure.
|