()
| 153 | // LRU eviction. Prefers `done` boards as victims so an active regen doesn't |
| 154 | // vanish mid-flight. Returns the evicted id, or null when the map fits. |
| 155 | function evictOne(): string | null { |
| 156 | if (boards.size <= MAX_BOARDS) return null; |
| 157 | let oldestDone: Board | null = null; |
| 158 | let oldestAny: Board | null = null; |
| 159 | for (const b of boards.values()) { |
| 160 | if (b.state === "done") { |
| 161 | if (!oldestDone || b.lastTouched < oldestDone.lastTouched) oldestDone = b; |
| 162 | } |
| 163 | if (!oldestAny || b.lastTouched < oldestAny.lastTouched) oldestAny = b; |
| 164 | } |
| 165 | const victim = oldestDone || oldestAny; |
| 166 | if (!victim) return null; |
| 167 | boards.delete(victim.id); |
| 168 | boardMutex.delete(victim.id); |
| 169 | dlog(`evicted board ${victim.id} state=${victim.state}`); |
| 170 | return victim.id; |
| 171 | } |
| 172 | |
| 173 | function evictUntilUnderCap(): void { |
| 174 | while (boards.size > MAX_BOARDS) { |
no test coverage detected