from core.global_symbols import NotFound class FastCache: """ Simplest LRU cache """ def __init__(self, max_size=256, default=None): self.max_size = max_size self.cache = {} self.lru = [] self.default = default self.calls = {} def __contains__(self, item): return self.has(item) def __iter__(self): yield from self.cache def __next__(self): return next(iter(self.cache)) def __len__(self): return len(self.cache) def put(self, key, value): if len(self.cache) == self.max_size: del self.cache[self.lru.pop(0)] if key in self.cache: self.lru.remove(key) self.cache[key] = value self.lru.append(key) self.calls[key] = 0 def has(self, key): return key in self.cache def get(self, key): try: res = self.cache[key] self.calls[key] += 1 return res except KeyError: if self.default: value = self.default(key) self.put(key, value) return value return NotFound def evict_by_key(self, predicate): to_remove = [] for k, v in self.cache.items(): if predicate(k): to_remove.append(k) for k in to_remove: self.lru.remove(k) del self.cache[k] def copy(self): return self.cache.copy() def clear(self): self.cache.clear() self.lru.clear()