"""Thread-safe object counter. Ported from net.i2p.util.ObjectCounter. """ from __future__ import annotations import threading class ObjectCounter: """Thread-safe counter for named keys.""" def __init__(self) -> None: self._lock = threading.Lock() self._counts: dict[str, int] = {} def increment(self, key: str) -> int: with self._lock: self._counts[key] = self._counts.get(key, 0) + 1 return self._counts[key] def decrement(self, key: str) -> int: with self._lock: val = self._counts.get(key, 0) - 1 self._counts[key] = max(0, val) return self._counts[key] def count(self, key: str) -> int: with self._lock: return self._counts.get(key, 0) def total(self) -> int: with self._lock: return sum(self._counts.values())