A Python port of the Invisible Internet Project (I2P)
at main 71 lines 2.1 kB view raw
1"""NetDB data store — in-memory storage for RouterInfo and LeaseSet entries.""" 2 3import enum 4import time 5 6 7class EntryType(enum.IntEnum): 8 ROUTER_INFO = 0 9 LEASE_SET = 1 10 11 12class NetDBEntry: 13 """A single entry in the network database.""" 14 15 def __init__(self, key: bytes, entry_type: EntryType, data: bytes, 16 received_ms: int, expiration_ms: int | None = None): 17 self.key = key 18 self.entry_type = entry_type 19 self.data = data 20 self.received_ms = received_ms 21 self.expiration_ms = expiration_ms 22 23 def is_expired(self, now_ms: int | None = None) -> bool: 24 if self.expiration_ms is None: 25 return False 26 if now_ms is None: 27 now_ms = int(time.time() * 1000) 28 return now_ms >= self.expiration_ms 29 30 31def _xor_distance(a: bytes, b: bytes) -> bytes: 32 return bytes(x ^ y for x, y in zip(a, b)) 33 34 35class DataStore: 36 """In-memory key-value store for NetDB entries.""" 37 38 def __init__(self): 39 self._entries: dict[bytes, NetDBEntry] = {} 40 41 def put(self, entry: NetDBEntry): 42 self._entries[entry.key] = entry 43 44 def get(self, key: bytes) -> NetDBEntry | None: 45 return self._entries.get(key) 46 47 def remove(self, key: bytes): 48 self._entries.pop(key, None) 49 50 def count(self) -> int: 51 return len(self._entries) 52 53 def count_by_type(self, entry_type: EntryType) -> int: 54 return sum(1 for e in self._entries.values() if e.entry_type == entry_type) 55 56 def remove_expired(self, now_ms: int | None = None): 57 expired = [k for k, e in self._entries.items() if e.is_expired(now_ms)] 58 for k in expired: 59 del self._entries[k] 60 61 def get_all(self) -> list[NetDBEntry]: 62 """Return all entries.""" 63 return list(self._entries.values()) 64 65 def get_all_keys(self) -> list[bytes]: 66 return list(self._entries.keys()) 67 68 def closest_keys(self, target: bytes, n: int) -> list[bytes]: 69 keys = list(self._entries.keys()) 70 keys.sort(key=lambda k: _xor_distance(k, target)) 71 return keys[:n]