Sha256: dbc53f2955582e4ac6cf58874b350734aca5c55bfc68f97d60c0b3f9e209e354

Contents?: true

Size: 1.75 KB

Versions: 19

Compression:

Stored size: 1.75 KB

Contents

# frozen_string_literal: true

module JSI
  module Util::Private
    class MemoMap
      def initialize(key_by: nil, &block)
        @key_by = key_by
        @block = block || raise(ArgumentError, "no block given")

        # each result has its own mutex to update its memoized value thread-safely
        @result_mutexes = {}
        # another mutex to thread-safely initialize each result mutex
        @result_mutexes_mutex = Mutex.new

        @results = {}
      end

      def key_for(inputs)
        if @key_by
          @key_by.call(**inputs)
        else
          inputs
        end
      end
    end

    class MemoMap::Mutable < MemoMap
      Result = AttrStruct[*%w(
        value
        inputs
        inputs_hash
      )]

      class Result
      end

      def [](**inputs)
        key = key_for(inputs)

        result_mutex = @result_mutexes_mutex.synchronize do
          @result_mutexes[key] ||= Mutex.new
        end

        result_mutex.synchronize do
          inputs_hash = inputs.hash
          if @results.key?(key) && inputs_hash == @results[key].inputs_hash && inputs == @results[key].inputs
            @results[key].value
          else
            value = @block.call(**inputs)
            @results[key] = Result.new(value: value, inputs: inputs, inputs_hash: inputs_hash)
            value
          end
        end
      end
    end

    class MemoMap::Immutable < MemoMap
      def [](**inputs)
        key = key_for(inputs)

        result_mutex = @result_mutexes_mutex.synchronize do
          @result_mutexes[key] ||= Mutex.new
        end

        result_mutex.synchronize do
          if @results.key?(key)
            @results[key]
          else
            @results[key] = @block.call(**inputs)
          end
        end
      end
    end
  end
end

Version data entries

19 entries across 19 versions & 2 rubygems

Version Path
jsi-0.8.1 lib/jsi/util/private/memo_map.rb
jsi-0.8.0 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.4 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.5 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.6 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.7 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.8 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.8.pre.maruku lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.7.pre.rdiscount lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.6.pre.redcarpet lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.5.pre.kramdown lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.4.pre.commonmarker lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.0.pre.commonmarker lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.0.pre.kramdown lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.0.pre.redcarpet lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.0.pre.rdiscount lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.0.pre.maruku lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.3 lib/jsi/util/private/memo_map.rb
jsi-dev-0.0.2 lib/jsi/util/private/memo_map.rb