"""Trimmer implementations for Kademlia buckets. Ported from net.i2p.kademlia.{RejectTrimmer, RandomTrimmer, RandomIfOldTrimmer}. """ import random import time as _time from i2p_kademlia.kbucket import KBucket, KBucketTrimmer def _now_ms() -> int: return int(_time.time() * 1000) class RejectTrimmer(KBucketTrimmer): """Always reject new entries when bucket is full. Flood-resistant.""" def trim(self, bucket: KBucket, to_add: bytes) -> bool: return False class RandomTrimmer(KBucketTrimmer): """Remove a random entry to make room. Not flood-resistant.""" def __init__(self, max_size: int) -> None: self._max = max_size def trim(self, bucket: KBucket, to_add: bytes) -> bool: entries = list(bucket.get_entries()) if len(entries) >= self._max and entries: victim = random.choice(entries) bucket.remove(victim) return True class RandomIfOldTrimmer(RandomTrimmer): """Remove random entry only if bucket hasn't been updated recently (5 min).""" _STALE_THRESHOLD = 5 * 60 * 1000 # 5 minutes def trim(self, bucket: KBucket, to_add: bytes) -> bool: if bucket.last_changed > _now_ms() - self._STALE_THRESHOLD: return False # Bucket is fresh, reject return super().trim(bucket, to_add)