Spaces:
Running
Running
Download src/koevd_eval/profile_cache.py from KETI-NLP/KoEVD-Platform: direct link, hf CLI and curl.
- Browser
- Download file 3.51 kB
-
https://huggingface.co/spaces/KETI-NLP/KoEVD-Platform/resolve/main/src/koevd_eval/profile_cache.py
- Command line
-
hf download hf://spaces/KETI-NLP/KoEVD-Platform/src/koevd_eval/profile_cache.py
-
curl -L -o profile_cache.py https://huggingface.co/spaces/KETI-NLP/KoEVD-Platform/resolve/main/src/koevd_eval/profile_cache.py
3.51 kB
| """Bounded, disposable numerical cache; never an authority for publication. | |
| Only application-selected numerical projections enter this cache. Current | |
| publication and recovery checks must happen outside it on every request. | |
| """ | |
| from collections import OrderedDict | |
| from concurrent.futures import Future | |
| import json | |
| from threading import Lock | |
| from .results import canonical_hash | |
| from .storage import encode | |
| VERSION = 'koevd-public-numerical-profile-v2' | |
| FIELDS = ('format', 'artifact_sha256', 'protocol', 'scoring', 'statistics', | |
| 'interpretation', 'tasks', 'task3_task5', 'quality', 'signal_thresholds', | |
| 'signals', 'charts') | |
| def numerical_profile(profile): | |
| """Whitelist analytical output; omit originals, cases and source identities.""" | |
| value = {key: profile[key] for key in FIELDS} | |
| disagreement = profile['measurement_disagreement'] | |
| value['measurement_disagreement'] = { | |
| key: disagreement[key] for key in ('count', 'comparable_sources', 'interpretation')} | |
| # Round trip also detaches every nested object from the analysis engine. | |
| return json.loads(encode(value)) | |
| def numerical_comparison(comparison): | |
| """Exact matched-input counts and rates without run or sample identities.""" | |
| value = {key: comparison[key] for key in | |
| ('format', 'left_artifact', 'right_artifact', 'tasks', 'note')} | |
| value = json.loads(encode(value)) | |
| value['note'] = (comparison['note'].replace('Intervals resample shared sources together.', | |
| 'Bootstrap is disabled in this public summary; no confidence intervals are shown.')) | |
| for task in value['tasks']: | |
| for partition in task['partitions']: | |
| partition.pop('sample_ids', None) | |
| return value | |
| class NumericalProfileCache: | |
| def __init__(self, *, max_entries=128, max_bytes=64 * 1024**2): | |
| if (type(max_entries) is not int or max_entries < 1 | |
| or type(max_bytes) is not int or max_bytes < 1): | |
| raise ValueError('Positive numerical cache bounds required') | |
| self.max_entries, self.max_bytes = max_entries, max_bytes | |
| self._entries, self._pending = OrderedDict(), {} | |
| self._size, self._lock = 0, Lock() | |
| def get_or_compute(self, identity, compute): | |
| key = canonical_hash({'projection': VERSION, **identity}) | |
| with self._lock: | |
| if key in self._entries: | |
| self._entries.move_to_end(key) | |
| return json.loads(self._entries[key]) | |
| future = self._pending.get(key) | |
| leader = future is None | |
| if leader: | |
| future = self._pending[key] = Future() | |
| if not leader: | |
| return json.loads(future.result()) | |
| try: | |
| blob = encode(compute()) | |
| with self._lock: | |
| if len(blob) <= self.max_bytes: | |
| while self._entries and (len(self._entries) >= self.max_entries | |
| or self._size + len(blob) > self.max_bytes): | |
| _, removed = self._entries.popitem(last=False) | |
| self._size -= len(removed) | |
| self._entries[key] = blob | |
| self._size += len(blob) | |
| self._pending.pop(key) | |
| future.set_result(blob) | |
| return json.loads(blob) | |
| except BaseException as exc: | |
| with self._lock: | |
| self._pending.pop(key, None) | |
| future.set_exception(exc) | |
| raise | |