| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- """
- engine.cache — Compile cache for YAML → Term.
- Compilation is deterministic (FROM_CONFIG_SPEC P4), so same hash → same Term.
- """
- from __future__ import annotations
- from collections import OrderedDict
- from typing import Any, Optional
- class CompileCache:
- def __init__(self, maxsize: int = 1000):
- self._cache: OrderedDict = OrderedDict()
- self._maxsize = maxsize
- self.hits = 0
- self.misses = 0
- def get(self, config_hash: str) -> Optional[Any]:
- if config_hash in self._cache:
- self._cache.move_to_end(config_hash)
- self.hits += 1
- return self._cache[config_hash]
- self.misses += 1
- return None
- def put(self, config_hash: str, term: Any):
- self._cache[config_hash] = term
- self._cache.move_to_end(config_hash)
- while len(self._cache) > self._maxsize:
- self._cache.popitem(last=False)
- def get_or_compile(self, config_hash: str, config: dict) -> Any:
- cached = self.get(config_hash)
- if cached:
- return cached
- import tempfile, yaml, os
- with tempfile.NamedTemporaryFile(mode='w', suffix='.yml', delete=False, encoding='utf-8') as f:
- yaml.dump(config, f, allow_unicode=True)
- tmp = f.name
- try:
- from lambdagent.fromconfig import from_config
- term = from_config(tmp)
- self.put(config_hash, term)
- return term
- finally:
- os.unlink(tmp)
- @property
- def stats(self):
- total = self.hits + self.misses
- return {"size": len(self._cache), "hits": self.hits, "misses": self.misses,
- "hit_rate": f"{self.hits/total:.1%}" if total else "N/A"}
|