rambling-trie 1.0.3 → 2.2.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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +6 -4
  3. data/Guardfile +3 -1
  4. data/README.md +12 -9
  5. data/Rakefile +4 -0
  6. data/lib/rambling-trie.rb +2 -0
  7. data/lib/rambling/trie.rb +25 -9
  8. data/lib/rambling/trie/comparable.rb +4 -1
  9. data/lib/rambling/trie/compressible.rb +6 -4
  10. data/lib/rambling/trie/compressor.rb +12 -10
  11. data/lib/rambling/trie/configuration.rb +3 -1
  12. data/lib/rambling/trie/configuration/properties.rb +15 -8
  13. data/lib/rambling/trie/configuration/provider_collection.rb +4 -1
  14. data/lib/rambling/trie/container.rb +7 -40
  15. data/lib/rambling/trie/enumerable.rb +2 -0
  16. data/lib/rambling/trie/inspectable.rb +2 -0
  17. data/lib/rambling/trie/invalid_operation.rb +3 -1
  18. data/lib/rambling/trie/nodes.rb +3 -1
  19. data/lib/rambling/trie/nodes/compressed.rb +53 -70
  20. data/lib/rambling/trie/nodes/missing.rb +2 -0
  21. data/lib/rambling/trie/nodes/node.rb +38 -6
  22. data/lib/rambling/trie/nodes/raw.rb +21 -28
  23. data/lib/rambling/trie/readers.rb +3 -1
  24. data/lib/rambling/trie/readers/plain_text.rb +2 -0
  25. data/lib/rambling/trie/serializers.rb +3 -1
  26. data/lib/rambling/trie/serializers/file.rb +2 -0
  27. data/lib/rambling/trie/serializers/marshal.rb +12 -2
  28. data/lib/rambling/trie/serializers/yaml.rb +18 -2
  29. data/lib/rambling/trie/serializers/zip.rb +6 -0
  30. data/lib/rambling/trie/stringifyable.rb +8 -2
  31. data/lib/rambling/trie/version.rb +3 -1
  32. data/rambling-trie.gemspec +21 -10
  33. data/spec/integration/rambling/trie_spec.rb +8 -4
  34. data/spec/lib/rambling/trie/comparable_spec.rb +2 -0
  35. data/spec/lib/rambling/trie/compressor_spec.rb +35 -33
  36. data/spec/lib/rambling/trie/configuration/properties_spec.rb +17 -9
  37. data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +10 -14
  38. data/spec/lib/rambling/trie/container_spec.rb +28 -53
  39. data/spec/lib/rambling/trie/enumerable_spec.rb +2 -0
  40. data/spec/lib/rambling/trie/inspectable_spec.rb +32 -7
  41. data/spec/lib/rambling/trie/nodes/compressed_spec.rb +2 -0
  42. data/spec/lib/rambling/trie/nodes/node_spec.rb +2 -0
  43. data/spec/lib/rambling/trie/nodes/raw_spec.rb +2 -0
  44. data/spec/lib/rambling/trie/readers/plain_text_spec.rb +3 -1
  45. data/spec/lib/rambling/trie/serializers/file_spec.rb +2 -0
  46. data/spec/lib/rambling/trie/serializers/marshal_spec.rb +2 -0
  47. data/spec/lib/rambling/trie/serializers/yaml_spec.rb +2 -0
  48. data/spec/lib/rambling/trie/serializers/zip_spec.rb +6 -4
  49. data/spec/lib/rambling/trie/stringifyable_spec.rb +7 -3
  50. data/spec/lib/rambling/trie_spec.rb +16 -9
  51. data/spec/spec_helper.rb +10 -7
  52. data/spec/support/config.rb +6 -0
  53. data/spec/support/helpers/add_word.rb +2 -0
  54. data/spec/support/helpers/one_line_heredoc.rb +11 -0
  55. data/spec/support/shared_examples/a_compressible_trie.rb +7 -3
  56. data/spec/support/shared_examples/a_serializable_trie.rb +2 -0
  57. data/spec/support/shared_examples/a_serializer.rb +3 -1
  58. data/spec/support/shared_examples/a_trie_data_structure.rb +2 -0
  59. data/spec/support/shared_examples/a_trie_node.rb +15 -5
  60. data/spec/support/shared_examples/a_trie_node_implementation.rb +10 -6
  61. metadata +22 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 63d9f2dee886a2a54a5e1df6316eff8abd21dc81
4
- data.tar.gz: 5c25c7cfb39c458b6335d3e160cc543ecae2f951
2
+ SHA256:
3
+ metadata.gz: 84eecdcb6a45ad3f8104e85aadc5bfb777342a4ea2b332b5e236b651b1398375
4
+ data.tar.gz: b68bb7bd9a9da2fe61c921645ff0864ca0dcaa515920d99ccf9456bb5482e159
5
5
  SHA512:
6
- metadata.gz: 798145e320bddef33321bf18fa2a7713c29e8cc82a004a83b257b71923a97df9a6610e73c08625e9c927f90a7833a2c9e7a800bb1b6c03aa61b7808dd893fc3e
7
- data.tar.gz: 834c2e2fcc39611cda4d4de5847944bffac2bf5f6852d2c3ea12e3aca570f80ed9883666d7a35161cb1848712e2e7ecef21b05689c9d3e678a2afcea2f4f4592
6
+ metadata.gz: d6d88b9d85d9e373a6da19a7db578c7ecd20826974ea1cb4b6a2a502fd7b7d653de46c385e7aa4f9d31918d9d2a792563322c7d8e30ea272e1df053e352b1775
7
+ data.tar.gz: 4f47a7e8e9f38e6580154c5efe5e723798c48a264e530cb86951ee53e0c555f57bb04414a9367584242f6116e1c198ebbd4065b25d52f12a5769c5adc33cc516
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  source 'https://rubygems.org'
3
4
 
4
5
  gemspec
@@ -6,19 +7,20 @@ gemspec
6
7
  gem 'rubyzip'
7
8
 
8
9
  group :development do
9
- gem 'ruby-prof'
10
- gem 'memory_profiler'
11
10
  gem 'benchmark-ips'
12
11
  gem 'flamegraph'
13
- gem 'stackprof'
12
+ gem 'memory_profiler'
14
13
  gem 'pry'
14
+ gem 'ruby-prof'
15
+ gem 'stackprof'
15
16
  end
16
17
 
17
18
  group :test do
18
- gem 'simplecov', require: false
19
19
  gem 'coveralls', '~>0.8.21', require: false
20
+ gem 'simplecov', require: false
20
21
  end
21
22
 
22
23
  group :local do
23
24
  gem 'guard-rspec'
25
+ gem 'rubocop', require: false
24
26
  end
data/Guardfile CHANGED
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # A sample Guardfile
2
4
  # More info at https://github.com/guard/guard#readme
3
5
 
4
6
  guard 'rspec', cmd: 'rspec', all_on_start: true, all_after_pass: false do
5
7
  watch(%r{^spec/.+_spec\.rb$})
6
8
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
9
+ watch('spec/spec_helper.rb') { 'spec' }
8
10
  end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rambling Trie
2
2
 
3
- [![Gem Version][badge_fury_badge]][badge_fury_link] [![Dependency Status][gemnasium_badge]][gemnasium_link] [![Build Status][travis_ci_badge]][travis_ci_link] [![Code Climate][code_climate_badge]][code_climage_link] [![Coverage Status][coveralls_badge]][coveralls_link] [![Documentation Status][inch_ci_badge]][inch_ci_link] [![License][license_badge]][license_link]
3
+ [![Gem Version][badge_fury_badge]][badge_fury_link] [![Build Status][travis_ci_badge]][travis_ci_link] [![Code Climate][code_climate_badge]][code_climage_link] [![Coverage Status][coveralls_badge]][coveralls_link] [![Documentation Status][inch_ci_badge]][inch_ci_link] [![License][license_badge]][license_link]
4
4
 
5
5
  The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wiki], which includes compression abilities and is designed to be very fast to traverse.
6
6
 
@@ -10,7 +10,7 @@ The Rambling Trie is a Ruby implementation of the [trie data structure][trie_wik
10
10
 
11
11
  You will need:
12
12
 
13
- * Ruby 2.2.0 or up
13
+ * Ruby 2.5.0 or up
14
14
  * RubyGems
15
15
 
16
16
  See [RVM][rvm], [rbenv][rbenv] or [chruby][chruby] for more information on how to manage Ruby versions.
@@ -242,15 +242,18 @@ You can find further API documentation on the autogenerated [rambling-trie gem R
242
242
 
243
243
  The Rambling Trie has been tested with the following Ruby versions:
244
244
 
245
+ * 3.0.x
246
+ * 2.7.x
247
+ * 2.6.x
245
248
  * 2.5.x
246
- * 2.4.x
247
- * 2.3.x
248
- * 2.2.x
249
249
 
250
250
  **No longer supported**:
251
251
 
252
- * 2.1.x (might still work, but is not officially supported)
253
- * 2.0.x (might still work, but is not officially supported)
252
+ * 2.4.x (EOL'ed)
253
+ * 2.3.x (EOL'ed)
254
+ * 2.2.x
255
+ * 2.1.x
256
+ * 2.0.x
254
257
  * 1.9.x
255
258
  * 1.8.x
256
259
 
@@ -293,7 +296,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
293
296
  [rubydoc_github]: http://rubydoc.info/github/gonzedge/rambling-trie
294
297
  [rubyzip]: https://github.com/rubyzip/rubyzip
295
298
  [rvm]: https://rvm.io
296
- [travis_ci_badge]: https://travis-ci.org/gonzedge/rambling-trie.svg
297
- [travis_ci_link]: https://travis-ci.org/gonzedge/rambling-trie
299
+ [travis_ci_badge]: https://travis-ci.com/gonzedge/rambling-trie.svg?branch=master
300
+ [travis_ci_link]: https://travis-ci.com/github/gonzedge/rambling-trie
298
301
  [trie_wiki]: https://en.wikipedia.org/wiki/Trie
299
302
  [yaml]: https://ruby-doc.org/stdlib-2.5.0/libdoc/yaml/rdoc/YAML.html
data/Rakefile CHANGED
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
3
6
 
4
7
  require 'rambling-trie'
5
8
  require_relative 'tasks/performance'
@@ -7,5 +10,6 @@ require_relative 'tasks/serialization'
7
10
  require_relative 'tasks/ips'
8
11
 
9
12
  RSpec::Core::RakeTask.new :spec
13
+ RuboCop::RakeTask.new :rubocop
10
14
 
11
15
  task default: :spec
data/lib/rambling-trie.rb CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rambling/trie'
data/lib/rambling/trie.rb CHANGED
@@ -1,8 +1,10 @@
1
- %w{
1
+ # frozen_string_literal: true
2
+
3
+ %w(
2
4
  comparable compressible compressor configuration container enumerable
3
5
  inspectable invalid_operation readers serializers stringifyable nodes
4
6
  version
5
- }.each do |file|
7
+ ).each do |file|
6
8
  require File.join('rambling', 'trie', file)
7
9
  end
8
10
 
@@ -18,7 +20,9 @@ module Rambling
18
20
  # @yield [Container] the trie just created.
19
21
  # @see Rambling::Trie::Readers Readers.
20
22
  def create filepath = nil, reader = nil
21
- Rambling::Trie::Container.new root_builder.call, compressor do |container|
23
+ root = root_builder.call
24
+
25
+ Rambling::Trie::Container.new root, compressor do |container|
22
26
  if filepath
23
27
  reader ||= readers.resolve filepath
24
28
  reader.each_word filepath do |word|
@@ -30,13 +34,20 @@ module Rambling
30
34
  end
31
35
  end
32
36
 
33
- # Loads an existing trie from disk into memory.
37
+ # Loads an existing trie from disk into memory. By default, it will
38
+ # deduce the correct way to deserialize based on the file extension.
39
+ # Available formats are `yml`, `marshal`, and `zip` versions of all the
40
+ # previous formats. You can also define your own.
34
41
  # @param [String] filepath the file to load the words from.
35
- # @param [Serializer, nil] serializer the object responsible of loading the trie
36
- # from disk
42
+ # @param [Serializer, nil] serializer the object responsible of loading
43
+ # the trie from disk
37
44
  # @return [Container] the trie just loaded.
38
45
  # @yield [Container] the trie just loaded.
39
46
  # @see Rambling::Trie::Serializers Serializers.
47
+ # @note Use of
48
+ # {https://ruby-doc.org/core-2.5.0/Marshal.html#method-c-load
49
+ # Marshal.load} is generally discouraged. Only use the `.marshal`
50
+ # format with trusted input.
40
51
  def load filepath, serializer = nil
41
52
  serializer ||= serializers.resolve filepath
42
53
  root = serializer.load filepath
@@ -45,7 +56,10 @@ module Rambling
45
56
  end
46
57
  end
47
58
 
48
- # Dumps an existing trie from memory into disk.
59
+ # Dumps an existing trie from memory into disk. By default, it will
60
+ # deduce the correct way to serialize based on the file extension.
61
+ # Available formats are `yml`, `marshal`, and `zip` versions of all the
62
+ # previous formats. You can also define your own.
49
63
  # @param [Container] trie the trie to dump into disk.
50
64
  # @param [String] filepath the file to dump to serialized trie into.
51
65
  # @param [Serializer, nil] serializer the object responsible of
@@ -57,8 +71,10 @@ module Rambling
57
71
  end
58
72
 
59
73
  # Provides configuration properties for the Rambling::Trie gem.
60
- # @return [Configuration::Properties] the configured properties of the gem.
61
- # @yield [Configuration::Properties] the configured properties of the gem.
74
+ # @return [Configuration::Properties] the configured properties of the
75
+ # gem.
76
+ # @yield [Configuration::Properties] the configured properties of the
77
+ # gem.
62
78
  def config
63
79
  yield properties if block_given?
64
80
  properties
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Provides the comparable behavior for the trie data structure.
@@ -5,7 +7,8 @@ module Rambling
5
7
  # Compares two nodes.
6
8
  # @param [Nodes::Node] other the node to compare against.
7
9
  # @return [Boolean] `true` if the nodes' {Nodes::Node#letter #letter} and
8
- # {Nodes::Node#children_tree #children_tree} are equal, `false` otherwise.
10
+ # {Nodes::Node#children_tree #children_tree} are equal, `false`
11
+ # otherwise.
9
12
  def == other
10
13
  letter == other.letter &&
11
14
  terminal? == other.terminal? &&
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Provides the compressible behavior for the trie data structure.
4
6
  module Compressible
5
- # Indicates if the current {Rambling::Trie::Nodes::Node Node} can be compressed
6
- # or not.
7
- # @return [Boolean] `true` for non-{Nodes::Node#terminal? terminal} nodes with
8
- # one child, `false` otherwise.
7
+ # Indicates if the current {Rambling::Trie::Nodes::Node Node} can be
8
+ # compressed or not.
9
+ # @return [Boolean] `true` for non-{Nodes::Node#terminal? terminal} nodes
10
+ # with one child, `false` otherwise.
9
11
  def compressible?
10
12
  !(root? || terminal?) && children_tree.size == 1
11
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Responsible for the compression process of a trie data structure.
@@ -26,7 +28,7 @@ module Rambling
26
28
  letter.to_sym,
27
29
  node.parent,
28
30
  other.children_tree,
29
- other.terminal?
31
+ other.terminal?,
30
32
  )
31
33
  end
32
34
 
@@ -35,26 +37,26 @@ module Rambling
35
37
  node.letter,
36
38
  node.parent,
37
39
  compress_children(node.children_tree),
38
- node.terminal?
40
+ node.terminal?,
39
41
  )
40
42
  end
41
43
 
42
- def compress_children children_tree
43
- new_children_tree = {}
44
+ def compress_children tree
45
+ new_tree = {}
44
46
 
45
- children_tree.each_value do |child|
47
+ tree.each do |letter, child|
46
48
  compressed_child = compress child
47
- new_children_tree[compressed_child.letter] = compressed_child
49
+ new_tree[letter] = compressed_child
48
50
  end
49
51
 
50
- new_children_tree
52
+ new_tree
51
53
  end
52
54
 
53
- def new_compressed_node letter, parent, children_tree, terminal
54
- node = Rambling::Trie::Nodes::Compressed.new letter, parent, children_tree
55
+ def new_compressed_node letter, parent, tree, terminal
56
+ node = Rambling::Trie::Nodes::Compressed.new letter, parent, tree
55
57
  node.terminal! if terminal
56
58
 
57
- children_tree.each_value { |child| child.parent = node }
59
+ tree.each_value { |child| child.parent = node }
58
60
  node
59
61
  end
60
62
  end
@@ -1,4 +1,6 @@
1
- %w{properties provider_collection}.each do |file|
1
+ # frozen_string_literal: true
2
+
3
+ %w(properties provider_collection).each do |file|
2
4
  require File.join('rambling', 'trie', 'configuration', file)
3
5
  end
4
6
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Configuration
@@ -17,8 +19,8 @@ module Rambling
17
19
  # @return [Compressor] the configured compressor.
18
20
  attr_accessor :compressor
19
21
 
20
- # The configured root_builder, which should return a {Nodes::Node Node} when
21
- # called.
22
+ # The configured root_builder, which should return a {Nodes::Node Node}
23
+ # when called.
22
24
  # @return [Proc<Nodes::Node>] the configured root_builder.
23
25
  attr_accessor :root_builder
24
26
 
@@ -36,9 +38,9 @@ module Rambling
36
38
  reset_readers
37
39
  reset_serializers
38
40
 
39
- self.compressor = Rambling::Trie::Compressor.new
40
- self.root_builder = lambda { Rambling::Trie::Nodes::Raw.new }
41
- self.tmp_path = '/tmp'
41
+ @compressor = Rambling::Trie::Compressor.new
42
+ @root_builder = -> { Rambling::Trie::Nodes::Raw.new }
43
+ @tmp_path = '/tmp'
42
44
  end
43
45
 
44
46
  private
@@ -48,7 +50,10 @@ module Rambling
48
50
  def reset_readers
49
51
  plain_text_reader = Rambling::Trie::Readers::PlainText.new
50
52
 
51
- self.readers = Rambling::Trie::Configuration::ProviderCollection.new :reader, txt: plain_text_reader
53
+ @readers = Rambling::Trie::Configuration::ProviderCollection.new(
54
+ :reader,
55
+ txt: plain_text_reader,
56
+ )
52
57
  end
53
58
 
54
59
  def reset_serializers
@@ -56,11 +61,13 @@ module Rambling
56
61
  yaml_serializer = Rambling::Trie::Serializers::Yaml.new
57
62
  zip_serializer = Rambling::Trie::Serializers::Zip.new self
58
63
 
59
- self.serializers = Rambling::Trie::Configuration::ProviderCollection.new :serializer,
64
+ @serializers = Rambling::Trie::Configuration::ProviderCollection.new(
65
+ :serializer,
60
66
  marshal: marshal_serializer,
61
67
  yml: yaml_serializer,
62
68
  yaml: yaml_serializer,
63
- zip: zip_serializer
69
+ zip: zip_serializer,
70
+ )
64
71
  end
65
72
  end
66
73
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Configuration
@@ -44,7 +46,8 @@ module Rambling
44
46
 
45
47
  def default= provider
46
48
  unless contains? provider
47
- raise ArgumentError, "default #{name} should be part of configured #{name}s"
49
+ raise ArgumentError,
50
+ "default #{name} should be part of configured #{name}s"
48
51
  end
49
52
 
50
53
  @default = provider
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Wrapper on top of trie data structure.
@@ -175,9 +177,9 @@ module Rambling
175
177
  # Check if a letter is part of the root {Nodes::Node}'s children tree.
176
178
  # @param [Symbol] letter the letter to search for in the root node.
177
179
  # @return [Boolean] whether the letter is contained or not.
178
- # @see Nodes::Node#has_key?
179
- def has_key? letter
180
- root.has_key? letter
180
+ # @see Nodes::Node#key?
181
+ def key? letter
182
+ root.key? letter
181
183
  end
182
184
 
183
185
  # Size of the Root {Nodes::Node Node}'s children tree.
@@ -186,47 +188,12 @@ module Rambling
186
188
  root.size
187
189
  end
188
190
 
189
- # String representation of the current node, if it is a terminal node.
190
- # @return [String] the string representation of the current node.
191
- # @raise [InvalidOperation] if node is not terminal or is root.
192
- # @deprecated This will always raise an {InvalidOperation} exception.
193
- def as_word
194
- warn '[DEPRECATION WARNING] `#as_word` is deprecated. Please use `#root#as_word` instead.'
195
- root.as_word
196
- end
197
-
198
- # Root {Nodes::Node Node}'s letter.
199
- # @return [Symbol] the root node's letter
200
- # @see Nodes::Node#letter
201
- # @deprecated This will always return `nil`.
202
- def letter
203
- warn '[DEPRECATION WARNING] `#letter` is deprecated. Please use `#root#letter` instead.'
204
- root.letter
205
- end
206
-
207
- # Root {Nodes::Node Node}'s parent.
208
- # @return [Symbol] the root node's parent
209
- # @see Nodes::Node#parent
210
- # @deprecated This will always return `nil`.
211
- def parent
212
- warn '[DEPRECATION WARNING] `#parent` is deprecated. Please use `#root#parent` instead.'
213
- root.parent
214
- end
215
-
216
- # String representation of root {Nodes::Node Node}.
217
- # @return [String] the root node's string representation.
218
- # @see Stringifyable#to_s
219
- # @deprecated This will always return an empty string (`''`).
220
- def to_s
221
- warn '[DEPRECATION WARNING] `#to_s` is deprecated. Please use `#root#to_s` instead.'
222
- root.to_s
223
- end
224
-
225
191
  alias_method :include?, :word?
226
192
  alias_method :match?, :partial_word?
227
193
  alias_method :words, :scan
228
194
  alias_method :<<, :add
229
- alias_method :has_letter?, :has_key?
195
+ alias_method :has_key?, :key?
196
+ alias_method :has_letter?, :key?
230
197
 
231
198
  private
232
199
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Provides enumerable behavior to the trie data structure.