Complete plan execution: gossip/raft bounds, deadlock fix, JSON escaping, memtable limits
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled

Remaining plan items:
- 1.4 hybrid_search: JSON built with std/json instead of string concat
- 2.3 lsm.nim: reject oversized memtable entries
- 3.3 gossip.nim: bounds checking for idLen/nodeCount/hostLen
- 3.4 raft.nim: max length caps for cmdLen/dataLen/logLen
- 4.3 deadlock.nim: per-path seq stack instead of global parent table
This commit is contained in:
2026-05-18 11:42:46 +03:00
parent 967c0855a5
commit 47c4393a7e
5 changed files with 38 additions and 24 deletions
+13 -21
View File
@@ -1,7 +1,6 @@
## Deadlock Detection — wait-for graph
import std/tables
import std/sets
import std/algorithm
import std/locks
type
@@ -68,32 +67,25 @@ proc removeTxn*(dd: DeadlockDetector, txnId: uint64) =
proc detectCycleUnsafe(dd: DeadlockDetector): seq[uint64] =
var visited = initHashSet[uint64]()
var inStack = initHashSet[uint64]()
var parent = initTable[uint64, uint64]()
proc dfs(node: uint64): seq[uint64] =
proc dfs(node: uint64, path: seq[uint64]): seq[uint64] =
visited.incl(node)
inStack.incl(node)
var newPath = path & @[node]
for neighbor in dd.adjacency.getOrDefault(node, @[]):
if neighbor in inStack:
# Found cycle — reconstruct
var cycle = @[neighbor, node]
var current = node
while parent.getOrDefault(current, 0'u64) != neighbor and
parent.getOrDefault(current, 0'u64) != 0:
current = parent[current]
if current == 0: break
cycle.add(current)
# Verify we actually closed the cycle back to neighbor
if cycle[^1] != neighbor and parent.getOrDefault(cycle[^1], 0'u64) == neighbor:
cycle.add(neighbor)
elif cycle[^1] != neighbor:
# Incomplete cycle — should not happen with valid parent chain
return @[]
cycle.reverse()
# Found cycle — reconstruct from path
var cycle: seq[uint64] = @[]
var found = false
for n in newPath:
if n == neighbor:
found = true
if found:
cycle.add(n)
cycle.add(neighbor)
return cycle
if neighbor notin visited:
parent[neighbor] = node
let cycle = dfs(neighbor)
let cycle = dfs(neighbor, newPath)
if cycle.len > 0:
return cycle
inStack.excl(node)
@@ -101,7 +93,7 @@ proc detectCycleUnsafe(dd: DeadlockDetector): seq[uint64] =
for txnId in dd.txnIds:
if txnId notin visited:
let cycle = dfs(txnId)
let cycle = dfs(txnId, @[])
if cycle.len > 0:
return cycle
return @[]