|
|
import json |
|
|
import os |
|
|
import time |
|
|
from typing import Optional, Dict, Any |
|
|
|
|
|
|
|
|
class AnswersCache: |
|
|
def __init__(self, filename: str = "cache.json", max_size: int = 1000): |
|
|
self.filename = filename |
|
|
self.max_size = max_size |
|
|
self.cache: Dict[str, Dict[str, Any]] = {} |
|
|
self._load_cache() |
|
|
|
|
|
def _load_cache(self): |
|
|
"""Load cache from file if it exists""" |
|
|
if os.path.exists(self.filename): |
|
|
try: |
|
|
with open(self.filename, 'r') as f: |
|
|
self.cache = json.load(f) |
|
|
except (json.JSONDecodeError, FileNotFoundError): |
|
|
self.cache = {} |
|
|
|
|
|
def _save_cache(self): |
|
|
"""Save cache to file""" |
|
|
with open(self.filename, 'w') as f: |
|
|
json.dump(self.cache, f, indent=2) |
|
|
|
|
|
def set(self, key: str, value: str, ttl: Optional[int] = None): |
|
|
"""Set a key-value pair with optional TTL (time to live in seconds)""" |
|
|
if len(self.cache) >= self.max_size: |
|
|
self._evict_oldest() |
|
|
|
|
|
cache_entry = { |
|
|
'value': value, |
|
|
'created_at': time.time(), |
|
|
'ttl': ttl |
|
|
} |
|
|
self.cache[key] = cache_entry |
|
|
self._save_cache() |
|
|
|
|
|
def get(self, key: str) -> Optional[str]: |
|
|
"""Get value for key, returns None if not found or expired""" |
|
|
if key not in self.cache: |
|
|
return None |
|
|
|
|
|
entry = self.cache[key] |
|
|
|
|
|
|
|
|
if entry['ttl'] is not None: |
|
|
if time.time() - entry['created_at'] > entry['ttl']: |
|
|
self.delete(key) |
|
|
return None |
|
|
|
|
|
return entry['value'] |
|
|
|
|
|
def delete(self, key: str): |
|
|
"""Delete a key from cache""" |
|
|
if key in self.cache: |
|
|
del self.cache[key] |
|
|
self._save_cache() |
|
|
|
|
|
def clear(self): |
|
|
"""Clear all cache entries""" |
|
|
self.cache = {} |
|
|
self._save_cache() |
|
|
|
|
|
def _evict_oldest(self): |
|
|
"""Remove the oldest entry when cache is full""" |
|
|
if not self.cache: |
|
|
return |
|
|
|
|
|
oldest_key = min(self.cache.keys(), |
|
|
key=lambda k: self.cache[k]['created_at']) |
|
|
del self.cache[oldest_key] |