Skip to content

Commit d501b53

Browse files
committed
fix edge index pruning
1 parent 416f99e commit d501b53

2 files changed

Lines changed: 54 additions & 37 deletions

File tree

lib/graph.ex

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,6 @@ defmodule Graph do
15281528
defp prune_edge_index(
15291529
%__MODULE__{
15301530
multigraph: true,
1531-
edge_index: edge_index,
15321531
edges: meta,
15331532
partition_by: partition_by
15341533
} = g,
@@ -1548,14 +1547,14 @@ defmodule Graph do
15481547
v1_key = {v1_id, edge_p}
15491548
v2_key = {v2_id, edge_p}
15501549

1551-
edge_index =
1552-
edge_index
1550+
updated_edge_index =
1551+
acc.edge_index
15531552
|> Map.delete(v1_key)
15541553
|> Map.delete(v2_key)
15551554

15561555
%__MODULE__{
15571556
acc
1558-
| edge_index: edge_index
1557+
| edge_index: updated_edge_index
15591558
}
15601559
end)
15611560
end)
@@ -1564,7 +1563,6 @@ defmodule Graph do
15641563
defp prune_edge_index(
15651564
%__MODULE__{
15661565
multigraph: true,
1567-
edge_index: edge_index,
15681566
edges: meta,
15691567
partition_by: partition_by
15701568
} = g,
@@ -1584,25 +1582,47 @@ defmodule Graph do
15841582

15851583
edge_partitions = partition_by.(edge)
15861584

1585+
edge_key = {v1_id, v2_id}
1586+
15871587
Enum.reduce(edge_partitions, g, fn edge_p, acc ->
15881588
partition =
1589-
edge_index
1589+
acc.edge_index
15901590
|> Map.get(edge_p, %{})
1591-
|> Map.reject(fn {k, v} ->
1592-
(k == v1_id and MapSet.member?(v, {v1_id, v2_id})) or
1593-
(k == v2_id and MapSet.member?(v, {v1_id, v2_id}))
1591+
|> Enum.reduce(%{}, fn {k, v}, new_partition ->
1592+
cond do
1593+
k == v1_id ->
1594+
remaining = MapSet.delete(v, edge_key)
1595+
1596+
if MapSet.size(remaining) > 0 do
1597+
Map.put(new_partition, k, remaining)
1598+
else
1599+
new_partition
1600+
end
1601+
1602+
k == v2_id ->
1603+
remaining = MapSet.delete(v, edge_key)
1604+
1605+
if MapSet.size(remaining) > 0 do
1606+
Map.put(new_partition, k, remaining)
1607+
else
1608+
new_partition
1609+
end
1610+
1611+
true ->
1612+
Map.put(new_partition, k, v)
1613+
end
15941614
end)
15951615

1596-
edge_index =
1616+
updated_edge_index =
15971617
if not Enum.empty?(partition) do
1598-
Map.put(edge_index, edge_p, partition)
1618+
Map.put(acc.edge_index, edge_p, partition)
15991619
else
1600-
Map.delete(edge_index, edge_p)
1620+
Map.delete(acc.edge_index, edge_p)
16011621
end
16021622

16031623
%__MODULE__{
16041624
acc
1605-
| edge_index: edge_index
1625+
| edge_index: updated_edge_index
16061626
}
16071627
end)
16081628
end

test/graph_test.exs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,30 +156,27 @@ defmodule GraphTest do
156156
assert Map.has_key?(g.edge_index[:baz], g.vertex_identifier.(:a))
157157
end
158158

159-
# test "BFS traversal using multigraph partitions" do
160-
# graph =
161-
# Graph.new(multigraph: true)
162-
# |> Graph.add_edges([
163-
# {:a, :b, label: :foo},
164-
# {:a, :b, label: :bar},
165-
# {:b, :c, weight: 3},
166-
# {:b, :a, label: {:complex, :label}}
167-
# ])
168-
169-
# assert Graph.bfs(graph, :a) == [:a, :b, :c]
170-
# end
171-
172-
# test "DFS traversal using multigraph partitions" do
173-
# end
174-
175-
# test "Dijkstra traversal using multigraph partitions" do
176-
# end
177-
178-
# test "A* traversal using multigraph partitions" do
179-
# end
180-
181-
# test "Bellman-Ford traversal using multigraph partitions" do
182-
# end
159+
test "update_labelled_edge preserves sibling edges in partition index" do
160+
g =
161+
Graph.new(multigraph: true)
162+
|> Graph.add_edge(:fact, :join, label: :runnable)
163+
|> Graph.add_edge(:fact, :step_a, label: :runnable)
164+
|> Graph.add_edge(:fact, :step_b, label: :runnable)
165+
166+
assert length(Graph.edges(g, by: [:runnable])) == 3
167+
168+
g = Graph.update_labelled_edge(g, :fact, :join, :runnable, label: :ran)
169+
170+
ran_edges = Graph.edges(g, by: [:ran])
171+
assert length(ran_edges) == 1
172+
assert hd(ran_edges).v1 == :fact and hd(ran_edges).v2 == :join
173+
174+
runnable_edges = Graph.edges(g, by: [:runnable])
175+
assert length(runnable_edges) == 2
176+
177+
runnable_targets = Enum.map(runnable_edges, & &1.v2) |> Enum.sort()
178+
assert runnable_targets == [:step_a, :step_b]
179+
end
183180
end
184181

185182
describe "edge properties" do

0 commit comments

Comments
 (0)