rambling-trie 2.5.0 → 2.5.1
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/Dockerfile +28 -0
- data/Gemfile +18 -9
- data/Guardfile +16 -5
- data/README.md +23 -23
- data/Rakefile +6 -0
- data/Steepfile +35 -0
- data/lib/rambling/trie/comparable.rb +2 -2
- data/lib/rambling/trie/compressible.rb +1 -1
- data/lib/rambling/trie/compressor.rb +22 -21
- data/lib/rambling/trie/configuration/properties.rb +5 -4
- data/lib/rambling/trie/configuration/provider_collection.rb +12 -7
- data/lib/rambling/trie/configuration.rb +2 -3
- data/lib/rambling/trie/container.rb +20 -23
- data/lib/rambling/trie/enumerable.rb +4 -5
- data/lib/rambling/trie/nodes/compressed.rb +26 -16
- data/lib/rambling/trie/nodes/node.rb +31 -8
- data/lib/rambling/trie/nodes/raw.rb +16 -19
- data/lib/rambling/trie/nodes.rb +2 -3
- data/lib/rambling/trie/readers/plain_text.rb +2 -2
- data/lib/rambling/trie/readers.rb +2 -3
- data/lib/rambling/trie/serializers/marshal.rb +1 -1
- data/lib/rambling/trie/serializers/yaml.rb +1 -1
- data/lib/rambling/trie/serializers/zip.rb +12 -6
- data/lib/rambling/trie/serializers.rb +2 -3
- data/lib/rambling/trie/stringifyable.rb +1 -1
- data/lib/rambling/trie/version.rb +1 -1
- data/lib/rambling/trie.rb +11 -14
- data/rambling-trie.gemspec +1 -1
- data/sig/lib/rambling/trie/comparable.rbs +17 -0
- data/sig/lib/rambling/trie/compressible.rbs +17 -0
- data/sig/lib/rambling/trie/compressor.rbs +17 -0
- data/sig/lib/rambling/trie/configuration/properties.rbs +28 -0
- data/sig/lib/rambling/trie/configuration/provider_collection.rbs +47 -0
- data/sig/lib/rambling/trie/container.rbs +69 -0
- data/sig/lib/rambling/trie/enumerable.rbs +23 -0
- data/sig/lib/rambling/trie/inspectable.rbs +27 -0
- data/sig/lib/rambling/trie/invalid_operation.rbs +7 -0
- data/sig/lib/rambling/trie/nodes/compressed.rbs +25 -0
- data/sig/lib/rambling/trie/nodes/missing.rbs +9 -0
- data/sig/lib/rambling/trie/nodes/node.rbs +69 -0
- data/sig/lib/rambling/trie/nodes/raw.rbs +27 -0
- data/sig/lib/rambling/trie/readers/plain_text.rbs +9 -0
- data/sig/lib/rambling/trie/readers/reader.rbs +9 -0
- data/sig/lib/rambling/trie/serializers/file.rbs +8 -0
- data/sig/lib/rambling/trie/serializers/marshal.rbs +13 -0
- data/sig/lib/rambling/trie/serializers/serializer.rbs +10 -0
- data/sig/lib/rambling/trie/serializers/yaml.rbs +13 -0
- data/sig/lib/rambling/trie/serializers/zip.rbs +21 -0
- data/sig/lib/rambling/trie/stringifyable.rbs +21 -0
- data/sig/lib/rambling/trie.rbs +27 -0
- data/sig/lib/zip/entry.rbs +11 -0
- data/sig/lib/zip/file.rbs +11 -0
- metadata +29 -3
@@ -6,6 +6,9 @@ module Rambling
|
|
6
6
|
module Enumerable
|
7
7
|
include ::Enumerable
|
8
8
|
|
9
|
+
# Empty enumerator constant for early each exits.
|
10
|
+
EMPTY_ENUMERATOR = [].to_enum :each
|
11
|
+
|
9
12
|
# Returns number of words contained in the trie
|
10
13
|
# @see https://ruby-doc.org/3.3.0/Enumerable.html#method-i-count Enumerable#count
|
11
14
|
alias_method :size, :count
|
@@ -18,11 +21,7 @@ module Rambling
|
|
18
21
|
|
19
22
|
yield as_word if terminal?
|
20
23
|
|
21
|
-
children_tree.each_value
|
22
|
-
child.each do |word|
|
23
|
-
yield word
|
24
|
-
end
|
25
|
-
end
|
24
|
+
children_tree.each_value { |child| child.each { |word| yield word } }
|
26
25
|
|
27
26
|
self
|
28
27
|
end
|
@@ -4,7 +4,19 @@ module Rambling
|
|
4
4
|
module Trie
|
5
5
|
module Nodes
|
6
6
|
# A representation of a node in an compressed trie data structure.
|
7
|
+
# :reek:RepeatedConditional { max_ifs: 4 }
|
7
8
|
class Compressed < Rambling::Trie::Nodes::Node
|
9
|
+
# Creates a new compressed node.
|
10
|
+
# @param [Symbol, nil] letter the Node's letter value.
|
11
|
+
# @param [Node, nil] parent the parent of the current node.
|
12
|
+
# @param [Hash<Symbol, Node>] children_tree the children tree of the current node.
|
13
|
+
def initialize letter = nil, parent = nil, children_tree = {}
|
14
|
+
super
|
15
|
+
|
16
|
+
# Ensure all children have the current compressed node as the parent
|
17
|
+
children_tree.each_value { |child| child.parent = self }
|
18
|
+
end
|
19
|
+
|
8
20
|
# Always raises {Rambling::Trie::InvalidOperation InvalidOperation} when
|
9
21
|
# trying to add a word to the current compressed trie node
|
10
22
|
# @param [String] _ the word to add to the trie.
|
@@ -14,8 +26,8 @@ module Rambling
|
|
14
26
|
raise Rambling::Trie::InvalidOperation, 'Cannot add word to compressed trie'
|
15
27
|
end
|
16
28
|
|
17
|
-
# Always return
|
18
|
-
# @return [Boolean] always
|
29
|
+
# Always return `true` for a compressed node.
|
30
|
+
# @return [Boolean] always `true` for a compressed node.
|
19
31
|
def compressed?
|
20
32
|
true
|
21
33
|
end
|
@@ -23,13 +35,13 @@ module Rambling
|
|
23
35
|
private
|
24
36
|
|
25
37
|
def partial_word_chars? chars
|
26
|
-
child = children_tree[chars.first.to_sym]
|
38
|
+
child = children_tree[(chars.first || raise).to_sym]
|
27
39
|
return false unless child
|
28
40
|
|
29
41
|
child_letter = child.letter.to_s
|
30
42
|
|
31
43
|
if chars.size >= child_letter.size
|
32
|
-
letter = chars.
|
44
|
+
letter = (chars.shift(child_letter.size) || raise).join
|
33
45
|
return child.partial_word? chars if child_letter == letter
|
34
46
|
end
|
35
47
|
|
@@ -39,7 +51,7 @@ module Rambling
|
|
39
51
|
end
|
40
52
|
|
41
53
|
def word_chars? chars
|
42
|
-
letter = chars.
|
54
|
+
letter = chars.shift || raise
|
43
55
|
letter_sym = letter.to_sym
|
44
56
|
|
45
57
|
child = children_tree[letter_sym]
|
@@ -50,7 +62,7 @@ module Rambling
|
|
50
62
|
|
51
63
|
break if chars.empty?
|
52
64
|
|
53
|
-
letter << chars.
|
65
|
+
letter << (chars.shift || raise)
|
54
66
|
letter_sym = letter.to_sym
|
55
67
|
end
|
56
68
|
|
@@ -58,13 +70,13 @@ module Rambling
|
|
58
70
|
end
|
59
71
|
|
60
72
|
def closest_node chars
|
61
|
-
child = children_tree[chars.first.to_sym]
|
73
|
+
child = children_tree[(chars.first || raise).to_sym]
|
62
74
|
return missing unless child
|
63
75
|
|
64
76
|
child_letter = child.letter.to_s
|
65
77
|
|
66
78
|
if chars.size >= child_letter.size
|
67
|
-
letter = chars.
|
79
|
+
letter = (chars.shift(child_letter.size) || raise).join
|
68
80
|
return child.scan chars if child_letter == letter
|
69
81
|
end
|
70
82
|
|
@@ -77,19 +89,17 @@ module Rambling
|
|
77
89
|
def children_match_prefix chars
|
78
90
|
return enum_for :children_match_prefix, chars unless block_given?
|
79
91
|
|
80
|
-
return if chars.empty?
|
92
|
+
return EMPTY_ENUMERATOR if chars.empty?
|
81
93
|
|
82
|
-
child = children_tree[chars.first.to_sym]
|
83
|
-
return unless child
|
94
|
+
child = children_tree[(chars.first || raise).to_sym]
|
95
|
+
return EMPTY_ENUMERATOR unless child
|
84
96
|
|
85
97
|
child_letter = child.letter.to_s
|
86
|
-
letter = chars.
|
98
|
+
letter = (chars.shift(child_letter.size) || raise).join
|
87
99
|
|
88
|
-
return unless child_letter == letter
|
100
|
+
return EMPTY_ENUMERATOR unless child_letter == letter
|
89
101
|
|
90
|
-
child.match_prefix
|
91
|
-
yield word
|
92
|
-
end
|
102
|
+
child.match_prefix(chars) { |word| yield word }
|
93
103
|
end
|
94
104
|
end
|
95
105
|
end
|
@@ -4,6 +4,8 @@ module Rambling
|
|
4
4
|
module Trie
|
5
5
|
module Nodes
|
6
6
|
# A representation of a node in the trie data structure.
|
7
|
+
# :reek:MissingSafeMethod { exclude: [ terminal! ] }
|
8
|
+
# :reek:RepeatedConditional { max_ifs: 3 }
|
7
9
|
class Node
|
8
10
|
include Rambling::Trie::Compressible
|
9
11
|
include Rambling::Trie::Enumerable
|
@@ -22,7 +24,7 @@ module Rambling
|
|
22
24
|
attr_reader :letter
|
23
25
|
|
24
26
|
# Child nodes tree.
|
25
|
-
# @return [Hash<Symbol, Node>] the children tree hash, consisting of
|
27
|
+
# @return [Hash<Symbol, Node>] the children tree hash, consisting of `:letter => node`.
|
26
28
|
attr_accessor :children_tree
|
27
29
|
|
28
30
|
# Parent node.
|
@@ -32,6 +34,7 @@ module Rambling
|
|
32
34
|
# Creates a new node.
|
33
35
|
# @param [Symbol, nil] letter the Node's letter value.
|
34
36
|
# @param [Node, nil] parent the parent of the current node.
|
37
|
+
# @param [Hash<Symbol, Node>] children_tree the children tree of the current node.
|
35
38
|
def initialize letter = nil, parent = nil, children_tree = {}
|
36
39
|
@letter = letter
|
37
40
|
@parent = parent
|
@@ -52,16 +55,18 @@ module Rambling
|
|
52
55
|
# rubocop:disable Lint/UnreachableLoop
|
53
56
|
children_tree.each_value { |child| return child }
|
54
57
|
# rubocop:enable Lint/UnreachableLoop
|
58
|
+
|
59
|
+
nil
|
55
60
|
end
|
56
61
|
|
57
62
|
# Indicates if the current node is the root node.
|
58
|
-
# @return [Boolean]
|
63
|
+
# @return [Boolean] `true` if the node does not have a parent, `false` otherwise.
|
59
64
|
def root?
|
60
65
|
!parent
|
61
66
|
end
|
62
67
|
|
63
68
|
# Indicates if a {Node Node} is terminal or not.
|
64
|
-
# @return [Boolean]
|
69
|
+
# @return [Boolean] `true` for terminal nodes, `false` otherwise.
|
65
70
|
def terminal?
|
66
71
|
!!terminal
|
67
72
|
end
|
@@ -79,7 +84,7 @@ module Rambling
|
|
79
84
|
|
80
85
|
# Checks if a path for a set of characters exists in the trie.
|
81
86
|
# @param [Array<String>] chars the characters to look for in the trie.
|
82
|
-
# @return [Boolean]
|
87
|
+
# @return [Boolean] `true` if the characters are found, `false` otherwise.
|
83
88
|
def partial_word? chars
|
84
89
|
return true if chars.empty?
|
85
90
|
|
@@ -88,7 +93,7 @@ module Rambling
|
|
88
93
|
|
89
94
|
# Checks if a path for set of characters represents a word in the trie.
|
90
95
|
# @param [Array<String>] chars the characters to look for in the trie.
|
91
|
-
# @return [Boolean]
|
96
|
+
# @return [Boolean] `true` if the characters are found and form a word, `false` otherwise.
|
92
97
|
def word? chars = []
|
93
98
|
return terminal? if chars.empty?
|
94
99
|
|
@@ -106,7 +111,7 @@ module Rambling
|
|
106
111
|
end
|
107
112
|
|
108
113
|
# Returns all words that match a prefix of any length within chars.
|
109
|
-
# @param [String] chars the chars to base the prefix on.
|
114
|
+
# @param [Array[String]] chars the chars to base the prefix on.
|
110
115
|
# @return [Enumerator<String>] all the words that match a prefix by chars.
|
111
116
|
# @yield [String] each word found.
|
112
117
|
def match_prefix chars
|
@@ -138,7 +143,7 @@ module Rambling
|
|
138
143
|
|
139
144
|
# Check if a {Node Node}'s children tree contains a given letter.
|
140
145
|
# @param [Symbol] letter the letter to search for in the node.
|
141
|
-
# @return [Boolean]
|
146
|
+
# @return [Boolean] `true` if the letter is present, `false` otherwise.
|
142
147
|
# @see https://ruby-doc.org/3.3.0/Hash.html#method-i-has_key-3F Hash#key?
|
143
148
|
def key? letter
|
144
149
|
children_tree.key? letter
|
@@ -147,7 +152,7 @@ module Rambling
|
|
147
152
|
# Delete a given letter and its corresponding {Node Node} from
|
148
153
|
# this {Node Node}'s children tree.
|
149
154
|
# @param [Symbol] letter the letter to delete from the node's children tree.
|
150
|
-
# @return [Node] the node corresponding to the deleted letter.
|
155
|
+
# @return [Node, nil] the node corresponding to the deleted letter.
|
151
156
|
# @see https://ruby-doc.org/3.3.0/Hash.html#method-i-delete Hash#delete
|
152
157
|
def delete letter
|
153
158
|
children_tree.delete letter
|
@@ -164,6 +169,24 @@ module Rambling
|
|
164
169
|
private
|
165
170
|
|
166
171
|
attr_accessor :terminal
|
172
|
+
|
173
|
+
# abstract methods
|
174
|
+
|
175
|
+
def children_match_prefix chars
|
176
|
+
raise NotImplementedError
|
177
|
+
end
|
178
|
+
|
179
|
+
def partial_word_chars? chars
|
180
|
+
raise NotImplementedError
|
181
|
+
end
|
182
|
+
|
183
|
+
def word_chars? chars
|
184
|
+
raise NotImplementedError
|
185
|
+
end
|
186
|
+
|
187
|
+
def closest_node chars
|
188
|
+
raise NotImplementedError
|
189
|
+
end
|
167
190
|
end
|
168
191
|
end
|
169
192
|
end
|
@@ -4,22 +4,23 @@ module Rambling
|
|
4
4
|
module Trie
|
5
5
|
module Nodes
|
6
6
|
# A representation of a node in an uncompressed trie data structure.
|
7
|
+
# :reek:RepeatedConditional { max_ifs: 4 }
|
7
8
|
class Raw < Rambling::Trie::Nodes::Node
|
8
9
|
# Adds a word to the current raw (uncompressed) trie node.
|
9
|
-
# @param [Array<Symbol>]
|
10
|
-
# @return [
|
10
|
+
# @param [Array<Symbol>] reversed_chars the char array to add to the trie, in reverse order.
|
11
|
+
# @return [Node] the added/modified node based on the word added.
|
11
12
|
# @note This method clears the contents of the chars variable.
|
12
|
-
def add
|
13
|
-
if
|
13
|
+
def add reversed_chars
|
14
|
+
if reversed_chars.empty?
|
14
15
|
terminal! unless root?
|
15
16
|
self
|
16
17
|
else
|
17
|
-
add_to_children_tree
|
18
|
+
add_to_children_tree reversed_chars
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
# Always return
|
22
|
-
# @return [Boolean] always
|
22
|
+
# Always return `false` for a raw (uncompressed) node.
|
23
|
+
# @return [Boolean] always `false` for a raw (uncompressed) node.
|
23
24
|
def compressed?
|
24
25
|
false
|
25
26
|
end
|
@@ -27,7 +28,7 @@ module Rambling
|
|
27
28
|
private
|
28
29
|
|
29
30
|
def add_to_children_tree chars
|
30
|
-
letter = chars.pop
|
31
|
+
letter = chars.pop || raise
|
31
32
|
child = children_tree[letter] || new_node(letter)
|
32
33
|
child.add chars
|
33
34
|
child
|
@@ -40,7 +41,7 @@ module Rambling
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def partial_word_chars? chars = []
|
43
|
-
letter = chars.shift.to_sym
|
44
|
+
letter = (chars.shift || raise).to_sym
|
44
45
|
child = children_tree[letter]
|
45
46
|
return false unless child
|
46
47
|
|
@@ -48,7 +49,7 @@ module Rambling
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def word_chars? chars = []
|
51
|
-
letter = chars.shift.to_sym
|
52
|
+
letter = (chars.shift || raise).to_sym
|
52
53
|
child = children_tree[letter]
|
53
54
|
return false unless child
|
54
55
|
|
@@ -56,7 +57,7 @@ module Rambling
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def closest_node chars
|
59
|
-
letter = chars.shift.to_sym
|
60
|
+
letter = (chars.shift || raise).to_sym
|
60
61
|
child = children_tree[letter]
|
61
62
|
return missing unless child
|
62
63
|
|
@@ -66,16 +67,12 @@ module Rambling
|
|
66
67
|
def children_match_prefix chars
|
67
68
|
return enum_for :children_match_prefix, chars unless block_given?
|
68
69
|
|
69
|
-
return if chars.empty?
|
70
|
+
return EMPTY_ENUMERATOR if chars.empty?
|
70
71
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
return unless child
|
72
|
+
child = children_tree[(chars.shift || raise).to_sym]
|
73
|
+
return EMPTY_ENUMERATOR unless child
|
75
74
|
|
76
|
-
child.match_prefix
|
77
|
-
yield word
|
78
|
-
end
|
75
|
+
child.match_prefix(chars) { |word| yield word }
|
79
76
|
end
|
80
77
|
end
|
81
78
|
end
|
data/lib/rambling/trie/nodes.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
end
|
3
|
+
path = File.join 'rambling', 'trie', 'nodes'
|
4
|
+
%w(node missing compressed raw).each { |file| require File.join(path, file) }
|
6
5
|
|
7
6
|
module Rambling
|
8
7
|
module Trie
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Readers
|
6
|
-
# File reader for
|
6
|
+
# File reader for `.txt` files.
|
7
7
|
class PlainText < Reader
|
8
|
-
# Yields each word read from a
|
8
|
+
# Yields each word read from a `.txt` file.
|
9
9
|
# @param [String] filepath the full path of the file to load the words from.
|
10
10
|
# @yield [String] Each line read from the file.
|
11
11
|
# @return [self]
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
end
|
3
|
+
path = File.join 'rambling', 'trie', 'readers'
|
4
|
+
%w(reader plain_text).each { |file| require File.join(path, file) }
|
6
5
|
|
7
6
|
module Rambling
|
8
7
|
module Trie
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Serializer for Ruby marshal format (
|
6
|
+
# Serializer for Ruby marshal format (`.marshal`) files.
|
7
7
|
class Marshal < Serializer
|
8
8
|
# Creates a new Marshal serializer.
|
9
9
|
# @param [Serializer] serializer the serializer responsible to write to and read from disk.
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Serializer for Ruby yaml format (
|
6
|
+
# Serializer for Ruby yaml format (`.yaml`, or `.yml`) files.
|
7
7
|
class Yaml < Serializer
|
8
8
|
# Creates a new Yaml serializer.
|
9
9
|
# @param [Serializer] serializer the serializer responsible to write to and read from disk.
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Zip file serializer. Dumps/loads contents from
|
7
|
-
# Automatically detects if zip file contains a
|
8
|
-
# or any other registered
|
6
|
+
# Zip file serializer. Dumps/loads contents from `.zip` files.
|
7
|
+
# Automatically detects if zip file contains a `.marshal` or `.yml` file,
|
8
|
+
# or any other registered `:format => serializer` combo.
|
9
9
|
class Zip < Serializer
|
10
10
|
# Creates a new Zip serializer.
|
11
11
|
# @param [Configuration::Properties] properties the configuration
|
@@ -26,12 +26,15 @@ module Rambling
|
|
26
26
|
|
27
27
|
::Zip::File.open filepath do |zip|
|
28
28
|
entry = zip.entries.first
|
29
|
-
|
29
|
+
raise unless entry
|
30
30
|
|
31
|
-
|
31
|
+
entry_name = entry.name
|
32
|
+
entry_path = path entry_name
|
32
33
|
entry.extract entry_path
|
33
34
|
|
34
|
-
serializer = serializers.resolve
|
35
|
+
serializer = serializers.resolve entry_name
|
36
|
+
raise unless serializer
|
37
|
+
|
35
38
|
serializer.load entry_path
|
36
39
|
end
|
37
40
|
end
|
@@ -50,6 +53,9 @@ module Rambling
|
|
50
53
|
|
51
54
|
entry_path = path filename
|
52
55
|
serializer = serializers.resolve filename
|
56
|
+
|
57
|
+
raise unless serializer
|
58
|
+
|
53
59
|
serializer.dump contents, entry_path
|
54
60
|
|
55
61
|
zip.add filename, entry_path
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
end
|
3
|
+
path = File.join 'rambling', 'trie', 'serializers'
|
4
|
+
%w(serializer file marshal yaml zip).each { |file| require File.join(path, file) }
|
6
5
|
|
7
6
|
module Rambling
|
8
7
|
module Trie
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
|
-
# Provides the
|
5
|
+
# Provides the `String` representation behavior for the trie data structure.
|
6
6
|
module Stringifyable
|
7
7
|
# String representation of the current node, if it is a terminal node.
|
8
8
|
# @return [String] the string representation of the current node.
|
data/lib/rambling/trie.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
path = File.join 'rambling', 'trie'
|
3
4
|
%w(
|
4
5
|
comparable compressible compressor configuration container enumerable inspectable invalid_operation
|
5
6
|
readers serializers stringifyable nodes version
|
6
|
-
).each
|
7
|
-
require File.join('rambling', 'trie', file)
|
8
|
-
end
|
7
|
+
).each { |file| require File.join(path, file) }
|
9
8
|
|
10
9
|
# General namespace for all Rambling gems.
|
11
10
|
module Rambling
|
12
|
-
# Entry point for
|
11
|
+
# Entry point for `rambling-trie` API.
|
13
12
|
module Trie
|
14
13
|
class << self
|
15
|
-
# Creates a new
|
14
|
+
# Creates a new `Rambling::Trie`. Entry point for the `rambling-trie` API.
|
16
15
|
# @param [String, nil] filepath the file to load the words from.
|
17
16
|
# @param [Readers::Reader, nil] reader the file parser to get each word.
|
18
17
|
# @return [Container] the trie just created.
|
@@ -26,9 +25,7 @@ module Rambling
|
|
26
25
|
if filepath
|
27
26
|
reader ||= readers.resolve filepath
|
28
27
|
# noinspection RubyMismatchedArgumentType,RubyNilAnalysis
|
29
|
-
reader.each_word
|
30
|
-
container << word
|
31
|
-
end
|
28
|
+
(reader || raise).each_word(filepath) { |word| container << word }
|
32
29
|
end
|
33
30
|
|
34
31
|
yield container if block_given?
|
@@ -37,7 +34,7 @@ module Rambling
|
|
37
34
|
|
38
35
|
# Loads an existing trie from disk into memory. By default, it will
|
39
36
|
# deduce the correct way to deserialize based on the file extension.
|
40
|
-
# Available formats are
|
37
|
+
# Available formats are `yml`, `marshal`, and `zip` versions of all the
|
41
38
|
# previous formats. You can also define your own.
|
42
39
|
# @param [String] filepath the file to load the words from.
|
43
40
|
# @param [Serializer, nil] serializer the object responsible of loading the trie from disk.
|
@@ -45,10 +42,10 @@ module Rambling
|
|
45
42
|
# @yield [Container] the trie just loaded.
|
46
43
|
# @see Rambling::Trie::Serializers Serializers.
|
47
44
|
# @note Use of # {https://ruby-doc.org/3.3.0/Marshal.html#method-c-load Marshal.load} is generally
|
48
|
-
# discouraged. Only use the
|
45
|
+
# discouraged. Only use the `.marshal` format with trusted input.
|
49
46
|
def load filepath, serializer = nil
|
50
47
|
serializer ||= serializers.resolve filepath
|
51
|
-
root = serializer.load filepath
|
48
|
+
root = (serializer || raise).load filepath
|
52
49
|
Rambling::Trie::Container.new root, compressor do |container|
|
53
50
|
yield container if block_given?
|
54
51
|
end
|
@@ -56,7 +53,7 @@ module Rambling
|
|
56
53
|
|
57
54
|
# Dumps an existing trie from memory into disk. By default, it will
|
58
55
|
# deduce the correct way to serialize based on the file extension.
|
59
|
-
# Available formats are
|
56
|
+
# Available formats are `yml`, `marshal`, and `zip` versions of all the
|
60
57
|
# previous formats. You can also define your own.
|
61
58
|
# @param [Container] trie the trie to dump into disk.
|
62
59
|
# @param [String] filepath the file to dump to serialized trie into.
|
@@ -66,10 +63,10 @@ module Rambling
|
|
66
63
|
def dump trie, filepath, serializer = nil
|
67
64
|
serializer ||= serializers.resolve filepath
|
68
65
|
# noinspection RubyNilAnalysis
|
69
|
-
serializer.dump trie.root, filepath
|
66
|
+
(serializer || raise).dump trie.root, filepath
|
70
67
|
end
|
71
68
|
|
72
|
-
# Provides configuration properties for the
|
69
|
+
# Provides configuration properties for the `Rambling::Trie` gem.
|
73
70
|
# @return [Configuration::Properties] the configured properties of the gem.
|
74
71
|
# @yield [Configuration::Properties] the configured properties of the gem.
|
75
72
|
def config
|
data/rambling-trie.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
}
|
22
22
|
|
23
23
|
executables = `git ls-files -- bin/*`.split "\n"
|
24
|
-
files = `git ls-files -- {lib,*file,*.gemspec,LICENSE*,README*}`.split "\n"
|
24
|
+
files = `git ls-files -- {lib,sig,*file,*.gemspec,LICENSE*,README*}`.split "\n"
|
25
25
|
|
26
26
|
gem.executables = executables.map { |f| File.basename f }
|
27
27
|
gem.files = files
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rambling
|
2
|
+
module Trie
|
3
|
+
module Comparable
|
4
|
+
def ==: (Nodes::Node) -> bool
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# abstract methods
|
9
|
+
|
10
|
+
def letter: -> Symbol
|
11
|
+
|
12
|
+
def terminal?: -> bool
|
13
|
+
|
14
|
+
def children_tree: -> Hash[Symbol, Nodes::Node]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rambling
|
2
|
+
module Trie
|
3
|
+
class Compressor
|
4
|
+
def compress: (Nodes::Node?) -> Nodes::Compressed?
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def compress_only_child_and_merge: (Nodes::Node) -> Nodes::Compressed
|
9
|
+
|
10
|
+
def merge: (Nodes::Node, Nodes::Node) -> Nodes::Compressed
|
11
|
+
|
12
|
+
def compress_children_and_copy: (Nodes::Node) -> Nodes::Compressed
|
13
|
+
|
14
|
+
def compress_children: (Hash[Symbol, Nodes::Node]) -> Hash[Symbol, Nodes::Node]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Rambling
|
2
|
+
module Trie
|
3
|
+
module Configuration
|
4
|
+
class Properties
|
5
|
+
attr_reader readers: ProviderCollection[Readers::Reader]
|
6
|
+
attr_reader serializers: ProviderCollection[Serializers::Serializer[Nodes::Node]]
|
7
|
+
attr_accessor compressor: Compressor
|
8
|
+
attr_accessor root_builder: ^() -> Nodes::Node
|
9
|
+
attr_accessor tmp_path: String
|
10
|
+
|
11
|
+
def initialize: -> void
|
12
|
+
|
13
|
+
def reset: -> void
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_writer readers: ProviderCollection[Readers::Reader]
|
18
|
+
attr_writer serializers: ProviderCollection[Serializers::Serializer[Nodes::Node]]
|
19
|
+
|
20
|
+
def reset_readers: -> void
|
21
|
+
|
22
|
+
def default_reader_providers: -> Hash[Symbol, Readers::Reader]
|
23
|
+
|
24
|
+
def reset_serializers: -> void
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|