mirror of https://github.com/status-im/nim-abc.git
Implicitly add vertices when adding edges to a DAG
This commit is contained in:
parent
dd0685c96e
commit
d15e23cf13
|
@ -25,6 +25,12 @@ type
|
||||||
func new*[V](_: type SortedDag[V]): SortedDag[V] =
|
func new*[V](_: type SortedDag[V]): SortedDag[V] =
|
||||||
SortedDag[V]()
|
SortedDag[V]()
|
||||||
|
|
||||||
|
func contains*[V](dag: SortedDag[V], vertex: V): bool =
|
||||||
|
vertex in dag.order
|
||||||
|
|
||||||
|
func contains*[V](dag: SortedDag[V], edge: Edge[V]): bool =
|
||||||
|
edge in dag.edges
|
||||||
|
|
||||||
func lookup[V](dag: SortedDag[V], vertex: V): SortedVertex[V] =
|
func lookup[V](dag: SortedDag[V], vertex: V): SortedVertex[V] =
|
||||||
SortedVertex[V](vertex: vertex, index: dag.order[vertex])
|
SortedVertex[V](vertex: vertex, index: dag.order[vertex])
|
||||||
|
|
||||||
|
@ -82,23 +88,17 @@ func update[V](dag: SortedDag[V], lowerbound, upperbound: SortedVertex[V]) =
|
||||||
let backward = searchBackward(dag, upperbound, lowerbound)
|
let backward = searchBackward(dag, upperbound, lowerbound)
|
||||||
dag.reorder(forward, backward)
|
dag.reorder(forward, backward)
|
||||||
|
|
||||||
func add*[V](dag: SortedDag[V], vertex: V) =
|
func add[V](dag: SortedDag[V], vertex: V) =
|
||||||
## Adds a vertex to the DAG
|
if vertex notin dag:
|
||||||
dag.order[vertex] = -(dag.order.len)
|
dag.order[vertex] = -(dag.order.len)
|
||||||
|
|
||||||
func add*[V](dag: SortedDag[V], edge: tuple[x, y: V]) =
|
func add*[V](dag: SortedDag[V], edge: tuple[x, y: V]) =
|
||||||
## Adds an edge x -> y to the DAG
|
## Adds an edge x -> y to the DAG
|
||||||
doAssert edge.x in dag
|
dag.add(edge.y)
|
||||||
doAssert edge.y in dag
|
dag.add(edge.x)
|
||||||
dag.edges.incl(edge)
|
dag.edges.incl(edge)
|
||||||
dag.update(dag.lookup(edge.y), dag.lookup(edge.x))
|
dag.update(dag.lookup(edge.y), dag.lookup(edge.x))
|
||||||
|
|
||||||
func contains*[V](dag: SortedDag[V], vertex: V): bool =
|
|
||||||
vertex in dag.order
|
|
||||||
|
|
||||||
func contains*[V](dag: SortedDag[V], edge: Edge[V]): bool =
|
|
||||||
edge in dag.edges
|
|
||||||
|
|
||||||
iterator visit*[V](dag: SortedDag[V], start: V): V =
|
iterator visit*[V](dag: SortedDag[V], start: V): V =
|
||||||
## Visits all vertices that are reachable from the starting vertex. Vertices
|
## Visits all vertices that are reachable from the starting vertex. Vertices
|
||||||
## are visited in topological order, meaning that vertices close to the
|
## are visited in topological order, meaning that vertices close to the
|
||||||
|
|
|
@ -8,31 +8,21 @@ suite "Sorted DAG":
|
||||||
|
|
||||||
test "contains vertices":
|
test "contains vertices":
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
dag.add(1)
|
dag.add( (1, 2) )
|
||||||
check 1 in dag
|
check 1 in dag
|
||||||
|
check 2 in dag
|
||||||
check 42 notin dag
|
check 42 notin dag
|
||||||
dag.add(42)
|
dag.add( (2, 42) )
|
||||||
check 42 in dag
|
check 42 in dag
|
||||||
|
|
||||||
test "contains edges":
|
test "contains edges":
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
dag.add(1)
|
|
||||||
dag.add(2)
|
|
||||||
dag.add(3)
|
|
||||||
dag.add( (1, 2) )
|
dag.add( (1, 2) )
|
||||||
check (1, 2) in dag
|
check (1, 2) in dag
|
||||||
check (2, 3) notin dag
|
check (2, 3) notin dag
|
||||||
dag.add( (2, 3) )
|
dag.add( (2, 3) )
|
||||||
check (2, 3) in dag
|
check (2, 3) in dag
|
||||||
|
|
||||||
test "raises when adding adding edge for unknown vertex":
|
|
||||||
var dag = SortedDag[int].new
|
|
||||||
dag.add(1)
|
|
||||||
expect Defect:
|
|
||||||
dag.add( (1, 2) )
|
|
||||||
expect Defect:
|
|
||||||
dag.add( (2, 1) )
|
|
||||||
|
|
||||||
test "visits reachable vertices, nearest first":
|
test "visits reachable vertices, nearest first":
|
||||||
|
|
||||||
# ⓪ → ①
|
# ⓪ → ①
|
||||||
|
@ -40,8 +30,6 @@ suite "Sorted DAG":
|
||||||
# ②
|
# ②
|
||||||
|
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
for vertex in 0..2:
|
|
||||||
dag.add(vertex)
|
|
||||||
for edge in [ (0, 1), (1, 2), (0, 2) ]:
|
for edge in [ (0, 1), (1, 2), (0, 2) ]:
|
||||||
dag.add(edge)
|
dag.add(edge)
|
||||||
|
|
||||||
|
@ -58,8 +46,6 @@ suite "Sorted DAG":
|
||||||
# ③
|
# ③
|
||||||
|
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
for vertex in 0..5:
|
|
||||||
dag.add(vertex)
|
|
||||||
for edge in [ (5, 2), (5, 0), (4, 0), (4, 1), (2, 3), (3, 1) ]:
|
for edge in [ (5, 2), (5, 0), (4, 0), (4, 1), (2, 3), (3, 1) ]:
|
||||||
dag.add(edge)
|
dag.add(edge)
|
||||||
|
|
||||||
|
@ -79,8 +65,6 @@ suite "Sorted DAG":
|
||||||
# gain ← spend
|
# gain ← spend
|
||||||
|
|
||||||
var dag = SortedDag[string].new
|
var dag = SortedDag[string].new
|
||||||
for vertex in ["spend", "gain", "ack1", "ack2", "acks"]:
|
|
||||||
dag.add(vertex)
|
|
||||||
for edge in [("acks", "ack1"),
|
for edge in [("acks", "ack1"),
|
||||||
("acks", "ack2"),
|
("acks", "ack2"),
|
||||||
("ack1", "gain"),
|
("ack1", "gain"),
|
||||||
|
@ -106,8 +90,6 @@ suite "Sorted DAG":
|
||||||
# ⑤ → ⑩
|
# ⑤ → ⑩
|
||||||
|
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
for vertex in 0..10:
|
|
||||||
dag.add(vertex)
|
|
||||||
for vertex in [1,6]:
|
for vertex in [1,6]:
|
||||||
dag.add((0, vertex))
|
dag.add((0, vertex))
|
||||||
for vertex in 1..<5:
|
for vertex in 1..<5:
|
||||||
|
@ -126,11 +108,6 @@ suite "Sorted DAG":
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
|
|
||||||
var vertices: seq[int]
|
var vertices: seq[int]
|
||||||
for vertex in 0..100:
|
|
||||||
vertices.add(vertex)
|
|
||||||
vertices.shuffle()
|
|
||||||
for vertex in vertices:
|
|
||||||
dag.add(vertex)
|
|
||||||
|
|
||||||
for _ in 0..10_000:
|
for _ in 0..10_000:
|
||||||
let x, y = rand(100)
|
let x, y = rand(100)
|
||||||
|
@ -147,9 +124,7 @@ suite "Sorted DAG":
|
||||||
# ⓪ ← ① ← ② ← ...
|
# ⓪ ← ① ← ② ← ...
|
||||||
|
|
||||||
var dag = SortedDag[int].new
|
var dag = SortedDag[int].new
|
||||||
dag.add(0)
|
|
||||||
for i in 1..10_000:
|
for i in 1..10_000:
|
||||||
dag.add(i)
|
|
||||||
dag.add((i, i-1))
|
dag.add((i, i-1))
|
||||||
|
|
||||||
var latest = 10_000
|
var latest = 10_000
|
||||||
|
|
Loading…
Reference in New Issue