radix_tree 1.0.0.dev.2 → 1.0.0
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/lib/radix_tree.rb +81 -10
- data/test/helper.rb +5 -2
- data/test/test_radix_tree.rb +53 -0
- metadata +11 -5
data/lib/radix_tree.rb
CHANGED
@@ -4,6 +4,20 @@
|
|
4
4
|
# 25 times slower for 10 bytes key, 100000 elements insertion
|
5
5
|
# 10 times slower for 10 bytes key, 100000 elements retrieval
|
6
6
|
#
|
7
|
+
# TODO: Implement following methods for Hash compatibility.
|
8
|
+
# * delete_if
|
9
|
+
# * reject
|
10
|
+
# * reject!
|
11
|
+
# * fetch
|
12
|
+
# * values_at
|
13
|
+
# * replace
|
14
|
+
# * key
|
15
|
+
# * shift
|
16
|
+
# * has_value?/value?
|
17
|
+
# * ==
|
18
|
+
# * eql?
|
19
|
+
# * hash
|
20
|
+
#
|
7
21
|
# TODO: Implement following features for utilizing strength of Radix Tree.
|
8
22
|
# * find predecessor
|
9
23
|
# * find successor
|
@@ -28,7 +42,7 @@ class RadixTree
|
|
28
42
|
end
|
29
43
|
|
30
44
|
def empty?
|
31
|
-
|
45
|
+
!@children and undefined?
|
32
46
|
end
|
33
47
|
|
34
48
|
def size
|
@@ -101,14 +115,7 @@ class RadixTree
|
|
101
115
|
if child = find_child(key)
|
102
116
|
value = child.delete(key)
|
103
117
|
if value and child.undefined?
|
104
|
-
|
105
|
-
delete_child(child)
|
106
|
-
elsif child.children.size == 1
|
107
|
-
# pull up the grand child as a child
|
108
|
-
delete_child(child)
|
109
|
-
grand = child.children.values.first
|
110
|
-
add_child(Node.new(child.key + grand.key, grand.value, grand.children))
|
111
|
-
end
|
118
|
+
reap(child)
|
112
119
|
end
|
113
120
|
value
|
114
121
|
end
|
@@ -156,6 +163,17 @@ class RadixTree
|
|
156
163
|
add_child(child)
|
157
164
|
end
|
158
165
|
|
166
|
+
def reap(child)
|
167
|
+
if !child.children
|
168
|
+
delete_child(child)
|
169
|
+
elsif child.children.size == 1
|
170
|
+
# pull up the grand child as a child
|
171
|
+
delete_child(child)
|
172
|
+
grand = child.children.values.first
|
173
|
+
add_child(Node.new(child.key + grand.key, grand.value, grand.children))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
159
177
|
def child_key(key)
|
160
178
|
key[head_match_length(key)..-1]
|
161
179
|
end
|
@@ -190,6 +208,9 @@ class RadixTree
|
|
190
208
|
end
|
191
209
|
|
192
210
|
DEFAULT = Object.new
|
211
|
+
|
212
|
+
attr_accessor :default
|
213
|
+
attr_reader :default_proc
|
193
214
|
|
194
215
|
def initialize(default = DEFAULT, &block)
|
195
216
|
if block && default != DEFAULT
|
@@ -207,9 +228,50 @@ class RadixTree
|
|
207
228
|
def size
|
208
229
|
@root.size
|
209
230
|
end
|
231
|
+
alias length size
|
210
232
|
|
211
233
|
def each(&block)
|
212
|
-
|
234
|
+
if block_given?
|
235
|
+
@root.each('', &block)
|
236
|
+
self
|
237
|
+
else
|
238
|
+
Enumerator.new { |yielder|
|
239
|
+
@root.each('') do |k, v|
|
240
|
+
yielder << [k, v]
|
241
|
+
end
|
242
|
+
}
|
243
|
+
end
|
244
|
+
end
|
245
|
+
alias each_pair each
|
246
|
+
|
247
|
+
def each_key
|
248
|
+
if block_given?
|
249
|
+
@root.each('') do |k, v|
|
250
|
+
yield k
|
251
|
+
end
|
252
|
+
self
|
253
|
+
else
|
254
|
+
Enumerator.new { |yielder|
|
255
|
+
@root.each('') do |k, v|
|
256
|
+
yielder << k
|
257
|
+
end
|
258
|
+
}
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def each_value
|
263
|
+
if block_given?
|
264
|
+
@root.each('') do |k, v|
|
265
|
+
yield v
|
266
|
+
end
|
267
|
+
self
|
268
|
+
else
|
269
|
+
Enumerator.new { |yielder|
|
270
|
+
@root.each('') do |k, v|
|
271
|
+
yielder << v
|
272
|
+
end
|
273
|
+
}
|
274
|
+
end
|
213
275
|
end
|
214
276
|
|
215
277
|
def keys
|
@@ -220,9 +282,14 @@ class RadixTree
|
|
220
282
|
@root.values('')
|
221
283
|
end
|
222
284
|
|
285
|
+
def clear
|
286
|
+
@root = Node.new('')
|
287
|
+
end
|
288
|
+
|
223
289
|
def []=(key, value)
|
224
290
|
@root.store(key.to_s, value)
|
225
291
|
end
|
292
|
+
alias store []=
|
226
293
|
|
227
294
|
def key?(key)
|
228
295
|
@root.retrieve(key.to_s) != Node::UNDEFINED
|
@@ -252,4 +319,8 @@ class RadixTree
|
|
252
319
|
@root.dump_tree(io)
|
253
320
|
io
|
254
321
|
end
|
322
|
+
|
323
|
+
def to_hash
|
324
|
+
inject({}) { |r, (k, v)| r[k] = v; r }
|
325
|
+
end
|
255
326
|
end
|
data/test/helper.rb
CHANGED
data/test/test_radix_tree.rb
CHANGED
@@ -181,6 +181,8 @@ class TestRadixTree < Test::Unit::TestCase
|
|
181
181
|
s.each do |k, v|
|
182
182
|
h[k] = v
|
183
183
|
end
|
184
|
+
assert_equal s.to_a.sort_by { |k, v| k }, h.each.sort_by { |k, v| k }
|
185
|
+
#
|
184
186
|
values = []
|
185
187
|
h.each do |k, v|
|
186
188
|
values << [k, v]
|
@@ -188,6 +190,36 @@ class TestRadixTree < Test::Unit::TestCase
|
|
188
190
|
assert_equal s.to_a.sort_by { |k, v| k }, values.sort_by { |k, v| k }
|
189
191
|
end
|
190
192
|
|
193
|
+
def test_each_key
|
194
|
+
h = RadixTree.new
|
195
|
+
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
196
|
+
s.each do |k, v|
|
197
|
+
h[k] = v
|
198
|
+
end
|
199
|
+
assert_equal s.keys.sort, h.each_key.sort
|
200
|
+
#
|
201
|
+
values = []
|
202
|
+
h.each_key do |k|
|
203
|
+
values << k
|
204
|
+
end
|
205
|
+
assert_equal s.keys.sort, values.sort
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_each_value
|
209
|
+
h = RadixTree.new
|
210
|
+
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6, 'azzzzz' => 6 }
|
211
|
+
s.each do |k, v|
|
212
|
+
h[k] = v
|
213
|
+
end
|
214
|
+
assert_equal s.values.sort, h.each_value.sort
|
215
|
+
#
|
216
|
+
values = []
|
217
|
+
h.each_value do |v|
|
218
|
+
values << v
|
219
|
+
end
|
220
|
+
assert_equal s.values.sort, values.sort
|
221
|
+
end
|
222
|
+
|
191
223
|
def test_keys
|
192
224
|
h = RadixTree.new
|
193
225
|
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
@@ -239,6 +271,27 @@ class TestRadixTree < Test::Unit::TestCase
|
|
239
271
|
assert h['baz'].object_id != h['qux'].object_id
|
240
272
|
end
|
241
273
|
|
274
|
+
def test_to_hash
|
275
|
+
h = RadixTree.new
|
276
|
+
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
277
|
+
s.each do |k, v|
|
278
|
+
h[k] = v
|
279
|
+
end
|
280
|
+
assert_equal s, h.to_hash
|
281
|
+
end
|
282
|
+
|
283
|
+
def test_clear
|
284
|
+
h = RadixTree.new
|
285
|
+
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
286
|
+
s.each do |k, v|
|
287
|
+
h[k] = v
|
288
|
+
end
|
289
|
+
assert_equal s, h.to_hash
|
290
|
+
h.clear
|
291
|
+
assert_equal 0, h.size
|
292
|
+
assert h.to_hash.empty?
|
293
|
+
end
|
294
|
+
|
242
295
|
if RUBY_VERSION >= '1.9.0'
|
243
296
|
def test_encoding
|
244
297
|
h = RadixTree.new
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radix_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Hiroshi Nakamura
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: nahi@ruby-lang.org
|
@@ -33,12 +33,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
33
33
|
- - ! '>='
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: '0'
|
36
|
+
segments:
|
37
|
+
- 0
|
38
|
+
hash: -966188071225850011
|
36
39
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
40
|
none: false
|
38
41
|
requirements:
|
39
|
-
- - ! '
|
42
|
+
- - ! '>='
|
40
43
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
44
|
+
version: '0'
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
hash: -966188071225850011
|
42
48
|
requirements: []
|
43
49
|
rubyforge_project:
|
44
50
|
rubygems_version: 1.8.11
|