radix_tree 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1 -0
- data/lib/radix_tree.rb +216 -14
- data/test/test_radix_tree.rb +235 -35
- metadata +4 -9
data/README
CHANGED
data/lib/radix_tree.rb
CHANGED
@@ -5,23 +5,9 @@
|
|
5
5
|
# 10 times slower for 10 bytes key, 100000 elements retrieval
|
6
6
|
#
|
7
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
8
|
# * hash
|
20
9
|
#
|
21
10
|
# TODO: Implement following features for utilizing strength of Radix Tree.
|
22
|
-
# * find predecessor
|
23
|
-
# * find successor
|
24
|
-
# * find_all by start string
|
25
11
|
# * delete_all by start string
|
26
12
|
#
|
27
13
|
class RadixTree
|
@@ -155,6 +141,80 @@ class RadixTree
|
|
155
141
|
end
|
156
142
|
end
|
157
143
|
|
144
|
+
def dup
|
145
|
+
if @children
|
146
|
+
children_dup = Hash.new
|
147
|
+
@children.each do |k,v|
|
148
|
+
children_dup[k] = v.dup
|
149
|
+
end
|
150
|
+
else
|
151
|
+
children_dup = nil
|
152
|
+
end
|
153
|
+
Node.new(@key, @index, @value, children_dup)
|
154
|
+
end
|
155
|
+
alias clone dup
|
156
|
+
|
157
|
+
def find_pre(key, head, p_key)
|
158
|
+
if same_key?(key)
|
159
|
+
(p_key == "" ? nil : p_key)
|
160
|
+
else
|
161
|
+
if @children
|
162
|
+
pos = head_match_size(key, head)
|
163
|
+
if child = find_child(key[pos])
|
164
|
+
return child.find_pre(key, @index, self.label)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def find_suc(key, head, flag)
|
172
|
+
# check before the key or after
|
173
|
+
flag = true if !flag && same_key?(key)
|
174
|
+
if flag
|
175
|
+
# after tje key and omit undefined value
|
176
|
+
if undefined? || self.label == key
|
177
|
+
# if undefined keep going
|
178
|
+
if @children
|
179
|
+
# next by lexicographic order
|
180
|
+
k = @children.keys.sort.shift
|
181
|
+
return @children[k].find_suc(key, nil, flag)
|
182
|
+
end
|
183
|
+
nil
|
184
|
+
else
|
185
|
+
return self.label
|
186
|
+
end
|
187
|
+
else
|
188
|
+
# before the key
|
189
|
+
if @children
|
190
|
+
pos = head_match_size(key, head)
|
191
|
+
if child = find_child(key[pos])
|
192
|
+
return child.find_suc(key, @index, flag)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
nil
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def find_all(prefix, head, flag)
|
200
|
+
flag = true if !flag && same_key?(prefix)
|
201
|
+
if flag
|
202
|
+
strs = []
|
203
|
+
self.each do |l,v|
|
204
|
+
strs << l if v != UNDEFINED
|
205
|
+
end
|
206
|
+
return strs
|
207
|
+
else
|
208
|
+
if @children
|
209
|
+
pos = head_match_size(prefix, head)
|
210
|
+
if child = find_child(prefix[pos])
|
211
|
+
return child.find_all(prefix, @index, flag)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
158
218
|
private
|
159
219
|
|
160
220
|
def same_key?(key)
|
@@ -325,4 +385,146 @@ class RadixTree
|
|
325
385
|
def to_hash
|
326
386
|
inject({}) { |r, (k, v)| r[k] = v; r }
|
327
387
|
end
|
388
|
+
|
389
|
+
def delete_if(&block)
|
390
|
+
if block_given?
|
391
|
+
temp = []
|
392
|
+
@root.each do |key, value|
|
393
|
+
if block.call key, value
|
394
|
+
temp << key
|
395
|
+
end
|
396
|
+
end
|
397
|
+
temp.each do |k|
|
398
|
+
@root.delete(k, 0)
|
399
|
+
end
|
400
|
+
self
|
401
|
+
else
|
402
|
+
Enumerator.new(@root)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
def dup
|
407
|
+
if @default != DEFAULT then
|
408
|
+
rt = RadixTree.new(@default)
|
409
|
+
elsif @default_proc then
|
410
|
+
rt = RadixTree.new(@default_proc.to_proc)
|
411
|
+
else
|
412
|
+
rt = RadixTree.new
|
413
|
+
end
|
414
|
+
rt.root = @root.dup
|
415
|
+
rt
|
416
|
+
end
|
417
|
+
alias clone dup
|
418
|
+
|
419
|
+
def reject(&block)
|
420
|
+
if block_given?
|
421
|
+
self.dup.delete_if(&block)
|
422
|
+
else
|
423
|
+
Enumerator.new(@root)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def reject!(&block)
|
428
|
+
if block_given?
|
429
|
+
temp = []
|
430
|
+
@root.each do |key, value|
|
431
|
+
if block.call key, value
|
432
|
+
temp << key
|
433
|
+
end
|
434
|
+
end
|
435
|
+
if temp.empty?
|
436
|
+
nil
|
437
|
+
else
|
438
|
+
temp.each do |k|
|
439
|
+
@root.delete(k, 0)
|
440
|
+
end
|
441
|
+
self
|
442
|
+
end
|
443
|
+
else
|
444
|
+
Enumerator.new(@root)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
def fetch(key, *args, &block)
|
449
|
+
if args.size > 0 && block
|
450
|
+
raise ArgumentError, 'wrong number of arguments'
|
451
|
+
elsif self[key]
|
452
|
+
self[key]
|
453
|
+
elsif args.size == 1
|
454
|
+
args[0]
|
455
|
+
elsif block
|
456
|
+
block.call key
|
457
|
+
else
|
458
|
+
raise KeyError, 'can\'t find the key'
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
def values_at(*args)
|
463
|
+
vs = []
|
464
|
+
args.each do |a|
|
465
|
+
vs << self[a]
|
466
|
+
end
|
467
|
+
vs
|
468
|
+
end
|
469
|
+
|
470
|
+
def replace(h)
|
471
|
+
self.clear
|
472
|
+
h.each do |k,v|
|
473
|
+
self[k] = v
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def key(value)
|
478
|
+
self.each do |k,v|
|
479
|
+
return k if v == value
|
480
|
+
nil
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
def shift
|
485
|
+
self.each do |k,v|
|
486
|
+
self.delete(k)
|
487
|
+
return [k, v]
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
def has_value?(value)
|
492
|
+
self.each do |k,v|
|
493
|
+
return true if value == v
|
494
|
+
end
|
495
|
+
false
|
496
|
+
end
|
497
|
+
alias value? has_value?
|
498
|
+
|
499
|
+
def ==(oh)
|
500
|
+
return false if self.size != oh.size
|
501
|
+
self.each_key do |k|
|
502
|
+
return false if self[k] != oh[k]
|
503
|
+
end
|
504
|
+
true
|
505
|
+
end
|
506
|
+
|
507
|
+
def eql?(oh)
|
508
|
+
return false if self.size != oh.size
|
509
|
+
self.each_key do |k|
|
510
|
+
return false unless self[k].eql?(oh[k])
|
511
|
+
end
|
512
|
+
true
|
513
|
+
end
|
514
|
+
|
515
|
+
def find_predecessor(key)
|
516
|
+
@root.find_pre(key, 0, nil)
|
517
|
+
end
|
518
|
+
|
519
|
+
def find_successor(key)
|
520
|
+
@root.find_suc(key, 0, false)
|
521
|
+
end
|
522
|
+
|
523
|
+
def find_all(prefix)
|
524
|
+
@root.find_all(prefix, 0, false)
|
525
|
+
end
|
526
|
+
|
527
|
+
protected
|
528
|
+
attr_accessor :root
|
529
|
+
|
328
530
|
end
|
data/test/test_radix_tree.rb
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
require File.expand_path('./helper', File.dirname(__FILE__))
|
3
3
|
|
4
4
|
class TestRadixTree < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
# rt for RadixTree
|
7
|
+
# ip for input
|
8
|
+
@rt = RadixTree.new
|
9
|
+
@ip = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
10
|
+
@ip.each do |k, v|
|
11
|
+
@rt[k] = v
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
def test_aref_nil
|
6
16
|
h = RadixTree.new
|
7
17
|
h['abc'] = 1
|
@@ -176,26 +186,18 @@ class TestRadixTree < Test::Unit::TestCase
|
|
176
186
|
end
|
177
187
|
|
178
188
|
def test_each
|
179
|
-
h =
|
180
|
-
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
181
|
-
s.each do |k, v|
|
182
|
-
h[k] = v
|
183
|
-
end
|
189
|
+
h, s = @rt, @ip
|
184
190
|
assert_equal s.to_a.sort_by { |k, v| k }, h.each.sort_by { |k, v| k }
|
185
191
|
#
|
186
192
|
values = []
|
187
193
|
h.each do |k, v|
|
188
194
|
values << [k, v]
|
189
195
|
end
|
190
|
-
assert_equal
|
196
|
+
assert_equal h.to_a.sort_by { |k, v| k }, values.sort_by { |k, v| k }
|
191
197
|
end
|
192
198
|
|
193
199
|
def test_each_key
|
194
|
-
h =
|
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
|
200
|
+
h, s = @rt, @ip
|
199
201
|
assert_equal s.keys.sort, h.each_key.sort
|
200
202
|
#
|
201
203
|
values = []
|
@@ -206,35 +208,23 @@ class TestRadixTree < Test::Unit::TestCase
|
|
206
208
|
end
|
207
209
|
|
208
210
|
def test_each_value
|
209
|
-
h =
|
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
|
211
|
+
h, s = @rt, @ip
|
214
212
|
assert_equal s.values.sort, h.each_value.sort
|
215
213
|
#
|
216
214
|
values = []
|
217
215
|
h.each_value do |v|
|
218
216
|
values << v
|
219
217
|
end
|
220
|
-
assert_equal
|
218
|
+
assert_equal h.values.sort, values.sort
|
221
219
|
end
|
222
220
|
|
223
221
|
def test_keys
|
224
|
-
h =
|
225
|
-
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
226
|
-
s.each do |k, v|
|
227
|
-
h[k] = v
|
228
|
-
end
|
222
|
+
h, s = @rt, @ip
|
229
223
|
assert_equal s.keys.sort, h.keys.sort
|
230
224
|
end
|
231
225
|
|
232
226
|
def test_values
|
233
|
-
h =
|
234
|
-
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3, 'bc' => 4, 'a' => 5, 'abc' => 6 }
|
235
|
-
s.each do |k, v|
|
236
|
-
h[k] = v
|
237
|
-
end
|
227
|
+
h, s = @rt, @ip
|
238
228
|
assert_equal s.values.sort, h.values.sort
|
239
229
|
end
|
240
230
|
|
@@ -272,24 +262,234 @@ class TestRadixTree < Test::Unit::TestCase
|
|
272
262
|
end
|
273
263
|
|
274
264
|
def test_to_hash
|
265
|
+
h, s = @rt, @ip
|
266
|
+
assert_equal s, h.to_hash
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_clear
|
270
|
+
assert_equal @ip, @rt.to_hash
|
271
|
+
@rt.clear
|
272
|
+
assert_equal 0, @rt.size
|
273
|
+
assert @rt.to_hash.empty?
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_delete_if
|
277
|
+
h, s = @rt, @ip
|
278
|
+
assert_equal 6, h.size
|
279
|
+
h.delete_if do |k,v|
|
280
|
+
v > 3
|
281
|
+
end
|
282
|
+
assert_equal 3, h.size
|
283
|
+
assert_equal 1, h['aa']
|
284
|
+
assert_equal 2, h['ab']
|
285
|
+
assert_equal 3, h['bb']
|
286
|
+
assert_equal nil, h['bc']
|
287
|
+
assert_equal nil, h['a']
|
288
|
+
assert_equal nil, h['abc']
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_dup
|
275
292
|
h = RadixTree.new
|
276
|
-
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3
|
293
|
+
s = { 'aa' => 1, 'ab' => 2, 'bb' => 3 }
|
277
294
|
s.each do |k, v|
|
278
295
|
h[k] = v
|
279
296
|
end
|
280
|
-
assert_equal
|
297
|
+
assert_equal 3, h.size
|
298
|
+
assert_equal 1, h['aa']
|
299
|
+
assert_equal 2, h['ab']
|
300
|
+
assert_equal 3, h['bb']
|
301
|
+
h2 = h.dup
|
302
|
+
h2['aa'] = 4
|
303
|
+
h2['a'] = 5
|
304
|
+
|
305
|
+
assert_equal 3, h.size
|
306
|
+
assert_equal 1, h['aa']
|
307
|
+
assert_equal 2, h['ab']
|
308
|
+
assert_equal 3, h['bb']
|
309
|
+
assert_equal 4, h2.size
|
310
|
+
assert_equal 4, h2['aa']
|
311
|
+
assert_equal 2, h2['ab']
|
312
|
+
assert_equal 3, h2['bb']
|
313
|
+
assert_equal 5, h2['a']
|
281
314
|
end
|
282
315
|
|
283
|
-
def
|
316
|
+
def test_reject
|
317
|
+
h, s = @rt, @ip
|
318
|
+
h2 = h.reject do |k,v|
|
319
|
+
v > 3
|
320
|
+
end
|
321
|
+
assert_equal 6, h.size
|
322
|
+
assert_equal 1, h['aa']
|
323
|
+
assert_equal 2, h['ab']
|
324
|
+
assert_equal 3, h['bb']
|
325
|
+
assert_equal 4, h['bc']
|
326
|
+
assert_equal 5, h['a']
|
327
|
+
assert_equal 6, h['abc']
|
328
|
+
|
329
|
+
assert_equal 3, h2.size
|
330
|
+
assert_equal 1, h2['aa']
|
331
|
+
assert_equal 2, h2['ab']
|
332
|
+
assert_equal 3, h2['bb']
|
333
|
+
assert_equal nil, h2['bc']
|
334
|
+
assert_equal nil, h2['a']
|
335
|
+
assert_equal nil, h2['abc']
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_reject!
|
339
|
+
h, s = @rt, @ip
|
340
|
+
h2 = h.reject! do |k,v|
|
341
|
+
v > 8
|
342
|
+
end
|
343
|
+
assert_equal 6, h.size
|
344
|
+
assert_equal 1, h['aa']
|
345
|
+
assert_equal 2, h['ab']
|
346
|
+
assert_equal 3, h['bb']
|
347
|
+
assert_equal 4, h['bc']
|
348
|
+
assert_equal 5, h['a']
|
349
|
+
assert_equal 6, h['abc']
|
350
|
+
|
351
|
+
assert_equal nil, h2
|
352
|
+
end
|
353
|
+
|
354
|
+
def fetch!
|
284
355
|
h = RadixTree.new
|
285
|
-
s = { 'aa' => 1, 'ab' => 2
|
356
|
+
s = { 'aa' => 1, 'ab' => 2 }
|
286
357
|
s.each do |k, v|
|
287
358
|
h[k] = v
|
288
359
|
end
|
289
|
-
assert_equal
|
290
|
-
h.
|
291
|
-
assert_equal
|
292
|
-
|
360
|
+
assert_equal 1, h.fetch('aa')
|
361
|
+
assert_equal 'df value', h.fetch('aac', 'df value')
|
362
|
+
assert_equal "aac:df value from block", h.fetch('aac') {|k| "#{k}:df value from block" }
|
363
|
+
end
|
364
|
+
|
365
|
+
def test_values_at
|
366
|
+
h, s = @rt, @ip
|
367
|
+
ks = s.keys.shuffle[0..2]
|
368
|
+
vs = h.values_at(*ks)
|
369
|
+
for i in (0..(ks.size)) do
|
370
|
+
assert_equal vs[i], h[ks[i]]
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
def test_replace
|
375
|
+
h = RadixTree.new
|
376
|
+
s = { 'aa' => 1, 'ab' => 2 }
|
377
|
+
s2 = { 'bz' => 3, 'kk' => 4 }
|
378
|
+
s.each do |k, v|
|
379
|
+
h[k] = v
|
380
|
+
end
|
381
|
+
assert_equal 1, h['aa']
|
382
|
+
assert_equal 2, h['ab']
|
383
|
+
h.replace(s2)
|
384
|
+
assert_equal 3, h['bz']
|
385
|
+
assert_equal 4, h['kk']
|
386
|
+
end
|
387
|
+
|
388
|
+
def test_key
|
389
|
+
h, s = @rt, @ip
|
390
|
+
assert_equal 'aa', h.key(1)
|
391
|
+
assert_equal 'bb', h.key(3)
|
392
|
+
assert_equal 'bc', h.key(4)
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_shift
|
396
|
+
h, s = @rt, @ip
|
397
|
+
k, v = h.shift
|
398
|
+
assert_equal 'a', k
|
399
|
+
assert_equal 5, v
|
400
|
+
assert_equal 1, h['aa']
|
401
|
+
assert_equal 2, h['ab']
|
402
|
+
assert_equal 3, h['bb']
|
403
|
+
assert_equal 4, h['bc']
|
404
|
+
assert_equal 6, h['abc']
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_has_value?
|
408
|
+
h, s = @rt, @ip
|
409
|
+
assert_equal true, h.has_value?(3)
|
410
|
+
assert_equal true, h.has_value?(4)
|
411
|
+
assert_equal true, h.value?(5)
|
412
|
+
assert_equal true, h.value?(6)
|
413
|
+
assert_equal false, h.has_value?(7)
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_=
|
417
|
+
h, s = @rt, @ip
|
418
|
+
h2 = RadixTree.new
|
419
|
+
s.each do |k, v|
|
420
|
+
h2[k] = v
|
421
|
+
end
|
422
|
+
assert_equal true, (h==h2)
|
423
|
+
tk, tv= h2.shift
|
424
|
+
assert_equal false, (h==h2)
|
425
|
+
h2[tk] = tv+3
|
426
|
+
assert_equal false, (h==h2)
|
427
|
+
end
|
428
|
+
|
429
|
+
def test_eql?
|
430
|
+
h, s = @rt, @ip
|
431
|
+
h2 = RadixTree.new
|
432
|
+
s.each do |k, v|
|
433
|
+
h2[k] = v
|
434
|
+
end
|
435
|
+
assert_equal true, (h.eql?(h2))
|
436
|
+
tk, tv= h2.shift
|
437
|
+
assert_equal false, (h.eql?(h2))
|
438
|
+
h2[tk] = tv.to_s
|
439
|
+
assert_equal false, (h.eql?(h2))
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_find_predecessor
|
443
|
+
h, s = @rt, @ip
|
444
|
+
assert_equal nil, h.find_predecessor('a')
|
445
|
+
assert_equal nil, h.find_predecessor('b')
|
446
|
+
assert_equal 'a', h.find_predecessor('aa')
|
447
|
+
assert_equal 'a', h.find_predecessor('ab')
|
448
|
+
assert_equal 'ab', h.find_predecessor('abc')
|
449
|
+
assert_equal 'b', h.find_predecessor('bb')
|
450
|
+
assert_equal 'b', h.find_predecessor('bc')
|
451
|
+
end
|
452
|
+
|
453
|
+
def test_find_successor
|
454
|
+
h, s = @rt, @ip
|
455
|
+
h['cde'] = 7
|
456
|
+
h['cdf'] = 8
|
457
|
+
h['cf'] = 9
|
458
|
+
h['c'] = 10
|
459
|
+
assert_equal 'aa', h.find_successor('a')
|
460
|
+
assert_equal nil, h.find_successor('aa')
|
461
|
+
assert_equal 'abc', h.find_successor('ab')
|
462
|
+
assert_equal nil, h.find_successor('abc')
|
463
|
+
assert_equal 'bb', h.find_successor('b')
|
464
|
+
assert_equal nil, h.find_successor('bb')
|
465
|
+
assert_equal nil, h.find_successor('bc')
|
466
|
+
assert_equal 'cde', h.find_successor('c')
|
467
|
+
assert_equal 'cde', h.find_successor('cd')
|
468
|
+
assert_equal nil, h.find_successor('cde')
|
469
|
+
assert_equal nil, h.find_successor('cdf')
|
470
|
+
assert_equal nil, h.find_successor('cf')
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_find_all
|
474
|
+
h, s = @rt, @ip
|
475
|
+
h['cde'] = 7
|
476
|
+
h['cdf'] = 8
|
477
|
+
h['cf'] = 9
|
478
|
+
h['c'] = 10
|
479
|
+
assert_equal ['ab', 'abc'].sort, h.find_all('ab').sort
|
480
|
+
assert_equal ['a', 'aa', 'ab', 'abc'].sort, h.find_all('a').sort
|
481
|
+
assert_equal ['aa'], h.find_all('aa')
|
482
|
+
assert_equal ['abc'], h.find_all('abc')
|
483
|
+
|
484
|
+
assert_equal ['bb', 'bc'].sort, h.find_all('b').sort
|
485
|
+
assert_equal ['bb'], h.find_all('bb')
|
486
|
+
assert_equal ['bc'], h.find_all('bc')
|
487
|
+
|
488
|
+
assert_equal ['c', 'cde', 'cdf', 'cf'].sort, h.find_all('c').sort
|
489
|
+
assert_equal ['cde', 'cdf'].sort, h.find_all('cd').sort
|
490
|
+
assert_equal ['cde'], h.find_all('cde')
|
491
|
+
assert_equal ['cdf'], h.find_all('cdf')
|
492
|
+
assert_equal ['cf'], h.find_all('cf')
|
293
493
|
end
|
294
494
|
|
295
495
|
if RUBY_VERSION >= '1.9.0'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radix_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-29 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email: nahi@ruby-lang.org
|
@@ -33,22 +33,17 @@ 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: 2336052632168712106
|
39
36
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
37
|
none: false
|
41
38
|
requirements:
|
42
39
|
- - ! '>='
|
43
40
|
- !ruby/object:Gem::Version
|
44
41
|
version: '0'
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
hash: 2336052632168712106
|
48
42
|
requirements: []
|
49
43
|
rubyforge_project:
|
50
|
-
rubygems_version: 1.8.
|
44
|
+
rubygems_version: 1.8.23
|
51
45
|
signing_key:
|
52
46
|
specification_version: 3
|
53
47
|
summary: Naive implementation of Radix Tree for Ruby
|
54
48
|
test_files: []
|
49
|
+
has_rdoc:
|