Skip to content

Instantly share code, notes, and snippets.

@travisofthenorth
Last active August 29, 2015 14:19
Show Gist options
  • Save travisofthenorth/b00c21821b45300953de to your computer and use it in GitHub Desktop.
Save travisofthenorth/b00c21821b45300953de to your computer and use it in GitHub Desktop.
A quick-and-dirty LRU Cache in ruby
class ListEntry
attr_accessor :next, :prev, :data
def initialize(data)
@next = nil
@prev = nil
@data = data
end
end
class List
include Enumerable
def initialize
@head = nil
@tail = nil
end
# Always insert new head
def insert(data)
entry = ListEntry.new(data)
entry.next = @head
@head.prev = entry if @head != nil
@head = entry
@tail = entry if @tail == nil
entry
end
# Move to the top
def bump(entry)
return if @head == entry
@tail = entry.prev if @tail == entry
entry.prev.next = entry.next if entry.prev != nil
entry.next.prev = entry.prev if entry.next != nil
entry.prev = nil
entry.next = @head
@head.prev = entry
@head = entry
end
# Delete the tail
def delete
old_tail = @tail
@tail = @tail.prev
@tail.next = nil
old_tail
end
def each
i = @head
while i != nil
yield i
i = i.next
end
end
def print
i = @head
while i != nil
puts i.data
i = i.next
end
end
end
class CacheEntry
attr_accessor :value, :list_entry
def initialize
@value = nil
@list_entry = nil
end
end
class Cache
def initialize(max_size)
@cache = {}
@keys = List.new
@max_size = max_size
end
def set_value(key, val)
entry = @cache[key] ||= CacheEntry.new
entry.value = val
if entry.list_entry != nil
@keys.bump(entry.list_entry)
else
tail = @keys.delete if @cache.size > @max_size + 1
@cache.delete(tail.data) if tail != nil
entry.list_entry = @keys.insert(key)
end
end
def get_value(key)
@cache[key].value
end
def print
puts "-- Debug -- Printing Cache --"
@cache.each do |key, entry|
puts "#{key}: #{entry.value}"
end
puts "-- Debug -- Printing List ---"
@keys.print
puts "-----------------------------"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment