A class to provide an exponential counter with jitter.
| 41 | |
| 42 | |
| 43 | class ExponentialCounter: |
| 44 | """A class to provide an exponential counter with jitter.""" |
| 45 | |
| 46 | def __init__(self, max_counter: int) -> None: |
| 47 | """Initialize an :class:`.ExponentialCounter` instance. |
| 48 | |
| 49 | :param max_counter: The maximum base value. |
| 50 | |
| 51 | .. note:: |
| 52 | |
| 53 | The computed value may be 3.125% higher due to jitter. |
| 54 | |
| 55 | """ |
| 56 | self._base = 1 |
| 57 | self._max = max_counter |
| 58 | |
| 59 | def counter(self) -> int | float: |
| 60 | """Increment the counter and return the current value with jitter.""" |
| 61 | max_jitter = self._base / 16.0 |
| 62 | value = self._base + random.random() * max_jitter - max_jitter / 2 # noqa: S311 |
| 63 | self._base = min(self._base * 2, self._max) |
| 64 | return value |
| 65 | |
| 66 | def reset(self) -> None: |
| 67 | """Reset the counter to 1.""" |
| 68 | self._base = 1 |
| 69 | |
| 70 | |
| 71 | def permissions_string(*, known_permissions: set[str], permissions: list[str] | None) -> str: |
no outgoing calls
searching dependent graphs…