Spaces:
Configuration error
Configuration error
Download core/cache.py from varshithreddy1807/aria: direct link, hf CLI and curl.
- Browser
- Download file 4.75 kB
-
https://huggingface.co/spaces/varshithreddy1807/aria/resolve/main/core/cache.py
- Command line
-
hf download hf://spaces/varshithreddy1807/aria/core/cache.py
-
curl -L -o cache.py https://huggingface.co/spaces/varshithreddy1807/aria/resolve/main/core/cache.py
4.75 kB
| """In-memory analysis caching layer (PH2-002).""" | |
| from __future__ import annotations | |
| import logging | |
| import time | |
| from typing import Any, Dict, Optional, Tuple | |
| import threading | |
| logger = logging.getLogger(__name__) | |
| class CacheEntry: | |
| """A single entry in the analysis cache.""" | |
| def __init__(self, value: Any, schema_version: int) -> None: | |
| self.value = value | |
| self.schema_version = schema_version | |
| self.created_at = time.time() | |
| self.last_accessed = self.created_at | |
| class AnalysisCache: | |
| """Shared in-memory cache for parsed AST data, graphs, and summaries.""" | |
| def __init__(self, limit: int = 1000) -> None: | |
| self.limit = limit | |
| # Cache map: (repo_name, key, subkey) -> CacheEntry | |
| self._cache: Dict[Tuple[str, str, Optional[str]], CacheEntry] = {} | |
| self.hits: Dict[str, int] = {} | |
| self.misses: Dict[str, int] = {} | |
| self._lock = threading.RLock() | |
| def get( | |
| self, | |
| repo_name: str, | |
| key: str, | |
| schema_version: int, | |
| subkey: Optional[str] = None, | |
| ) -> Optional[Any]: | |
| """Retrieve a cached object if valid and matches the schema version.""" | |
| with self._lock: | |
| cache_key = (repo_name, key, subkey) | |
| entry = self._cache.get(cache_key) | |
| stat_key = f"{key}:{subkey}" if subkey else key | |
| if entry is not None: | |
| if entry.schema_version >= schema_version: | |
| entry.last_accessed = time.time() | |
| self.hits[stat_key] = self.hits.get(stat_key, 0) + 1 | |
| return entry.value | |
| else: | |
| logger.info( | |
| "Stale cache entry invalidated for %s/%s:%s " | |
| "(v%d < expected v%d)", | |
| repo_name, | |
| key, | |
| subkey, | |
| entry.schema_version, | |
| schema_version, | |
| ) | |
| self.invalidate(repo_name, key, subkey) | |
| self.misses[stat_key] = self.misses.get(stat_key, 0) + 1 | |
| return None | |
| def set( | |
| self, | |
| repo_name: str, | |
| key: str, | |
| value: Any, | |
| schema_version: int, | |
| subkey: Optional[str] = None, | |
| ) -> None: | |
| """Store an object in the cache with its schema version.""" | |
| with self._lock: | |
| cache_key = (repo_name, key, subkey) | |
| # LRU Eviction if we are adding a new key and size exceeds limit | |
| if cache_key not in self._cache and len(self._cache) >= self.limit: | |
| oldest_key = None | |
| oldest_time = float("inf") | |
| for k, entry in self._cache.items(): | |
| if entry.last_accessed < oldest_time: | |
| oldest_time = entry.last_accessed | |
| oldest_key = k | |
| if oldest_key is not None: | |
| self._cache.pop(oldest_key, None) | |
| logger.info( | |
| "Cache eviction (LRU): removed %s due to size limit", oldest_key | |
| ) | |
| self._cache[cache_key] = CacheEntry(value, schema_version) | |
| logger.debug( | |
| "Cached entry for %s/%s:%s (v%d)", | |
| repo_name, | |
| key, | |
| subkey, | |
| schema_version, | |
| ) | |
| def invalidate( | |
| self, | |
| repo_name: str, | |
| key: Optional[str] = None, | |
| subkey: Optional[str] = None, | |
| ) -> None: | |
| """Invalidate cache entries. | |
| If key is None, invalidates all keys for the repo. | |
| If subkey is None, invalidates all subkeys for the key. | |
| Otherwise invalidates only the specific subkey. | |
| """ | |
| with self._lock: | |
| if key is None: | |
| to_remove = [k for k in self._cache.keys() if k[0] == repo_name] | |
| elif subkey is None: | |
| to_remove = [ | |
| k for k in self._cache.keys() if k[0] == repo_name and k[1] == key | |
| ] | |
| else: | |
| to_remove = [(repo_name, key, subkey)] | |
| for k in to_remove: | |
| self._cache.pop(k, None) | |
| def clear(self) -> None: | |
| """Clear all cache contents and statistics.""" | |
| with self._lock: | |
| self._cache.clear() | |
| self.hits.clear() | |
| self.misses.clear() | |
| def get_stats(self) -> Dict[str, Any]: | |
| """Return hit/miss statistics and current size of the cache.""" | |
| with self._lock: | |
| return { | |
| "hits": dict(self.hits), | |
| "misses": dict(self.misses), | |
| "size": len(self._cache), | |
| } | |