Files
hao-ai-lab-FastVideo/v2/cache/manager.py
T
SolitaryThinker a9e5f6ee7a [refactor] rename package mini_fastvideo → v2
Directory rename (git mv, history preserved) plus rewrite of all references: absolute imports in
tests, the zero-dep runner, docstrings, comments, and the README. No behavior change.

Run: python3 -m pytest v2/tests/ -q ; python3 v2/run_tests.py ; python3 -m v2.examples
2026-07-04 17:15:34 +00:00

65 lines
2.7 KiB
Python

"""CacheManager — per-class pools with static budgets, behind one handle (design_v3 §7.2).
Static partitioning makes cross-class fragmentation impossible (jumbo slab traffic cannot
strand text-KV pages and vice versa). Each class gets a budget carved at init from the card's
CacheContracts. ``invalidate_weights`` implements the wholesale RL weight-epoch bump.
"""
from __future__ import annotations
from typing import Any
from .classes import _Pool, make_pool
from .keys import CachePolicy
class CacheManager:
def __init__(self, policies: list[CachePolicy] | None = None):
self._pools: dict[str, _Pool] = {}
for p in (policies or []):
self._pools[p.class_name] = make_pool(p)
@classmethod
def from_card(cls, card) -> "CacheManager":
"""Build the per-class pools a card declares (KV pools materialize only if declared)."""
policies = []
for cc in card.caches.values():
policies.append(CachePolicy(
class_name=cc.cache_class, max_bytes=cc.max_bytes, block_bytes=cc.block_bytes,
eviction=cc.eviction, reuse_across_requests=cc.reuse_across_requests,
per_component=dict(cc.per_component),
training_mode_disables_recycle=cc.training_mode_disables_recycle,
))
return cls(policies)
def pool(self, class_name: str) -> _Pool:
if class_name not in self._pools:
raise KeyError(f"no cache pool for class {class_name!r}; card did not declare it")
return self._pools[class_name]
def has(self, class_name: str) -> bool:
return class_name in self._pools
def invalidate_weights(self, version: str) -> None:
for pool in self._pools.values():
if hasattr(pool, "invalidate_weights"):
pool.invalidate_weights(version)
def invalidate_components(self, components) -> None:
"""Component-scoped invalidation (design_v3 §7.1): only drop caches for changed components."""
comps = set(components)
for pool in self._pools.values():
if hasattr(pool, "invalidate_components"):
pool.invalidate_components(comps)
def clear_namespace(self, namespace: str) -> None:
"""Release a finished request's per-request caches (residual/slab)."""
for pool in self._pools.values():
if hasattr(pool, "clear_namespace"):
pool.clear_namespace(namespace)
if hasattr(pool, "free_namespace"):
pool.free_namespace(namespace)
def stats(self) -> dict[str, Any]:
return {name: {"used_bytes": p.used_bytes, "hits": p.hits, "misses": p.misses}
for name, p in self._pools.items()}