File size: 1,358 Bytes
30ea0e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | from __future__ import annotations
import hashlib
import threading
from collections import OrderedDict
def content_hash(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
class PromotionLRU:
"""LRU mapping (content_hash, dest_folder) -> existing target filename.
Used to make bucket-source promotions idempotent: the same bytes promoted
to the same destination twice in a row returns the existing filename
instead of creating a duplicate.
"""
def __init__(self, max_entries: int):
if max_entries <= 0:
raise ValueError("max_entries must be positive")
self._max = max_entries
self._data: OrderedDict[tuple[str, str], str] = OrderedDict()
self._lock = threading.Lock()
def get(self, content_hash: str, dest_folder: str) -> str | None:
key = (content_hash, dest_folder)
with self._lock:
if key in self._data:
self._data.move_to_end(key)
return self._data[key]
return None
def record(self, content_hash: str, dest_folder: str, filename: str) -> None:
key = (content_hash, dest_folder)
with self._lock:
self._data[key] = filename
self._data.move_to_end(key)
while len(self._data) > self._max:
self._data.popitem(last=False)
|