A simple LRU Cache implementation.
| 430 | |
| 431 | @abc.MutableMapping.register |
| 432 | class LRUCache: |
| 433 | """A simple LRU Cache implementation.""" |
| 434 | |
| 435 | # this is fast for small capacities (something below 1000) but doesn't |
| 436 | # scale. But as long as it's only used as storage for templates this |
| 437 | # won't do any harm. |
| 438 | |
| 439 | def __init__(self, capacity: int) -> None: |
| 440 | self.capacity = capacity |
| 441 | self._mapping: t.Dict[t.Any, t.Any] = {} |
| 442 | self._queue: te.Deque[t.Any] = deque() |
| 443 | self._postinit() |
| 444 | |
| 445 | def _postinit(self) -> None: |
| 446 | # alias all queue methods for faster lookup |
| 447 | self._popleft = self._queue.popleft |
| 448 | self._pop = self._queue.pop |
| 449 | self._remove = self._queue.remove |
| 450 | self._wlock = Lock() |
| 451 | self._append = self._queue.append |
| 452 | |
| 453 | def __getstate__(self) -> t.Mapping[str, t.Any]: |
| 454 | return { |
| 455 | "capacity": self.capacity, |
| 456 | "_mapping": self._mapping, |
| 457 | "_queue": self._queue, |
| 458 | } |
| 459 | |
| 460 | def __setstate__(self, d: t.Mapping[str, t.Any]) -> None: |
| 461 | self.__dict__.update(d) |
| 462 | self._postinit() |
| 463 | |
| 464 | def __getnewargs__(self) -> t.Tuple[t.Any, ...]: |
| 465 | return (self.capacity,) |
| 466 | |
| 467 | def copy(self) -> "te.Self": |
| 468 | """Return a shallow copy of the instance.""" |
| 469 | rv = self.__class__(self.capacity) |
| 470 | rv._mapping.update(self._mapping) |
| 471 | rv._queue.extend(self._queue) |
| 472 | return rv |
| 473 | |
| 474 | def get(self, key: t.Any, default: t.Any = None) -> t.Any: |
| 475 | """Return an item from the cache dict or `default`""" |
| 476 | try: |
| 477 | return self[key] |
| 478 | except KeyError: |
| 479 | return default |
| 480 | |
| 481 | def setdefault(self, key: t.Any, default: t.Any = None) -> t.Any: |
| 482 | """Set `default` if the key is not in the cache otherwise |
| 483 | leave unchanged. Return the value of this key. |
| 484 | """ |
| 485 | try: |
| 486 | return self[key] |
| 487 | except KeyError: |
| 488 | self[key] = default |
| 489 | return default |
no outgoing calls