Também chamado de: Object Pool, Bitmap Allocator, Resource Pool.
Gerencia slots numerados (números de entry do Nokia filter) marcando como
usado/livre sem nunca precisar renumerar.
Slots disponíveis: 100, 200, 300, ..., 500000 (múltiplos de 100)
Slots usados: {200: "209.14.7.57", 300: "1.2.3.4/24"}
import sqlite3
class SlotAllocator:
def __init__(self, db_path, start=100, stop=500_000, step=100):
self.db = db_path
self.slots = list(range(start, stop + 1, step))
self._init_db()
def _init_db(self):
with sqlite3.connect(self.db) as conn:
conn.execute("""
CREATE TABLE IF NOT EXISTS entries (
slot INTEGER PRIMARY KEY,
ip TEXT NOT NULL,
nexthop TEXT NOT NULL,
created TEXT DEFAULT (datetime('now'))
)
""")
def alloc(self, ip, nexthop) -> int:
with sqlite3.connect(self.db) as conn:
used = {r[0] for r in conn.execute("SELECT slot FROM entries")}
free = sorted(s for s in self.slots if s not in used)
if not free:
raise RuntimeError("Sem slots disponíveis")
slot = free[0]
conn.execute("INSERT INTO entries VALUES (?, ?, ?, datetime('now'))", (slot, ip, nexthop))
return slot
def release(self, slot: int):
with sqlite3.connect(self.db) as conn:
conn.execute("DELETE FROM entries WHERE slot = ?", (slot,))
def list_active(self):
with sqlite3.connect(self.db) as conn:
return conn.execute("SELECT slot, ip, nexthop, created FROM entries ORDER BY slot").fetchall()
Com step=100 e range 100→500000: 5000 slots disponíveis
Com step=10 e range 10→50000: 5000 slots disponíveis
Nokia entries são convencionalmente múltiplos de 100 (100, 200, 300...).
Isso deixa espaço para sub-entries futuras (101, 102...) se necessário.
Para só redirect, step=10 já é suficiente e dá mais slots.
CREATE TABLE entries (
slot INTEGER PRIMARY KEY, -- número da entry Nokia
ip TEXT NOT NULL, -- IP vítima (ex: 209.14.7.57/32)
nexthop TEXT NOT NULL, -- IP redirect (ex: 198.51.100.250)
created TEXT -- timestamp de criação
);