Files
fastapi-cache/fastapi_cache/backends/inmemory.py
Martijn Pieters 23d439f83a Make backends store bytes instead of strings
This is, for the majority of backends, the native format anyway, and so
we save encoding and decoding when using the PickleCodec or if (in future)
a orjson Coder was to be added.

For the JsonCodec, the only thing that changed is the location where the
JSON data is encoded to bytes and decoded back again to a string.
2023-05-10 17:35:15 +01:00

62 lines
1.6 KiB
Python

import time
from asyncio import Lock
from dataclasses import dataclass
from typing import Dict, Optional, Tuple
from fastapi_cache.backends import Backend
@dataclass
class Value:
data: bytes
ttl_ts: int
class InMemoryBackend(Backend):
_store: Dict[str, Value] = {}
_lock = Lock()
@property
def _now(self) -> int:
return int(time.time())
def _get(self, key: str) -> Optional[Value]:
v = self._store.get(key)
if v:
if v.ttl_ts < self._now:
del self._store[key]
else:
return v
return None
async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]:
async with self._lock:
v = self._get(key)
if v:
return v.ttl_ts - self._now, v.data
return 0, None
async def get(self, key: str) -> Optional[bytes]:
async with self._lock:
v = self._get(key)
if v:
return v.data
return None
async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None:
async with self._lock:
self._store[key] = Value(value, self._now + (expire or 0))
async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int:
count = 0
if namespace:
keys = list(self._store.keys())
for key in keys:
if key.startswith(namespace):
del self._store[key]
count += 1
elif key:
del self._store[key]
count += 1
return count