berna-r8 / code /cells /growth_engine.py
muhamedkamil's picture
Upload folder using huggingface_hub
d997548 verified
Raw History Blame Contribute Delete
2.82 kB
"""
Sequential Growth Engine — orchestrates Birth and Split events with K6 gating.
"""
from collections import deque
class SequentialGrowthEngine:
def __init__(self, max_events_per_step=1, max_births_per_100=5,
max_splits_per_100=3, cooldown_steps=100, verbose=False):
self.max_events_per_step = max_events_per_step
self.max_births_per_100 = max_births_per_100
self.max_splits_per_100 = max_splits_per_100
self.cooldown_steps = cooldown_steps
self.verbose = verbose
self.queue = deque()
self.birth_history = []
self.split_history = []
self.layer_last_event = {}
self.total_births = 0
self.total_splits = 0
self.total_rejected = 0
def _recent_count(self, history, step, window=100):
return sum(1 for s in history if step - s < window)
def can_birth(self, layer_idx, step):
if self._recent_count(self.birth_history, step) >= self.max_births_per_100:
return False
last = self.layer_last_event.get(layer_idx, -1e9)
return (step - last) >= self.cooldown_steps
def can_split(self, layer_idx, step):
if self._recent_count(self.split_history, step) >= self.max_splits_per_100:
return False
last = self.layer_last_event.get(layer_idx, -1e9)
return (step - last) >= self.cooldown_steps
def enqueue(self, event):
self.queue.append(event)
def process_one(self, step):
processed = []
for _ in range(self.max_events_per_step):
if not self.queue:
break
found = False
for i, event in enumerate(self.queue):
if event["type"] == "birth" and self.can_birth(event["layer_idx"], step):
e = self.queue[i]; del self.queue[i]
self.birth_history.append(step)
self.layer_last_event[e["layer_idx"]] = step
self.total_births += 1
processed.append(e); found = True; break
elif event["type"] == "split" and self.can_split(event["layer_idx"], step):
e = self.queue[i]; del self.queue[i]
self.split_history.append(step)
self.layer_last_event[e["layer_idx"]] = step
self.total_splits += 1
processed.append(e); found = True; break
if not found:
self.total_rejected += 1
break
return processed
def pending_count(self):
return len(self.queue)
def stats(self):
return {
"queued": len(self.queue),
"births": self.total_births,
"splits": self.total_splits,
"rejected": self.total_rejected,
}