class Rufus::Lru::Hash


use Rufus::Lru::SynchronizedHash.
Nota bene: this class is not thread-safe. If you need something thread-safe,
# or h.clear_value_on_removal=true after h is created
h = LruHash.new(33, does_not_matter, true)
key-value removal
If a value has destructor method #clear it may be called upon the
h.squeeze!
.
.
# or h.squeeze_on_demand=true after h is created
h = LruHash.new(3, true)
One may want to squeeze hash manually
puts h.inspect # >> {:newer=>“b”, 3=>“aaa”, 4=>“aaaa”}
= “b”
puts h.inspect # >> {2=>“aa”, 3=>“aaa”, 4=>“aaaa”}
5.times { |i| h = “a” * i }
h = LruHash.new(3)
require ‘rufus/lru’
require ‘rubygems’
room for the new entries.
least recently used entries (LRU hence), will be discared to make
A Hash that has a max size. After the maxsize has been reached, the

def [](key)

def [](key)
  return nil unless has_key?(key)
  touch(key)
  super
end

def []=(key, value)

def []=(key, value)
  super
  touch(key)
  do_squeeze! if @auto_squeeze
end

def auto_squeeze=(b)

def auto_squeeze=(b)
  squeeze! if (@auto_squeeze = b)
end

def auto_squeeze?

def auto_squeeze?
  @auto_squeeze
end

def call_on_removal(value)

def call_on_removal(value)
  if ! @on_removal
    # nothing to do
  elsif @on_removal.is_a?(Symbol)
    value.send(@on_removal)
  else # must be a block
    @on_removal.call(value)
  end
end

def clear

def clear
  @lru_keys.clear
  self.each_value { |v| call_on_removal(v) }
  super
end

def delete(key)

def delete(key)
  value = super
  call_on_removal(value)
  @lru_keys.delete(key)
  value
end

def do_squeeze!


the least recently used items.
Makes sure that the hash fits its maxsize. If not, will remove
def do_squeeze!
  while size > @maxsize
    delete(@lru_keys.shift)
  end
end

def initialize(maxsize, opts={})


value as argument) each time a removal occurs
* A lambda/proc can be set, it's thus called (and passed the removed
that has to be called on the value just removed
* A symbol can be used to point to a method like :clear or :destroy
* False is the default, values are removed, nothing special happens.
accepts false, a symbol or a lambda.
* :on_removal
defaults to true
* :auto_squeeze

Options:

Initializes a LruHash with a given maxsize.
def initialize(maxsize, opts={})
  fail ArgumentError.new("maxsize must be >= 0") if maxsize < 0
  super()
  @maxsize = maxsize
  @lru_keys = []
  @auto_squeeze = opts.has_key?(:auto_squeeze) ? opts[:auto_squeeze] : true
  @on_removal = opts[:on_removal]
end

def maxsize=(i)

def maxsize=(i)
  @maxsize = i
  squeeze! if @auto_squeeze
  i
end

def merge!(hash)

def merge!(hash)
  hash.each { |k, v| self[k] = v }
  # not using 'super', but in order not guaranteed at all...
end

def squeeze!; do_squeeze!; end

def squeeze!; do_squeeze!; end

def to_h


Returns a regular Hash with the entries in this hash.
def to_h
  {}.merge!(self)
end

def touch(key)


The bottom being the lru place.
Puts the key on top of the lru 'stack'.
def touch(key)
  @lru_keys.delete(key)
  @lru_keys << key
end