| 2478 | |
| 2479 | |
| 2480 | class _StatementCache: |
| 2481 | |
| 2482 | __slots__ = ('_loop', '_entries', '_max_size', '_on_remove', |
| 2483 | '_max_lifetime') |
| 2484 | |
| 2485 | def __init__(self, *, loop, max_size, on_remove, max_lifetime): |
| 2486 | self._loop = loop |
| 2487 | self._max_size = max_size |
| 2488 | self._on_remove = on_remove |
| 2489 | self._max_lifetime = max_lifetime |
| 2490 | |
| 2491 | # We use an OrderedDict for LRU implementation. Operations: |
| 2492 | # |
| 2493 | # * We use a simple `__setitem__` to push a new entry: |
| 2494 | # `entries[key] = new_entry` |
| 2495 | # That will push `new_entry` to the *end* of the entries dict. |
| 2496 | # |
| 2497 | # * When we have a cache hit, we call |
| 2498 | # `entries.move_to_end(key, last=True)` |
| 2499 | # to move the entry to the *end* of the entries dict. |
| 2500 | # |
| 2501 | # * When we need to remove entries to maintain `max_size`, we call |
| 2502 | # `entries.popitem(last=False)` |
| 2503 | # to remove an entry from the *beginning* of the entries dict. |
| 2504 | # |
| 2505 | # So new entries and hits are always promoted to the end of the |
| 2506 | # entries dict, whereas the unused one will group in the |
| 2507 | # beginning of it. |
| 2508 | self._entries = collections.OrderedDict() |
| 2509 | |
| 2510 | def __len__(self): |
| 2511 | return len(self._entries) |
| 2512 | |
| 2513 | def get_max_size(self): |
| 2514 | return self._max_size |
| 2515 | |
| 2516 | def set_max_size(self, new_size): |
| 2517 | assert new_size >= 0 |
| 2518 | self._max_size = new_size |
| 2519 | self._maybe_cleanup() |
| 2520 | |
| 2521 | def get_max_lifetime(self): |
| 2522 | return self._max_lifetime |
| 2523 | |
| 2524 | def set_max_lifetime(self, new_lifetime): |
| 2525 | assert new_lifetime >= 0 |
| 2526 | self._max_lifetime = new_lifetime |
| 2527 | for entry in self._entries.values(): |
| 2528 | # For every entry cancel the existing callback |
| 2529 | # and setup a new one if necessary. |
| 2530 | self._set_entry_timeout(entry) |
| 2531 | |
| 2532 | def get(self, query, *, promote=True): |
| 2533 | if not self._max_size: |
| 2534 | # The cache is disabled. |
| 2535 | return |
| 2536 | |
| 2537 | entry = self._entries.get(query) # type: _StatementCacheEntry |
no outgoing calls
no test coverage detected
searching dependent graphs…