rambling-trie 0.4.2 → 0.5.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/.gitignore +6 -0
- data/.rspec +0 -0
- data/.travis.yml +0 -0
- data/Gemfile +2 -0
- data/Guardfile +1 -1
- data/LICENSE +0 -0
- data/README.markdown +36 -13
- data/Rakefile +0 -0
- data/assets/dictionaries/words_with_friends.txt +0 -0
- data/lib/rambling-trie.rb +0 -0
- data/lib/rambling/trie.rb +14 -19
- data/lib/rambling/trie/branches.rb +14 -21
- data/lib/rambling/trie/children_hash_deferer.rb +0 -0
- data/lib/rambling/trie/compressor.rb +3 -3
- data/lib/rambling/trie/enumerable.rb +0 -0
- data/lib/rambling/trie/inspector.rb +10 -0
- data/lib/rambling/trie/invalid_operation.rb +0 -0
- data/lib/rambling/trie/node.rb +6 -5
- data/lib/rambling/trie/root.rb +19 -21
- data/lib/rambling/trie/tasks/gem.rb +0 -0
- data/lib/rambling/trie/tasks/performance.rb +11 -11
- data/lib/rambling/trie/version.rb +1 -1
- data/rambling-trie.gemspec +9 -9
- data/spec/assets/test_words.txt +0 -0
- data/spec/lib/rambling/trie/branches_spec.rb +18 -17
- data/spec/lib/rambling/trie/children_hash_deferer_spec.rb +3 -3
- data/spec/lib/rambling/trie/enumerable_spec.rb +8 -8
- data/spec/lib/rambling/trie/inspector_spec.rb +22 -0
- data/spec/lib/rambling/trie/node_spec.rb +58 -34
- data/spec/lib/rambling/trie/root_spec.rb +150 -139
- data/spec/lib/rambling/trie_spec.rb +17 -17
- data/spec/spec_helper.rb +7 -1
- metadata +26 -15
data/.gitignore
CHANGED
data/.rspec
CHANGED
File without changes
|
data/.travis.yml
CHANGED
File without changes
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard 'rspec',
|
4
|
+
guard 'rspec', all_on_start: true, all_after_pass: false do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
data/LICENSE
CHANGED
File without changes
|
data/README.markdown
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rambling Trie [](http://travis-ci.org/gonzedge/rambling-trie) [](https://gemnasium.com/gonzedge/rambling-trie) [](https://codeclimate.com/github/gonzedge/rambling-trie)
|
2
2
|
|
3
3
|
The Rambling Trie is a custom implementation of the Trie data structure with Ruby, which includes compression abilities and is designed to be very fast to traverse.
|
4
4
|
|
@@ -29,9 +29,10 @@ gem 'rambling-trie'
|
|
29
29
|
## How to use the Rambling Trie
|
30
30
|
|
31
31
|
- - -
|
32
|
-
### Deprecation
|
32
|
+
### Deprecation warnings
|
33
33
|
|
34
|
-
Starting from version 0.4.0, `Rambling::Trie.new` is deprecated. Please use `Rambling::Trie.create` instead.
|
34
|
+
* Starting from version 0.4.0, `Rambling::Trie.new` is deprecated. Please use `Rambling::Trie.create` instead.
|
35
|
+
* Starting from version 0.5.0, the `has_branch_for?`, `is_word?` and `add_branch_from` methods are deprecated. The methods `branch?`, `word?` and `add` should be used respectively.
|
35
36
|
- - -
|
36
37
|
|
37
38
|
To create the trie, initialize it like this:
|
@@ -40,30 +41,38 @@ To create the trie, initialize it like this:
|
|
40
41
|
trie = Rambling::Trie.create
|
41
42
|
```
|
42
43
|
|
43
|
-
You can also provide a file
|
44
|
+
You can also provide the path to a file that contains all the words to be added to the trie, and it will read the file and create the complete structure for you, like this:
|
44
45
|
|
45
46
|
``` ruby
|
46
47
|
trie = Rambling::Trie.create '/path/to/file'
|
47
48
|
```
|
48
49
|
|
49
|
-
|
50
|
+
You can also provide a block and the created instance will be yielded for you to perform any operation on it:
|
50
51
|
|
51
52
|
``` ruby
|
52
|
-
|
53
|
+
Rambling::Trie.create do |trie|
|
54
|
+
trie << 'word'
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
To add new words to the trie, use `add` or `<<`:
|
59
|
+
|
60
|
+
``` ruby
|
61
|
+
trie.add 'word'
|
53
62
|
trie << 'word'
|
54
63
|
```
|
55
64
|
|
56
|
-
And to find out if a word already exists in the trie, use `
|
65
|
+
And to find out if a word already exists in the trie, use `word?` or `include?`:
|
57
66
|
|
58
67
|
``` ruby
|
59
|
-
trie.
|
68
|
+
trie.word? 'word'
|
60
69
|
trie.include? 'word'
|
61
70
|
```
|
62
71
|
|
63
|
-
If you wish to find if part of a word exists in the trie instance, you should call `
|
72
|
+
If you wish to find if part of a word exists in the trie instance, you should call `branch?`:
|
64
73
|
|
65
74
|
``` ruby
|
66
|
-
trie.
|
75
|
+
trie.branch? 'partial_word'
|
67
76
|
```
|
68
77
|
|
69
78
|
### Compression
|
@@ -78,7 +87,7 @@ trie.compress!
|
|
78
87
|
|
79
88
|
This will reduce the amount of Trie nodes by eliminating the redundant ones, which are the only-child non-terminal nodes.
|
80
89
|
|
81
|
-
Starting from version 0.3.2, the `has_branch_for?` and `is_word?` methods work as expected on a compressed trie.
|
90
|
+
Starting from version 0.3.2, the `has_branch_for?` (now `has_branch?`) and `is_word?` (now `word?`) methods work as expected on a compressed trie.
|
82
91
|
|
83
92
|
__Note that the `compress!` method acts over the trie instance it belongs to.__
|
84
93
|
__Also, adding words after compression is not supported.__
|
@@ -89,9 +98,22 @@ You can find out if a trie instance is compressed by calling the `compressed?` m
|
|
89
98
|
trie.compressed?
|
90
99
|
```
|
91
100
|
|
101
|
+
### Enumeration
|
102
|
+
|
103
|
+
Starting from version 0.4.2, you can use any `Enumerable` method over a trie instance, and it will iterate over each word contained in the trie. You can now do things like:
|
104
|
+
|
105
|
+
``` ruby
|
106
|
+
trie.each do |word|
|
107
|
+
puts word
|
108
|
+
end
|
109
|
+
|
110
|
+
trie.any? { |word| word.include? 'x' }
|
111
|
+
# etc.
|
112
|
+
```
|
113
|
+
|
92
114
|
## Further Documentation
|
93
115
|
|
94
|
-
You can find further API documentation on the autogenerated [rambling-trie gem RubyDoc.info page](http://rubydoc.info/gems/rambling-trie) or if you want edge documentation, you can go the [GitHub project RubyDoc.info page](http://rubydoc.info/github/
|
116
|
+
You can find further API documentation on the autogenerated [rambling-trie gem RubyDoc.info page](http://rubydoc.info/gems/rambling-trie) or if you want edge documentation, you can go the [GitHub project RubyDoc.info page](http://rubydoc.info/github/gonzedge/rambling-trie).
|
95
117
|
|
96
118
|
## Compatible Ruby and Rails versions
|
97
119
|
|
@@ -105,7 +127,8 @@ And the following Rails versions:
|
|
105
127
|
* 3.1.x
|
106
128
|
* 3.2.x
|
107
129
|
|
108
|
-
It's possible that
|
130
|
+
It's possible that Rails 3.0.x is supported, but there is no guarantee.
|
131
|
+
Ruby 1.8.7 is not supported.
|
109
132
|
|
110
133
|
## Contributing to Rambling Trie
|
111
134
|
|
data/Rakefile
CHANGED
File without changes
|
File without changes
|
data/lib/rambling-trie.rb
CHANGED
File without changes
|
data/lib/rambling/trie.rb
CHANGED
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
'branches',
|
6
|
-
'enumerable',
|
7
|
-
'node',
|
8
|
-
'root',
|
9
|
-
'version'
|
10
|
-
].map { |file| File.join 'rambling', 'trie', file }.each &method(:require)
|
1
|
+
%w{
|
2
|
+
invalid_operation children_hash_deferer compressor
|
3
|
+
branches enumerable inspector node root version
|
4
|
+
}.map { |file| File.join 'rambling', 'trie', file }.each &method(:require)
|
11
5
|
|
12
6
|
# General namespace for all Rambling gems.
|
13
7
|
module Rambling
|
@@ -15,18 +9,19 @@ module Rambling
|
|
15
9
|
module Trie
|
16
10
|
class << self
|
17
11
|
# Creates a new Trie. Entry point for the Rambling::Trie API.
|
18
|
-
# @param [String, nil] filename the file to load the words from
|
12
|
+
# @param [String, nil] filename the file to load the words from.
|
13
|
+
# @return [Root] the trie just created.
|
14
|
+
# @yield [Root] the trie just created.
|
19
15
|
def create(filename = nil)
|
20
|
-
Root.new
|
16
|
+
Root.new do |root|
|
17
|
+
words_from(filename) { |word| root << word } if filename
|
18
|
+
yield root if block_given?
|
19
|
+
end
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# @see .create
|
27
|
-
def new(filename = nil)
|
28
|
-
warn '[DEPRECATION] `new` is deprecated. Please use `create` instead.'
|
29
|
-
create filename
|
22
|
+
private
|
23
|
+
def words_from(filename)
|
24
|
+
File.open(filename) { |file| file.each_line { |line| yield line.chomp } }
|
30
25
|
end
|
31
26
|
end
|
32
27
|
end
|
@@ -7,8 +7,8 @@ module Rambling
|
|
7
7
|
# @return [Node] the just added branch's root node.
|
8
8
|
# @raise [InvalidOperation] if the trie is already compressed.
|
9
9
|
# @note This method clears the contents of the word variable.
|
10
|
-
def
|
11
|
-
raise InvalidOperation
|
10
|
+
def add(word)
|
11
|
+
raise InvalidOperation, 'Cannot add branch to compressed trie' if compressed?
|
12
12
|
if word.empty?
|
13
13
|
@terminal = true
|
14
14
|
return
|
@@ -26,56 +26,49 @@ module Rambling
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
# @param [String] word the word to add the branch from.
|
31
|
-
# @return [Node] the just added branch's root node.
|
32
|
-
# @raise [InvalidOperation] if the trie is already compressed.
|
33
|
-
# @see #add_branch_from
|
34
|
-
def <<(word)
|
35
|
-
add_branch_from word
|
36
|
-
end
|
29
|
+
alias_method :<<, :add
|
37
30
|
|
38
31
|
protected
|
39
32
|
|
40
|
-
def
|
41
|
-
chars.empty? or fulfills_uncompressed_condition?(:
|
33
|
+
def branch_when_uncompressed?(chars)
|
34
|
+
chars.empty? or fulfills_uncompressed_condition?(:branch_when_uncompressed?, chars)
|
42
35
|
end
|
43
36
|
|
44
|
-
def
|
37
|
+
def branch_when_compressed?(chars)
|
45
38
|
return true if chars.empty?
|
46
39
|
|
47
40
|
first_letter = chars.slice! 0
|
48
41
|
current_key, current_key_string = current_key first_letter
|
49
42
|
|
50
43
|
unless current_key.nil?
|
51
|
-
return @children[current_key].
|
44
|
+
return @children[current_key].branch_when_compressed?(chars) if current_key_string.length == first_letter.length
|
52
45
|
|
53
46
|
while not chars.empty?
|
54
47
|
char = chars.slice! 0
|
55
48
|
|
56
49
|
break unless current_key_string[first_letter.length] == char
|
57
50
|
|
58
|
-
first_letter += char
|
59
51
|
return true if chars.empty?
|
60
|
-
|
52
|
+
first_letter << char
|
53
|
+
return @children[current_key].branch_when_compressed?(chars) if current_key_string.length == first_letter.length
|
61
54
|
end
|
62
55
|
end
|
63
56
|
|
64
57
|
false
|
65
58
|
end
|
66
59
|
|
67
|
-
def
|
68
|
-
(chars.empty? and terminal?) or fulfills_uncompressed_condition?(:
|
60
|
+
def word_when_uncompressed?(chars)
|
61
|
+
(chars.empty? and terminal?) or fulfills_uncompressed_condition?(:word_when_uncompressed?, chars)
|
69
62
|
end
|
70
63
|
|
71
|
-
def
|
64
|
+
def word_when_compressed?(chars)
|
72
65
|
return true if chars.empty? and terminal?
|
73
66
|
|
74
67
|
first_letter = ''
|
75
68
|
while not chars.empty?
|
76
|
-
first_letter
|
69
|
+
first_letter << chars.slice!(0)
|
77
70
|
key = first_letter.to_sym
|
78
|
-
return @children[key].
|
71
|
+
return @children[key].word_when_compressed?(chars) if @children.has_key? key
|
79
72
|
end
|
80
73
|
|
81
74
|
false
|
File without changes
|
@@ -8,10 +8,10 @@ module Rambling
|
|
8
8
|
@parent.nil? ? false : @parent.compressed?
|
9
9
|
end
|
10
10
|
|
11
|
-
#
|
11
|
+
# Compress the current node using redundant node elimination.
|
12
12
|
# @return [Root, Node] the compressed node.
|
13
13
|
def compress_tree!
|
14
|
-
if @children.size == 1 and not terminal? and
|
14
|
+
if @children.size == 1 and not terminal? and @letter
|
15
15
|
merge_with! @children.values.first
|
16
16
|
compress_tree!
|
17
17
|
end
|
@@ -24,7 +24,7 @@ module Rambling
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def merge_with!(child)
|
27
|
-
new_letter = (@letter.to_s
|
27
|
+
new_letter = (@letter.to_s << child.letter.to_s).to_sym
|
28
28
|
|
29
29
|
rehash_on_parent! @letter, new_letter
|
30
30
|
redefine_self! new_letter, child
|
File without changes
|
File without changes
|
data/lib/rambling/trie/node.rb
CHANGED
@@ -6,6 +6,7 @@ module Rambling
|
|
6
6
|
include Compressor
|
7
7
|
include Branches
|
8
8
|
include Enumerable
|
9
|
+
include Inspector
|
9
10
|
|
10
11
|
# Letter or letters corresponding to this node.
|
11
12
|
# @return [Symbol, nil] the corresponding letter(s) or nil.
|
@@ -20,9 +21,9 @@ module Rambling
|
|
20
21
|
attr_accessor :parent
|
21
22
|
|
22
23
|
# Creates a new Node.
|
23
|
-
# @param [String] word the word from which to create this Node and his branch.
|
24
|
-
# @param [Node] parent the parent of this node.
|
25
|
-
def initialize(word, parent = nil)
|
24
|
+
# @param [String, nil] word the word from which to create this Node and his branch.
|
25
|
+
# @param [Node, nil] parent the parent of this node.
|
26
|
+
def initialize(word = nil, parent = nil)
|
26
27
|
@letter, @parent, @terminal, @children = [nil, parent, false, {}]
|
27
28
|
|
28
29
|
unless word.nil? or word.empty?
|
@@ -43,13 +44,13 @@ module Rambling
|
|
43
44
|
# @return [String] the string representation of the current node.
|
44
45
|
# @raise [InvalidOperation] if node is not terminal or is root.
|
45
46
|
def as_word
|
46
|
-
raise InvalidOperation
|
47
|
+
raise InvalidOperation, 'Cannot represent branch as a word' unless @letter.nil? or terminal?
|
47
48
|
get_letter_string
|
48
49
|
end
|
49
50
|
|
50
51
|
protected
|
51
52
|
def get_letter_string
|
52
|
-
(@parent.nil? ? '' : @parent.get_letter_string)
|
53
|
+
(@parent.nil? ? '' : @parent.get_letter_string) << @letter.to_s
|
53
54
|
end
|
54
55
|
end
|
55
56
|
end
|
data/lib/rambling/trie/root.rb
CHANGED
@@ -3,19 +3,17 @@ module Rambling
|
|
3
3
|
# A representation of the root node in the Trie data structure.
|
4
4
|
class Root < Node
|
5
5
|
# Creates a new Trie.
|
6
|
-
# @
|
7
|
-
def initialize
|
8
|
-
super
|
9
|
-
|
10
|
-
@filename = filename
|
6
|
+
# @yield [Root] the trie just created.
|
7
|
+
def initialize
|
8
|
+
super
|
11
9
|
@compressed = false
|
12
|
-
|
10
|
+
yield self if block_given?
|
13
11
|
end
|
14
12
|
|
15
13
|
# Compresses the existing tree using redundant node elimination. Flags the trie as compressed.
|
16
|
-
# @return [Root]
|
14
|
+
# @return [Root] self
|
17
15
|
def compress!
|
18
|
-
@compressed = (not compress_tree!.nil?)
|
16
|
+
@compressed = (compressed? or not compress_tree!.nil?)
|
19
17
|
self
|
20
18
|
end
|
21
19
|
|
@@ -28,37 +26,37 @@ module Rambling
|
|
28
26
|
# Checks if a path for a word or partial word exists in the trie.
|
29
27
|
# @param [String] word the word or partial word to look for in the trie.
|
30
28
|
# @return [Boolean] `true` if the word or partial word is found, `false` otherwise.
|
31
|
-
def
|
32
|
-
fulfills_condition word, :
|
29
|
+
def branch?(word = '')
|
30
|
+
fulfills_condition? word, :branch?
|
33
31
|
end
|
34
32
|
|
35
33
|
# Checks if a whole word exists in the trie.
|
36
34
|
# @param [String] word the word to look for in the trie.
|
37
35
|
# @return [Boolean] `true` only if the word is found and the last character corresponds to a terminal node.
|
38
|
-
def
|
39
|
-
fulfills_condition word, :
|
36
|
+
def word?(word = '')
|
37
|
+
fulfills_condition? word, :word?
|
40
38
|
end
|
41
39
|
|
42
|
-
alias_method :include?, :
|
40
|
+
alias_method :include?, :word?
|
43
41
|
|
44
42
|
# Adds a branch to the trie based on the word, without changing the passed word.
|
45
43
|
# @param [String] word the word to add the branch from.
|
46
44
|
# @return [Node] the just added branch's root node.
|
47
45
|
# @raise [InvalidOperation] if the trie is already compressed.
|
48
|
-
# @see Branches#
|
46
|
+
# @see Branches#add
|
49
47
|
# @note Avoids clearing the contents of the word variable.
|
50
|
-
def
|
48
|
+
def add(word)
|
51
49
|
super word.clone
|
52
50
|
end
|
53
51
|
|
52
|
+
alias_method :<<, :add
|
53
|
+
|
54
54
|
private
|
55
|
-
def fulfills_condition(word, method)
|
56
|
-
method = compressed? ? "compressed_#{method}" : "uncompressed_#{method}"
|
57
|
-
send(method, word.chars.to_a)
|
58
|
-
end
|
59
55
|
|
60
|
-
def
|
61
|
-
|
56
|
+
def fulfills_condition?(word, method)
|
57
|
+
method = method.to_s.slice 0...(method.length - 1)
|
58
|
+
method = compressed? ? "#{method}_when_compressed?" : "#{method}_when_uncompressed?"
|
59
|
+
send method, word.chars.to_a
|
62
60
|
end
|
63
61
|
end
|
64
62
|
end
|
File without changes
|
@@ -3,7 +3,7 @@ require 'benchmark'
|
|
3
3
|
namespace :performance do
|
4
4
|
def report(name, trie, output)
|
5
5
|
words = ['hi', 'help', 'beautiful', 'impressionism', 'anthropological']
|
6
|
-
methods = [:
|
6
|
+
methods = [:word?, :branch?]
|
7
7
|
|
8
8
|
output.puts "==> #{name}"
|
9
9
|
methods.each do |method|
|
@@ -21,7 +21,7 @@ namespace :performance do
|
|
21
21
|
output.puts "\nReport for rambling-trie version #{Rambling::Trie::VERSION}"
|
22
22
|
|
23
23
|
trie = nil
|
24
|
-
measure = Benchmark.measure { trie = Rambling::Trie.create
|
24
|
+
measure = Benchmark.measure { trie = Rambling::Trie.create path('assets', 'dictionaries', 'words_with_friends.txt') }
|
25
25
|
|
26
26
|
if ENV['profile_creation']
|
27
27
|
output.puts '==> Creation'
|
@@ -39,8 +39,8 @@ namespace :performance do
|
|
39
39
|
output.close
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
File.join File.dirname(__FILE__), '..', '..', '..', *filename
|
42
|
+
def path(*filename)
|
43
|
+
File.join File.dirname(__FILE__), '..', '..', '..', '..', *filename
|
44
44
|
end
|
45
45
|
|
46
46
|
desc 'Generate performance report'
|
@@ -53,7 +53,7 @@ namespace :performance do
|
|
53
53
|
desc 'Generate performance report and append result to reports/performance'
|
54
54
|
task :save do
|
55
55
|
puts 'Generating performance report...'
|
56
|
-
generate_report
|
56
|
+
generate_report path('reports', 'performance')
|
57
57
|
puts 'Report has been saved to reports/performance'
|
58
58
|
end
|
59
59
|
end
|
@@ -64,9 +64,9 @@ namespace :performance do
|
|
64
64
|
|
65
65
|
puts 'Generating profiling reports...'
|
66
66
|
|
67
|
-
rambling_trie = Rambling::Trie.create
|
67
|
+
rambling_trie = Rambling::Trie.create path('assets', 'dictionaries', 'words_with_friends.txt')
|
68
68
|
words = ['hi', 'help', 'beautiful', 'impressionism', 'anthropological']
|
69
|
-
methods = [:
|
69
|
+
methods = [:branch?, :word?]
|
70
70
|
tries = [lambda {rambling_trie.clone}, lambda {rambling_trie.clone.compress!}]
|
71
71
|
|
72
72
|
methods.each do |method|
|
@@ -78,7 +78,7 @@ namespace :performance do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
File.open
|
81
|
+
File.open path('reports', "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-#{method.to_s.sub(/\?/, '')}-#{Time.now.to_i}"), 'w' do |file|
|
82
82
|
RubyProf::CallTreePrinter.new(result).print file
|
83
83
|
end
|
84
84
|
end
|
@@ -93,15 +93,15 @@ namespace :performance do
|
|
93
93
|
|
94
94
|
puts 'Generating cpu profiling reports...'
|
95
95
|
|
96
|
-
rambling_trie = Rambling::Trie.create
|
96
|
+
rambling_trie = Rambling::Trie.create path('assets', 'dictionaries', 'words_with_friends.txt')
|
97
97
|
words = ['hi', 'help', 'beautiful', 'impressionism', 'anthropological']
|
98
|
-
methods = [:
|
98
|
+
methods = [:branch?, :word?]
|
99
99
|
tries = [lambda {rambling_trie.clone}, lambda {rambling_trie.clone.compress!}]
|
100
100
|
|
101
101
|
methods.each do |method|
|
102
102
|
tries.each do |trie_generator|
|
103
103
|
trie = trie_generator.call
|
104
|
-
result = PerfTools::CpuProfiler.start
|
104
|
+
result = PerfTools::CpuProfiler.start path('reports', "cpu_profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-#{method.to_s.sub(/\?/, '')}-#{Time.now.to_i}") do
|
105
105
|
words.each do |word|
|
106
106
|
200_000.times { trie.send method, word }
|
107
107
|
end
|