lib/lru_redux/cache.rb in lru_redux-0.0.2 vs lib/lru_redux/cache.rb in lru_redux-0.0.3

- old
+ new

@@ -1,42 +1,50 @@ class LruRedux::Cache # for high efficiency nodes in double linked list are stored in arrays # [prev,key,val,next] + # + # This makes this much more annoying to code, but gives us a 5-10% edge def initialize(max_size) @max_size = max_size @data = {} @head = nil @tail = nil end + def max_size=(size) + @max_size = size + while pop_tail + end + end + def [](key) node = @data[key] if node move_to_head(node) - node.value + node[2] end end def []=(key,val) node = @data[key] if node move_to_head(node) - node.value = val + node[2] = val else pop_tail @data[key] = add_to_head(key,val) end val end def each if n = @head while n - yield [n.key, n.value] - n = n.prev + yield [n[1], n[2]] + n = n[0] end end end # used further up the chain, non thread safe each @@ -52,15 +60,15 @@ def delete(k) node = @data[k] if node @data.delete(k) - prev = node.prev - nex = node.next + prev = node[0] + nex = node[3] - prev.next = nex if prev - nex.prev = prev if nex + prev[3] = nex if prev + nex[0] = prev if nex end end def clear @data.clear @@ -72,62 +80,55 @@ end # for cache validation only, ensures all is sound def valid? expected = {} + + count = 0 self.each_unsafe do |k,v| - expected[k] = v + return false if @data[k][2] != v + count += 1 end - expected == @data + count == @data.count end protected def add_to_head(key,val) if @head.nil? - @tail = @head = Node.new(key,val,nil,nil) + @tail = @head = [nil,key,val,nil] else - node = Node.new(key,val,@head,nil) - @head = @head.next = node + node = [@head,key,val,nil] + @head = @head[3] = node end end def move_to_head(node) - return unless @head && node != @head + return unless @head && node[1] != @head[1] - prev = node.prev - nex = node.next + prev = node[0] + nex = node[3] if prev - prev.next = nex + prev[3] = nex else @tail = nex end if nex - nex.prev = prev + nex[0] = prev end - @head.next = node - node.prev = @head + @head[3] = node + node[0] = @head @head = node end def pop_tail - if @data.length == @max_size - @data.delete(@tail.key) - @tail = @tail.next - @tail.prev = nil + if @data.length >= @max_size + @data.delete(@tail[1]) + @tail = @tail[3] + @tail[0] = nil end end - - class Node - attr_accessor :key, :value, :next, :prev - def initialize(key,value,prev,nex) - self.key = key - self.value = value - self.prev = prev - self.next = nex - end - end end