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