rambling-trie 1.0.2 → 2.2.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.
- checksums.yaml +5 -5
- data/Gemfile +6 -3
- data/Guardfile +3 -1
- data/README.md +30 -12
- data/Rakefile +8 -0
- data/lib/rambling-trie.rb +2 -0
- data/lib/rambling/trie.rb +48 -26
- data/lib/rambling/trie/comparable.rb +6 -3
- data/lib/rambling/trie/compressible.rb +16 -0
- data/lib/rambling/trie/compressor.rb +39 -24
- data/lib/rambling/trie/configuration.rb +3 -1
- data/lib/rambling/trie/configuration/properties.rb +18 -9
- data/lib/rambling/trie/configuration/provider_collection.rb +38 -17
- data/lib/rambling/trie/container.rb +123 -36
- data/lib/rambling/trie/enumerable.rb +6 -4
- data/lib/rambling/trie/inspectable.rb +2 -0
- data/lib/rambling/trie/invalid_operation.rb +3 -1
- data/lib/rambling/trie/nodes.rb +13 -0
- data/lib/rambling/trie/nodes/compressed.rb +98 -0
- data/lib/rambling/trie/nodes/missing.rb +12 -0
- data/lib/rambling/trie/nodes/node.rb +183 -0
- data/lib/rambling/trie/nodes/raw.rb +82 -0
- data/lib/rambling/trie/readers.rb +3 -1
- data/lib/rambling/trie/readers/plain_text.rb +3 -11
- data/lib/rambling/trie/serializers.rb +3 -1
- data/lib/rambling/trie/serializers/file.rb +2 -0
- data/lib/rambling/trie/serializers/marshal.rb +15 -5
- data/lib/rambling/trie/serializers/yaml.rb +21 -5
- data/lib/rambling/trie/serializers/zip.rb +15 -8
- data/lib/rambling/trie/stringifyable.rb +8 -2
- data/lib/rambling/trie/version.rb +3 -1
- data/rambling-trie.gemspec +21 -10
- data/spec/assets/test_words.es_DO.txt +1 -0
- data/spec/integration/rambling/trie_spec.rb +44 -35
- data/spec/lib/rambling/trie/comparable_spec.rb +8 -15
- data/spec/lib/rambling/trie/compressor_spec.rb +90 -13
- data/spec/lib/rambling/trie/configuration/properties_spec.rb +21 -13
- data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +18 -34
- data/spec/lib/rambling/trie/container_spec.rb +183 -217
- data/spec/lib/rambling/trie/enumerable_spec.rb +14 -9
- data/spec/lib/rambling/trie/inspectable_spec.rb +36 -11
- data/spec/lib/rambling/trie/nodes/compressed_spec.rb +37 -0
- data/spec/lib/rambling/trie/nodes/node_spec.rb +9 -0
- data/spec/lib/rambling/trie/nodes/raw_spec.rb +179 -0
- data/spec/lib/rambling/trie/readers/plain_text_spec.rb +3 -1
- data/spec/lib/rambling/trie/serializers/file_spec.rb +6 -4
- data/spec/lib/rambling/trie/serializers/marshal_spec.rb +5 -7
- data/spec/lib/rambling/trie/serializers/yaml_spec.rb +5 -7
- data/spec/lib/rambling/trie/serializers/zip_spec.rb +18 -20
- data/spec/lib/rambling/trie/stringifyable_spec.rb +14 -11
- data/spec/lib/rambling/trie_spec.rb +18 -11
- data/spec/spec_helper.rb +10 -5
- data/spec/support/config.rb +10 -0
- data/spec/support/helpers/add_word.rb +20 -0
- data/spec/support/helpers/one_line_heredoc.rb +11 -0
- data/spec/support/shared_examples/a_compressible_trie.rb +40 -0
- data/spec/support/shared_examples/a_serializable_trie.rb +10 -6
- data/spec/support/shared_examples/a_serializer.rb +9 -1
- data/spec/support/shared_examples/a_trie_data_structure.rb +2 -0
- data/spec/support/shared_examples/a_trie_node.rb +127 -0
- data/spec/{lib/rambling/trie/compressed_node_spec.rb → support/shared_examples/a_trie_node_implementation.rb} +25 -72
- metadata +42 -31
- data/lib/rambling/trie/compressable.rb +0 -14
- data/lib/rambling/trie/compressed_node.rb +0 -120
- data/lib/rambling/trie/missing_node.rb +0 -8
- data/lib/rambling/trie/node.rb +0 -97
- data/lib/rambling/trie/raw_node.rb +0 -96
- data/spec/lib/rambling/trie/node_spec.rb +0 -86
- data/spec/lib/rambling/trie/raw_node_spec.rb +0 -389
- data/spec/support/shared_examples/a_compressable_trie.rb +0 -26
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 22f6c4caa5644231338f085b6beb904e184db2f50c96a4e29ae31f931c4f60d1
         | 
| 4 | 
            +
              data.tar.gz: 5ff102450e6d8eb15990f2a5c14bcb8b280b44c9b1460a2fdb5653bacf838a21
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: '08b1564034a74f0ac49b67bd449037207d9573e9dad78e5db0b59bdeb0f5b87edd7b046b472eb653f8cca30ded40c2ebe8c024d20aabea294d3bbc0b40e95a02'
         | 
| 7 | 
            +
              data.tar.gz: 414644eaa457ffde46cef1135fa211e31a529bb83d4ea27f25ae9810c2480e822729ce7c7907e87db08873a267d3da57a1f427bc4d28a992c6ebbea7a598df54
         | 
    
        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,18 +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'
         | 
| 12 | 
            +
              gem 'memory_profiler'
         | 
| 13 | 
            +
              gem 'pry'
         | 
| 14 | 
            +
              gem 'ruby-prof'
         | 
| 13 15 | 
             
              gem 'stackprof'
         | 
| 14 16 | 
             
            end
         | 
| 15 17 |  | 
| 16 18 | 
             
            group :test do
         | 
| 19 | 
            +
              gem 'coveralls', '~>0.8.21', require: false
         | 
| 17 20 | 
             
              gem 'simplecov', require: false
         | 
| 18 | 
            -
              gem 'coveralls', require: false
         | 
| 19 21 | 
             
            end
         | 
| 20 22 |  | 
| 21 23 | 
             
            group :local do
         | 
| 22 24 | 
             
              gem 'guard-rspec'
         | 
| 25 | 
            +
              gem 'rubocop', require: false
         | 
| 23 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')  {  | 
| 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] [![ | 
| 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. | 
| 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.
         | 
| @@ -75,6 +75,12 @@ trie.add 'word' | |
| 75 75 | 
             
            trie << 'word'
         | 
| 76 76 | 
             
            ```
         | 
| 77 77 |  | 
| 78 | 
            +
            Or if you have multiple words to add, you can use `#concat`:
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            ``` ruby
         | 
| 81 | 
            +
            trie.concat %w(a collection of words)
         | 
| 82 | 
            +
            ```
         | 
| 83 | 
            +
             | 
| 78 84 | 
             
            And to find out if a word already exists in the trie, use `#word?` or its alias `#include?`:
         | 
| 79 85 |  | 
| 80 86 | 
             
            ``` ruby
         | 
| @@ -121,13 +127,20 @@ trie.compress! | |
| 121 127 | 
             
            This will reduce the size of the trie by using redundant node elimination (redundant nodes are the only-child non-terminal nodes).
         | 
| 122 128 |  | 
| 123 129 | 
             
            > _**Note**: The `#compress!` method acts over the trie instance it belongs to
         | 
| 124 | 
            -
            > and  | 
| 130 | 
            +
            > and replaces the root `Node`. Also, adding words after compression (with `#add` or
         | 
| 125 131 | 
             
            > `#<<`) is not supported._
         | 
| 126 132 |  | 
| 127 | 
            -
             | 
| 133 | 
            +
            If you want, you can also create a new compressed trie and leave the existing one intact. Just use `#compress` instead:
         | 
| 134 | 
            +
             | 
| 135 | 
            +
            ``` ruby
         | 
| 136 | 
            +
            compressed_trie = trie.compress
         | 
| 137 | 
            +
            ```
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            You can find out if a trie instance is compressed by calling the `#compressed?` method. From the `#compress` example:
         | 
| 128 140 |  | 
| 129 141 | 
             
            ``` ruby
         | 
| 130 | 
            -
            trie.compressed?
         | 
| 142 | 
            +
            trie.compressed? # => false
         | 
| 143 | 
            +
            compressed_trie.compressed? # => true
         | 
| 131 144 | 
             
            ```
         | 
| 132 145 |  | 
| 133 146 | 
             
            ### Enumeration
         | 
| @@ -229,14 +242,17 @@ You can find further API documentation on the autogenerated [rambling-trie gem R | |
| 229 242 |  | 
| 230 243 | 
             
            The Rambling Trie has been tested with the following Ruby versions:
         | 
| 231 244 |  | 
| 232 | 
            -
            * 2. | 
| 233 | 
            -
            * 2. | 
| 234 | 
            -
            * 2. | 
| 245 | 
            +
            * 2.7.x
         | 
| 246 | 
            +
            * 2.6.x
         | 
| 247 | 
            +
            * 2.5.x
         | 
| 235 248 |  | 
| 236 249 | 
             
            **No longer supported**:
         | 
| 237 250 |  | 
| 238 | 
            -
            * 2. | 
| 239 | 
            -
            * 2. | 
| 251 | 
            +
            * 2.4.x (EOL'ed)
         | 
| 252 | 
            +
            * 2.3.x (EOL'ed)
         | 
| 253 | 
            +
            * 2.2.x
         | 
| 254 | 
            +
            * 2.1.x
         | 
| 255 | 
            +
            * 2.0.x
         | 
| 240 256 | 
             
            * 1.9.x
         | 
| 241 257 | 
             
            * 1.8.x
         | 
| 242 258 |  | 
| @@ -268,7 +284,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |
| 268 284 | 
             
            [github_user_gonzedge]: https://github.com/gonzedge
         | 
| 269 285 | 
             
            [inch_ci_badge]: https://inch-ci.org/github/gonzedge/rambling-trie.svg?branch=master
         | 
| 270 286 | 
             
            [inch_ci_link]: https://inch-ci.org/github/gonzedge/rambling-trie
         | 
| 271 | 
            -
            [ | 
| 287 | 
            +
            [license_badge]: https://badges.frapsoft.com/os/mit/mit.svg?v=103
         | 
| 288 | 
            +
            [license_link]: https://opensource.org/licenses/mit-license.php
         | 
| 289 | 
            +
            [marshal]: https://ruby-doc.org/core-2.5.0/Marshal.html
         | 
| 272 290 | 
             
            [rambling_trie_configuration]: https://github.com/gonzedge/rambling-trie#configuration
         | 
| 273 291 | 
             
            [rambling_trie_contributing_guide]: https://github.com/gonzedge/rambling-trie/blob/master/CONTRIBUTING.md
         | 
| 274 292 | 
             
            [rambling_trie_plain_text_reader]: https://github.com/gonzedge/rambling-trie/blob/master/lib/rambling/trie/readers/plain_text.rb
         | 
| @@ -280,4 +298,4 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI | |
| 280 298 | 
             
            [travis_ci_badge]: https://travis-ci.org/gonzedge/rambling-trie.svg
         | 
| 281 299 | 
             
            [travis_ci_link]: https://travis-ci.org/gonzedge/rambling-trie
         | 
| 282 300 | 
             
            [trie_wiki]: https://en.wikipedia.org/wiki/Trie
         | 
| 283 | 
            -
            [yaml]: https://ruby-doc.org/stdlib-2. | 
| 301 | 
            +
            [yaml]: https://ruby-doc.org/stdlib-2.5.0/libdoc/yaml/rdoc/YAML.html
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,7 +1,15 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'bundler/gem_tasks'
         | 
| 2 4 | 
             
            require 'rspec/core/rake_task'
         | 
| 5 | 
            +
            require 'rubocop/rake_task'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require 'rambling-trie'
         | 
| 3 8 | 
             
            require_relative 'tasks/performance'
         | 
| 9 | 
            +
            require_relative 'tasks/serialization'
         | 
| 10 | 
            +
            require_relative 'tasks/ips'
         | 
| 4 11 |  | 
| 5 12 | 
             
            RSpec::Core::RakeTask.new :spec
         | 
| 13 | 
            +
            RuboCop::RakeTask.new :rubocop
         | 
| 6 14 |  | 
| 7 15 | 
             
            task default: :spec
         | 
    
        data/lib/rambling-trie.rb
    CHANGED
    
    
    
        data/lib/rambling/trie.rb
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            %w | 
| 4 | 
            -
              comparable  | 
| 5 | 
            -
              inspectable invalid_operation readers serializers stringifyable  | 
| 6 | 
            -
               | 
| 7 | 
            -
             | 
| 3 | 
            +
            %w(
         | 
| 4 | 
            +
              comparable compressible compressor configuration container enumerable
         | 
| 5 | 
            +
              inspectable invalid_operation readers serializers stringifyable nodes
         | 
| 6 | 
            +
              version
         | 
| 7 | 
            +
            ).each do |file|
         | 
| 8 8 | 
             
              require File.join('rambling', 'trie', file)
         | 
| 9 9 | 
             
            end
         | 
| 10 10 |  | 
| @@ -13,23 +13,16 @@ module Rambling | |
| 13 13 | 
             
              # Entry point for rambling-trie API.
         | 
| 14 14 | 
             
              module Trie
         | 
| 15 15 | 
             
                class << self
         | 
| 16 | 
            -
                  extend ::Forwardable
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  delegate [
         | 
| 19 | 
            -
                    :readers,
         | 
| 20 | 
            -
                    :serializers,
         | 
| 21 | 
            -
                    :compressor,
         | 
| 22 | 
            -
                    :root_builder
         | 
| 23 | 
            -
                  ] => :properties
         | 
| 24 | 
            -
             | 
| 25 16 | 
             
                  # Creates a new Rambling::Trie. Entry point for the Rambling::Trie API.
         | 
| 26 17 | 
             
                  # @param [String, nil] filepath the file to load the words from.
         | 
| 27 | 
            -
                  # @param [Reader, nil] reader the file parser to get each word. | 
| 28 | 
            -
                  #   {Rambling::Trie::Readers Readers}.
         | 
| 18 | 
            +
                  # @param [Reader, nil] reader the file parser to get each word.
         | 
| 29 19 | 
             
                  # @return [Container] the trie just created.
         | 
| 30 20 | 
             
                  # @yield [Container] the trie just created.
         | 
| 21 | 
            +
                  # @see Rambling::Trie::Readers Readers.
         | 
| 31 22 | 
             
                  def create filepath = nil, reader = nil
         | 
| 32 | 
            -
                     | 
| 23 | 
            +
                    root = root_builder.call
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    Rambling::Trie::Container.new root, compressor do |container|
         | 
| 33 26 | 
             
                      if filepath
         | 
| 34 27 | 
             
                        reader ||= readers.resolve filepath
         | 
| 35 28 | 
             
                        reader.each_word filepath do |word|
         | 
| @@ -41,12 +34,20 @@ module Rambling | |
| 41 34 | 
             
                    end
         | 
| 42 35 | 
             
                  end
         | 
| 43 36 |  | 
| 44 | 
            -
                  # 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.
         | 
| 45 41 | 
             
                  # @param [String] filepath the file to load the words from.
         | 
| 46 | 
            -
                  # @param [Serializer, nil] serializer the object responsible of loading | 
| 47 | 
            -
                  #   from disk | 
| 42 | 
            +
                  # @param [Serializer, nil] serializer the object responsible of loading
         | 
| 43 | 
            +
                  #   the trie from disk
         | 
| 48 44 | 
             
                  # @return [Container] the trie just loaded.
         | 
| 49 45 | 
             
                  # @yield [Container] the trie just loaded.
         | 
| 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.
         | 
| 50 51 | 
             
                  def load filepath, serializer = nil
         | 
| 51 52 | 
             
                    serializer ||= serializers.resolve filepath
         | 
| 52 53 | 
             
                    root = serializer.load filepath
         | 
| @@ -55,20 +56,25 @@ module Rambling | |
| 55 56 | 
             
                    end
         | 
| 56 57 | 
             
                  end
         | 
| 57 58 |  | 
| 58 | 
            -
                  # 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.
         | 
| 59 63 | 
             
                  # @param [Container] trie the trie to dump into disk.
         | 
| 60 64 | 
             
                  # @param [String] filepath the file to dump to serialized trie into.
         | 
| 61 65 | 
             
                  # @param [Serializer, nil] serializer the object responsible of
         | 
| 62 | 
            -
                  #   serializing and dumping the trie into disk. | 
| 63 | 
            -
                  # | 
| 66 | 
            +
                  #   serializing and dumping the trie into disk.
         | 
| 67 | 
            +
                  # @see Rambling::Trie::Serializers Serializers.
         | 
| 64 68 | 
             
                  def dump trie, filepath, serializer = nil
         | 
| 65 69 | 
             
                    serializer ||= serializers.resolve filepath
         | 
| 66 70 | 
             
                    serializer.dump trie.root, filepath
         | 
| 67 71 | 
             
                  end
         | 
| 68 72 |  | 
| 69 73 | 
             
                  # Provides configuration properties for the Rambling::Trie gem.
         | 
| 70 | 
            -
                  # @return [Properties] the configured properties of the | 
| 71 | 
            -
                  # | 
| 74 | 
            +
                  # @return [Configuration::Properties] the configured properties of the
         | 
| 75 | 
            +
                  #   gem.
         | 
| 76 | 
            +
                  # @yield [Configuration::Properties] the configured properties of the
         | 
| 77 | 
            +
                  #   gem.
         | 
| 72 78 | 
             
                  def config
         | 
| 73 79 | 
             
                    yield properties if block_given?
         | 
| 74 80 | 
             
                    properties
         | 
| @@ -79,6 +85,22 @@ module Rambling | |
| 79 85 | 
             
                  def properties
         | 
| 80 86 | 
             
                    @properties ||= Rambling::Trie::Configuration::Properties.new
         | 
| 81 87 | 
             
                  end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  def readers
         | 
| 90 | 
            +
                    properties.readers
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  def serializers
         | 
| 94 | 
            +
                    properties.serializers
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  def compressor
         | 
| 98 | 
            +
                    properties.compressor
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  def root_builder
         | 
| 102 | 
            +
                    properties.root_builder
         | 
| 103 | 
            +
                  end
         | 
| 82 104 | 
             
                end
         | 
| 83 105 | 
             
              end
         | 
| 84 106 | 
             
            end
         | 
| @@ -1,11 +1,14 @@ | |
| 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.
         | 
| 4 6 | 
             
                module Comparable
         | 
| 5 7 | 
             
                  # Compares two nodes.
         | 
| 6 | 
            -
                  # @param [Node] other the node to compare against.
         | 
| 7 | 
            -
                  # @return [Boolean] `true` if the nodes' {Node#letter #letter} and
         | 
| 8 | 
            -
                  #   {Node#children_tree #children_tree} are equal, `false` | 
| 8 | 
            +
                  # @param [Nodes::Node] other the node to compare against.
         | 
| 9 | 
            +
                  # @return [Boolean] `true` if the nodes' {Nodes::Node#letter #letter} and
         | 
| 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? &&
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Rambling
         | 
| 4 | 
            +
              module Trie
         | 
| 5 | 
            +
                # Provides the compressible behavior for the trie data structure.
         | 
| 6 | 
            +
                module Compressible
         | 
| 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.
         | 
| 11 | 
            +
                  def compressible?
         | 
| 12 | 
            +
                    !(root? || terminal?) && children_tree.size == 1
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -1,48 +1,63 @@ | |
| 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.
         | 
| 4 6 | 
             
                class Compressor
         | 
| 5 | 
            -
                  # Compresses a {Node Node} from a trie data structure.
         | 
| 6 | 
            -
                  # @param [ | 
| 7 | 
            -
                  # @return [ | 
| 7 | 
            +
                  # Compresses a {Nodes::Node Node} from a trie data structure.
         | 
| 8 | 
            +
                  # @param [Nodes::Raw] node the node to compress.
         | 
| 9 | 
            +
                  # @return [Nodes::Compressed] node the compressed version of the node.
         | 
| 8 10 | 
             
                  def compress node
         | 
| 9 | 
            -
                    if node. | 
| 10 | 
            -
                       | 
| 11 | 
            +
                    if node.compressible?
         | 
| 12 | 
            +
                      compress_child_and_merge node
         | 
| 11 13 | 
             
                    else
         | 
| 12 | 
            -
                       | 
| 14 | 
            +
                      compress_children_and_copy node
         | 
| 13 15 | 
             
                    end
         | 
| 14 16 | 
             
                  end
         | 
| 15 17 |  | 
| 16 18 | 
             
                  private
         | 
| 17 19 |  | 
| 18 | 
            -
                  def  | 
| 19 | 
            -
                     | 
| 20 | 
            +
                  def compress_child_and_merge node
         | 
| 21 | 
            +
                    merge node, compress(node.first_child)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def merge node, other
         | 
| 25 | 
            +
                    letter = node.letter.to_s << other.letter.to_s
         | 
| 20 26 |  | 
| 21 | 
            -
                     | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 27 | 
            +
                    new_compressed_node(
         | 
| 28 | 
            +
                      letter.to_sym,
         | 
| 29 | 
            +
                      node.parent,
         | 
| 30 | 
            +
                      other.children_tree,
         | 
| 31 | 
            +
                      other.terminal?,
         | 
| 32 | 
            +
                    )
         | 
| 33 | 
            +
                  end
         | 
| 24 34 |  | 
| 25 | 
            -
             | 
| 35 | 
            +
                  def compress_children_and_copy node
         | 
| 36 | 
            +
                    new_compressed_node(
         | 
| 37 | 
            +
                      node.letter,
         | 
| 38 | 
            +
                      node.parent,
         | 
| 39 | 
            +
                      compress_children(node.children_tree),
         | 
| 40 | 
            +
                      node.terminal?,
         | 
| 41 | 
            +
                    )
         | 
| 26 42 | 
             
                  end
         | 
| 27 43 |  | 
| 28 | 
            -
                  def  | 
| 29 | 
            -
                     | 
| 44 | 
            +
                  def compress_children tree
         | 
| 45 | 
            +
                    new_tree = {}
         | 
| 30 46 |  | 
| 31 | 
            -
                     | 
| 47 | 
            +
                    tree.each do |letter, child|
         | 
| 32 48 | 
             
                      compressed_child = compress child
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                      compressed_child.parent = new_node
         | 
| 35 | 
            -
                      new_node[compressed_child.letter] = compressed_child
         | 
| 49 | 
            +
                      new_tree[letter] = compressed_child
         | 
| 36 50 | 
             
                    end
         | 
| 37 51 |  | 
| 38 | 
            -
                     | 
| 52 | 
            +
                    new_tree
         | 
| 39 53 | 
             
                  end
         | 
| 40 54 |  | 
| 41 | 
            -
                  def new_compressed_node  | 
| 42 | 
            -
                     | 
| 43 | 
            -
                     | 
| 44 | 
            -
             | 
| 45 | 
            -
                     | 
| 55 | 
            +
                  def new_compressed_node letter, parent, tree, terminal
         | 
| 56 | 
            +
                    node = Rambling::Trie::Nodes::Compressed.new letter, parent, tree
         | 
| 57 | 
            +
                    node.terminal! if terminal
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    tree.each_value { |child| child.parent = node }
         | 
| 60 | 
            +
                    node
         | 
| 46 61 | 
             
                  end
         | 
| 47 62 | 
             
                end
         | 
| 48 63 | 
             
              end
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Rambling
         | 
| 2 4 | 
             
              module Trie
         | 
| 3 5 | 
             
                module Configuration
         | 
| @@ -17,11 +19,13 @@ 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 {Node Node} | 
| 21 | 
            -
                    # called.
         | 
| 22 | 
            -
                    # @return [Proc<Node>] the configured root_builder.
         | 
| 22 | 
            +
                    # The configured root_builder, which should return a {Nodes::Node Node}
         | 
| 23 | 
            +
                    #   when called.
         | 
| 24 | 
            +
                    # @return [Proc<Nodes::Node>] the configured root_builder.
         | 
| 23 25 | 
             
                    attr_accessor :root_builder
         | 
| 24 26 |  | 
| 27 | 
            +
                    # The configured tmp_path, which will be used for throwaway files.
         | 
| 28 | 
            +
                    # @return [String] the configured tmp_path.
         | 
| 25 29 | 
             
                    attr_accessor :tmp_path
         | 
| 26 30 |  | 
| 27 31 | 
             
                    # Returns a new properties instance.
         | 
| @@ -34,9 +38,9 @@ module Rambling | |
| 34 38 | 
             
                      reset_readers
         | 
| 35 39 | 
             
                      reset_serializers
         | 
| 36 40 |  | 
| 37 | 
            -
                       | 
| 38 | 
            -
                       | 
| 39 | 
            -
                       | 
| 41 | 
            +
                      @compressor = Rambling::Trie::Compressor.new
         | 
| 42 | 
            +
                      @root_builder = -> { Rambling::Trie::Nodes::Raw.new }
         | 
| 43 | 
            +
                      @tmp_path = '/tmp'
         | 
| 40 44 | 
             
                    end
         | 
| 41 45 |  | 
| 42 46 | 
             
                    private
         | 
| @@ -46,7 +50,10 @@ module Rambling | |
| 46 50 | 
             
                    def reset_readers
         | 
| 47 51 | 
             
                      plain_text_reader = Rambling::Trie::Readers::PlainText.new
         | 
| 48 52 |  | 
| 49 | 
            -
                       | 
| 53 | 
            +
                      @readers = Rambling::Trie::Configuration::ProviderCollection.new(
         | 
| 54 | 
            +
                        :reader,
         | 
| 55 | 
            +
                        txt: plain_text_reader,
         | 
| 56 | 
            +
                      )
         | 
| 50 57 | 
             
                    end
         | 
| 51 58 |  | 
| 52 59 | 
             
                    def reset_serializers
         | 
| @@ -54,11 +61,13 @@ module Rambling | |
| 54 61 | 
             
                      yaml_serializer = Rambling::Trie::Serializers::Yaml.new
         | 
| 55 62 | 
             
                      zip_serializer = Rambling::Trie::Serializers::Zip.new self
         | 
| 56 63 |  | 
| 57 | 
            -
                       | 
| 64 | 
            +
                      @serializers = Rambling::Trie::Configuration::ProviderCollection.new(
         | 
| 65 | 
            +
                        :serializer,
         | 
| 58 66 | 
             
                        marshal: marshal_serializer,
         | 
| 59 67 | 
             
                        yml: yaml_serializer,
         | 
| 60 68 | 
             
                        yaml: yaml_serializer,
         | 
| 61 | 
            -
                        zip: zip_serializer
         | 
| 69 | 
            +
                        zip: zip_serializer,
         | 
| 70 | 
            +
                      )
         | 
| 62 71 | 
             
                    end
         | 
| 63 72 | 
             
                  end
         | 
| 64 73 | 
             
                end
         |