class Oga::LRU

Thread-safe LRU cache using a Hash as the underlying storage engine. Whenever the size of the cache exceeds the given limit the oldest keys are removed (base on insert order).

This class uses its own list of keys (as returned by {LRU#keys}) instead of relying on ‘Hash#keys` as the latter allocates a new Array upon every call.

This class doesn’t use MonitorMixin due to the extra overhead it adds compared to using a Mutex directly.

Example usage:

cache = LRU.new(3)

cache[:a] = 10
cache[:b] = 20
cache[:c] = 30
cache[:d] = 40

cache.keys # => [:b, :c, :d]

@api private

Public Class Methods

new(maximum = 1024) click to toggle source

@param [Fixnum] maximum

# File lib/oga/lru.rb, line 26
def initialize(maximum = 1024)
  @maximum = maximum
  @cache   = {}
  @keys    = []
  @mutex   = Mutex.new
  @owner   = Thread.current
end

Public Instance Methods

[](key) click to toggle source

Returns the value of the key.

@param [Mixed] key @return [Mixed]

# File lib/oga/lru.rb, line 52
def [](key)
  synchronize { @cache[key] }
end
[]=(key, value) click to toggle source

Sets the key and its value. Old keys are discarded if the LRU size exceeds the limit.

@param [Mixed] key @param [Mixed] value

# File lib/oga/lru.rb, line 61
def []=(key, value)
  synchronize do
    @cache[key] = value

    @keys.delete(key) if @keys.include?(key)

    @keys << key

    resize
  end
end
clear() click to toggle source

Removes all keys from the cache.

# File lib/oga/lru.rb, line 94
def clear
  synchronize do
    @keys.clear
    @cache.clear
  end
end
get_or_set(key) { || ... } click to toggle source

Returns a key if it exists, otherwise yields the supplied block and uses its return value as the key value.

@param [Mixed] key @return [Mixed]

# File lib/oga/lru.rb, line 78
def get_or_set(key)
  synchronize { self[key] ||= yield }
end
key?(key) click to toggle source

@param [Mixed] key @return [TrueClass|FalseClass]

# File lib/oga/lru.rb, line 89
def key?(key)
  synchronize { @cache.key?(key) }
end
keys() click to toggle source

@return [Array]

# File lib/oga/lru.rb, line 83
def keys
  synchronize { @keys }
end
length()
Alias for: size
maximum() click to toggle source

@return [Fixnum]

# File lib/oga/lru.rb, line 44
def maximum
  synchronize { @maximum }
end
maximum=(value) click to toggle source

@param [Fixnum] value

# File lib/oga/lru.rb, line 35
def maximum=(value)
  synchronize do
    @maximum = value

    resize
  end
end
size() click to toggle source

@return [Fixnum]

# File lib/oga/lru.rb, line 102
def size
  synchronize { @cache.size }
end
Also aliased as: length

Private Instance Methods

resize() click to toggle source

Removes old keys until the size of the hash no longer exceeds the maximum size.

# File lib/oga/lru.rb, line 128
def resize
  return unless size > @maximum

  to_remove = @keys.shift(size - @maximum)

  to_remove.each { |key| @cache.delete(key) }
end
synchronize() { || ... } click to toggle source

Yields the supplied block in a synchronized manner (if needed). This method is heavily based on ‘MonitorMixin#mon_enter`.

# File lib/oga/lru.rb, line 112
def synchronize
  if @owner != Thread.current
    @mutex.synchronize do
      @owner = Thread.current
      retval = yield
      @owner = nil

      retval
    end
  else
    yield
  end
end