-
Notifications
You must be signed in to change notification settings - Fork 3.3k
When sorting update commands add Deleted + Inserted number of edges instead of Deleted * Inserted #26082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When sorting update commands add Deleted + Inserted number of edges instead of Deleted * Inserted #26082
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,19 +14,16 @@ internal class Multigraph<TVertex, TEdge> : Graph<TVertex> | |
where TVertex : notnull | ||
{ | ||
private readonly HashSet<TVertex> _vertices = new(); | ||
private readonly Dictionary<TVertex, Dictionary<TVertex, List<TEdge>>> _successorMap = new(); | ||
private readonly Dictionary<TVertex, Dictionary<TVertex, object?>> _successorMap = new(); | ||
private readonly Dictionary<TVertex, HashSet<TVertex>> _predecessorMap = new(); | ||
|
||
public IEnumerable<TEdge> Edges | ||
=> _successorMap.Values.SelectMany(s => s.Values).SelectMany(e => e).Distinct(); | ||
|
||
public IEnumerable<TEdge> GetEdges(TVertex from, TVertex to) | ||
{ | ||
if (_successorMap.TryGetValue(from, out var successorSet)) | ||
{ | ||
if (successorSet.TryGetValue(to, out var edgeList)) | ||
if (successorSet.TryGetValue(to, out var edges)) | ||
{ | ||
return edgeList; | ||
return edges is IEnumerable<TEdge> edgeList ? edgeList : (new TEdge[] { (TEdge)edges! }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like it would allocate more if GetEdges is called multiple times for the same two vertices - is this intentional (e.g. because we never do that?). We can also continue returnining a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, it's only called during cycle breaking
Can you make it a suggestion? I don't understand how it's simpler |
||
} | ||
} | ||
|
||
|
@@ -55,17 +52,23 @@ public void AddEdge(TVertex from, TVertex to, TEdge edge) | |
|
||
if (!_successorMap.TryGetValue(from, out var successorEdges)) | ||
{ | ||
successorEdges = new Dictionary<TVertex, List<TEdge>>(); | ||
successorEdges = new Dictionary<TVertex, object?>(); | ||
_successorMap.Add(from, successorEdges); | ||
} | ||
|
||
if (!successorEdges.TryGetValue(to, out var edgeList)) | ||
if (successorEdges.TryGetValue(to, out var edges)) | ||
{ | ||
edgeList = new List<TEdge>(); | ||
successorEdges.Add(to, edgeList); | ||
if (edges is not List<TEdge> edgeList) | ||
{ | ||
edgeList = new List<TEdge> { (TEdge)edges! }; | ||
successorEdges[to] = edgeList; | ||
} | ||
edgeList.Add(edge); | ||
} | ||
else | ||
{ | ||
successorEdges.Add(to, edge); | ||
} | ||
|
||
edgeList.Add(edge); | ||
|
||
if (!_predecessorMap.TryGetValue(to, out var predecessors)) | ||
{ | ||
|
@@ -76,7 +79,7 @@ public void AddEdge(TVertex from, TVertex to, TEdge edge) | |
predecessors.Add(from); | ||
} | ||
|
||
public void AddEdges(TVertex from, TVertex to, IEnumerable<TEdge> edges) | ||
public void AddEdges(TVertex from, TVertex to, IEnumerable<TEdge> newEdges) | ||
{ | ||
#if DEBUG | ||
if (!_vertices.Contains(from)) | ||
|
@@ -92,18 +95,25 @@ public void AddEdges(TVertex from, TVertex to, IEnumerable<TEdge> edges) | |
|
||
if (!_successorMap.TryGetValue(from, out var successorEdges)) | ||
{ | ||
successorEdges = new Dictionary<TVertex, List<TEdge>>(); | ||
successorEdges = new Dictionary<TVertex, object?>(); | ||
_successorMap.Add(from, successorEdges); | ||
} | ||
|
||
if (!successorEdges.TryGetValue(to, out var edgeList)) | ||
if (successorEdges.TryGetValue(to, out var edges)) | ||
{ | ||
edgeList = new List<TEdge>(); | ||
if (edges is not List<TEdge> edgeList) | ||
{ | ||
edgeList = new List<TEdge> { (TEdge)edges! }; | ||
successorEdges[to] = edgeList; | ||
} | ||
edgeList.AddRange(newEdges); | ||
} | ||
else | ||
{ | ||
var edgeList = newEdges.ToList(); | ||
successorEdges.Add(to, edgeList); | ||
} | ||
|
||
edgeList.AddRange(edges); | ||
|
||
if (!_predecessorMap.TryGetValue(to, out var predecessors)) | ||
{ | ||
predecessors = new HashSet<TVertex>(); | ||
|
@@ -193,7 +203,7 @@ public IReadOnlyList<TVertex> TopologicalSort( | |
.First(neighbor => predecessorCounts.TryGetValue(neighbor, out var neighborPredecessors) | ||
&& neighborPredecessors > 0); | ||
|
||
if (tryBreakEdge(incomingNeighbor, candidateVertex, _successorMap[incomingNeighbor][candidateVertex])) | ||
if (tryBreakEdge(incomingNeighbor, candidateVertex, GetEdges(incomingNeighbor, candidateVertex))) | ||
{ | ||
_successorMap[incomingNeighbor].Remove(candidateVertex); | ||
_predecessorMap[candidateVertex].Remove(incomingNeighbor); | ||
|
@@ -367,7 +377,7 @@ public IReadOnlyList<List<TVertex>> BatchingTopologicalSort( | |
.First(neighbor => predecessorCounts.TryGetValue(neighbor, out var neighborPredecessors) | ||
&& neighborPredecessors > 0); | ||
|
||
if (tryBreakEdge(incomingNeighbor, candidateVertex, _successorMap[incomingNeighbor][candidateVertex])) | ||
if (tryBreakEdge(incomingNeighbor, candidateVertex, GetEdges(incomingNeighbor, candidateVertex))) | ||
{ | ||
_successorMap[incomingNeighbor].Remove(candidateVertex); | ||
_predecessorMap[candidateVertex].Remove(incomingNeighbor); | ||
|
Uh oh!
There was an error while loading. Please reload this page.