# vim:fileencoding=utf-8 # License: GPL v3 Copyright: 2017, Kovid Goyal from __python__ import hash_literals, bound_methods def lru_node(key, val): return {'key': key, 'val':val, 'prev':None, 'next':None} class LRUCache: def __init__(self, size): self.limit = 200 self.clear(size) def set_head(self, node): node.next = self.head node.prev = None if self.head is not None: self.head.prev = node self.head = node if self.tail is None: self.tail = node self.size += 1 self.map[node.key] = node def pop(self, key): node = self.map[key] if not node: return if node.prev is not None: node.prev.next = node.next else: self.head = node.next if node.next is not None: node.next.prev = node.prev else: self.tail = node.prev v'delete self.map[key]' self.size -= 1 def set(self, key, val): node = lru_node(key, val) existing = self.map[key] if existing: existing.value = node.value self.pop(node.key) elif self.size > self.limit: v'delete self.map[self.tail.key]' self.size -= 1 self.tail = self.tail.prev self.tail.next = None self.set_head(node) def get(self, key, defval): existing = self.map[key] if not existing: return None if defval is undefined else defval val = existing.value node = lru_node(key, val) self.pop(key) self.set_head(node) return val def clear(self, size): self.size = 0 self.map = {} self.head = self.tail = None if jstype(size) is 'number': self.limit = size