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)