A simple LRU Cache implementation.
| 304 | |
| 305 | |
| 306 | class LRUCache(object): |
| 307 | """A simple LRU Cache implementation.""" |
| 308 | |
| 309 | # this is fast for small capacities (something below 1000) but doesn't |
| 310 | # scale. But as long as it's only used as storage for templates this |
| 311 | # won't do any harm. |
| 312 | |
| 313 | def __init__(self, capacity): |
| 314 | self.capacity = capacity |
| 315 | self._mapping = {} |
| 316 | self._queue = deque() |
| 317 | self._postinit() |
| 318 | |
| 319 | def _postinit(self): |
| 320 | # alias all queue methods for faster lookup |
| 321 | self._popleft = self._queue.popleft |
| 322 | self._pop = self._queue.pop |
| 323 | self._remove = self._queue.remove |
| 324 | self._wlock = Lock() |
| 325 | self._append = self._queue.append |
| 326 | |
| 327 | def __getstate__(self): |
| 328 | return { |
| 329 | 'capacity': self.capacity, |
| 330 | '_mapping': self._mapping, |
| 331 | '_queue': self._queue |
| 332 | } |
| 333 | |
| 334 | def __setstate__(self, d): |
| 335 | self.__dict__.update(d) |
| 336 | self._postinit() |
| 337 | |
| 338 | def __getnewargs__(self): |
| 339 | return (self.capacity,) |
| 340 | |
| 341 | def copy(self): |
| 342 | """Return a shallow copy of the instance.""" |
| 343 | rv = self.__class__(self.capacity) |
| 344 | rv._mapping.update(self._mapping) |
| 345 | rv._queue = deque(self._queue) |
| 346 | return rv |
| 347 | |
| 348 | def get(self, key, default=None): |
| 349 | """Return an item from the cache dict or `default`""" |
| 350 | try: |
| 351 | return self[key] |
| 352 | except KeyError: |
| 353 | return default |
| 354 | |
| 355 | def setdefault(self, key, default=None): |
| 356 | """Set `default` if the key is not in the cache otherwise |
| 357 | leave unchanged. Return the value of this key. |
| 358 | """ |
| 359 | self._wlock.acquire() |
| 360 | try: |
| 361 | try: |
| 362 | return self[key] |
| 363 | except KeyError: |
no outgoing calls
no test coverage detected
searching dependent graphs…