Spaces:
Running
Running
Claude Opus 5.5
Bloque: heredar solo si recupera en <=5 s (o <=10 s con la altura rival coincidente)
f9af9df Download src/racing_reports/data_cache.py from pablogrois/RRC: direct link, hf CLI and curl.
- Browser
- Download file 2.54 kB
-
https://huggingface.co/spaces/pablogrois/RRC/resolve/main/src/racing_reports/data_cache.py
- Command line
-
hf download hf://spaces/pablogrois/RRC/src/racing_reports/data_cache.py
-
curl -L -o data_cache.py https://huggingface.co/spaces/pablogrois/RRC/resolve/main/src/racing_reports/data_cache.py
2.54 kB
| """Cache en memoria del DataFrame del preprocessed. | |
| ``pd.read_csv`` de un archivo de 2.47 GB tarda ~60 s en CPU básico. Si lo | |
| guardamos en RAM, la primera corrida sigue tardando lo mismo, pero las que | |
| vienen después son instantáneas (parte CPU del pipeline). | |
| La key del cache incluye ``mtime`` para que, si el archivo se actualiza en | |
| disco (sync semanal del preprocessed), la entrada se invalide sola. | |
| Single-container HF Space, sin multiproceso → un dict global con lock alcanza. | |
| """ | |
| from __future__ import annotations | |
| import threading | |
| from collections import OrderedDict | |
| from pathlib import Path | |
| import pandas as pd | |
| from racing_reports import bloques | |
| _CACHE: "OrderedDict[tuple[str, float, bool], pd.DataFrame]" = OrderedDict() | |
| _LOCK = threading.Lock() | |
| _MAX_ENTRIES = 2 # preprocessed base + (eventual) labeled distinto | |
| def get_cached(path: Path, *, low_memory: bool = False) -> pd.DataFrame: | |
| """Devuelve un DataFrame del CSV, leyendo del cache si está disponible. | |
| Importante: el DataFrame es **compartido**. Los callers que vayan a mutar | |
| columnas deben hacer ``.copy()`` antes. Mutaciones tipo ``df[col] = ...`` | |
| sobre el devuelto afectan al cache. | |
| """ | |
| p = Path(path).resolve() | |
| key = (str(p), p.stat().st_mtime, low_memory) | |
| with _LOCK: | |
| hit = _CACHE.get(key) | |
| if hit is not None: | |
| _CACHE.move_to_end(key) | |
| return hit | |
| # Leer fuera del lock para no bloquear otros lookups durante 60 s. | |
| df = pd.read_csv(p, low_memory=low_memory) | |
| # Bloque corregido en phaseLabel (la secuencia corta sin bloque hereda el de la última con bloque | |
| # del equipo si recupera en ≤5 s, o ≤10 s con la altura rival coincidente) | |
| # para TODOS los reportes que lean de acá. Ver racing_reports/bloques.py. | |
| bloques.aplicar(df) | |
| with _LOCK: | |
| # Si otro thread cargó la misma key en el medio, preferimos su copia. | |
| existing = _CACHE.get(key) | |
| if existing is not None: | |
| return existing | |
| _CACHE[key] = df | |
| _CACHE.move_to_end(key) | |
| while len(_CACHE) > _MAX_ENTRIES: | |
| _CACHE.popitem(last=False) | |
| return df | |
| def is_cached(path: Path, *, low_memory: bool = False) -> bool: | |
| """Si el archivo ya está cargado en RAM (sin tocar disco más allá del stat).""" | |
| p = Path(path).resolve() | |
| if not p.exists(): | |
| return False | |
| key = (str(p), p.stat().st_mtime, low_memory) | |
| with _LOCK: | |
| return key in _CACHE | |
| def clear() -> None: | |
| with _LOCK: | |
| _CACHE.clear() | |