Skip to content

Commit f0b4d03

Browse files
authored
Merge pull request #356 from DataObjects-NET/7.1-hTopologicalSorter-imps
Helpers.TopologicalSorter issues fix
2 parents 54c8ffe + 44069b3 commit f0b4d03

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

ChangeLog/7.1.2_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[main] Addressed issue when cycles in Entity dependency graph were not detected

Orm/Xtensive.Orm/Sorting/TopologicalSorter.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
using Xtensive.Collections;
1010
using System.Linq;
1111
using Xtensive.Core;
12-
12+
using DotNetNotNullAttribute = System.Diagnostics.CodeAnalysis.NotNullAttribute;
13+
using JBNotNullAttribute = JetBrains.Annotations.NotNullAttribute;
14+
using JBCanBeNullAttribute = JetBrains.Annotations.CanBeNullAttribute;
1315

1416
namespace Xtensive.Sorting
1517
{
@@ -29,6 +31,7 @@ public static class TopologicalSorter
2931
/// Sorting result, if there were no loops;
3032
/// otherwise, <see langword="null"/>.
3133
/// </returns>
34+
[JBCanBeNull]
3235
public static IEnumerable<TNodeItem> Sort<TNodeItem>(IEnumerable<TNodeItem> items, Predicate<TNodeItem, TNodeItem> connector) =>
3336
Sort(items, connector, out List<Node<TNodeItem, object>> loops);
3437

@@ -43,6 +46,7 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem>(IEnumerable<TNodeItem> item
4346
/// Sorting result, if there were no loops;
4447
/// otherwise, <see langword="null"/>.
4548
/// </returns>
49+
[JBCanBeNull]
4650
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(IEnumerable<TNodeItem> items, Predicate<TNodeItem, TNodeItem> connector) =>
4751
SortToList(items, connector, out List<Node<TNodeItem, object>> loops);
4852

@@ -59,6 +63,7 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(IEnumerable<TNodeIt
5963
/// otherwise, <see langword="null"/>.
6064
/// In this case <paramref name="loops"/> will contain only the loop edges.
6165
/// </returns>
66+
[JBCanBeNull]
6267
public static IEnumerable<TNodeItem> Sort<TNodeItem>(
6368
IEnumerable<TNodeItem> items,
6469
Predicate<TNodeItem, TNodeItem> connector,
@@ -83,6 +88,7 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem>(
8388
/// otherwise, <see langword="null"/>.
8489
/// In this case <paramref name="loops"/> will contain only the loop edges.
8590
/// </returns>
91+
[JBCanBeNull]
8692
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
8793
IEnumerable<TNodeItem> items,
8894
Predicate<TNodeItem, TNodeItem> connector,
@@ -105,6 +111,8 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
105111
/// <returns>
106112
/// Sorting result
107113
/// </returns>
114+
[return: DotNetNotNull]
115+
[JBNotNull]
108116
public static IEnumerable<TNodeItem> Sort<TNodeItem>(
109117
IEnumerable<TNodeItem> items,
110118
Predicate<TNodeItem, TNodeItem> connector,
@@ -121,6 +129,8 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem>(
121129
/// <returns>
122130
/// Sorting result
123131
/// </returns>
132+
[return: DotNetNotNull]
133+
[JBNotNull]
124134
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
125135
IEnumerable<TNodeItem> items,
126136
Predicate<TNodeItem, TNodeItem> connector,
@@ -138,6 +148,8 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
138148
/// <returns>
139149
/// Sorting result
140150
/// </returns>
151+
[return: DotNetNotNull]
152+
[JBNotNull]
141153
public static IEnumerable<TNodeItem> Sort<TNodeItem>(
142154
IEnumerable<TNodeItem> items,
143155
Predicate<TNodeItem, TNodeItem> connector,
@@ -161,6 +173,8 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem>(
161173
/// <returns>
162174
/// Sorting result
163175
/// </returns>
176+
[return: DotNetNotNull]
177+
[JBNotNull]
164178
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
165179
IEnumerable<TNodeItem> items,
166180
Predicate<TNodeItem, TNodeItem> connector,
@@ -181,9 +195,16 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem>(
181195
/// <returns>Sorting result, if there were no loops;
182196
/// otherwise, <see langword="null" />.
183197
/// In this case <paramref name="nodes"/> will contain only the loop edges.</returns>
198+
[JBCanBeNull]
184199
public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
185200
List<Node<TNodeItem, TConnectionItem>> nodes,
186-
out List<Node<TNodeItem, TConnectionItem>> loops) => SortInternal(nodes, out loops).sorted ?? Array.Empty<TNodeItem>();
201+
out List<Node<TNodeItem, TConnectionItem>> loops)
202+
{
203+
var (sorted, count) = SortInternal(nodes, out loops) /* ?? Array.Empty<TNodeItem>()*/;
204+
return (sorted is not null && count == 0)
205+
? Array.Empty<TNodeItem>()
206+
: sorted;
207+
}
187208

188209
/// <summary>
189210
/// Sorts the specified oriented graph of the nodes in their topological order
@@ -194,14 +215,17 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
194215
/// <returns>Sorting result, if there were no loops;
195216
/// otherwise, <see langword="null" />.
196217
/// In this case <paramref name="nodes"/> will contain only the loop edges.</returns>
218+
[JBCanBeNull]
197219
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem, TConnectionItem>(
198220
List<Node<TNodeItem, TConnectionItem>> nodes,
199221
out List<Node<TNodeItem, TConnectionItem>> loops)
200222
{
201223
var (sorted, count) = SortInternal(nodes, out loops);
202-
return (sorted is null || count == 0)
203-
? Array.Empty<TNodeItem>()
204-
: sorted.ToArray(count);
224+
return (sorted is null)
225+
? null
226+
: count == 0
227+
? Array.Empty<TNodeItem>()
228+
: sorted.ToArray(count);
205229
}
206230

207231
/// <summary>
@@ -211,6 +235,8 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem, TConnectionItem>(
211235
/// <param name="nodes">The nodes.</param>
212236
/// <param name="removedEdges">Edges removed to make graph non-cyclic.</param>
213237
/// <returns>Sorting result.</returns>
238+
[return: DotNetNotNull]
239+
[JBNotNull]
214240
public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
215241
IEnumerable<Node<TNodeItem, TConnectionItem>> nodes,
216242
out List<NodeConnection<TNodeItem, TConnectionItem>> removedEdges) =>
@@ -223,6 +249,8 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
223249
/// <param name="nodes">The nodes.</param>
224250
/// <param name="removedEdges">Edges removed to make graph non-cyclic.</param>
225251
/// <returns>Sorting result.</returns>
252+
[return: DotNetNotNull]
253+
[JBNotNull]
226254
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem, TConnectionItem>(
227255
IEnumerable<Node<TNodeItem, TConnectionItem>> nodes,
228256
out List<NodeConnection<TNodeItem, TConnectionItem>> removedEdges) =>
@@ -236,6 +264,8 @@ public static IReadOnlyList<TNodeItem> SortToList<TNodeItem, TConnectionItem>(
236264
/// <param name="removedEdges">Edges removed to make graph non-cyclic.</param>
237265
/// <param name="removeWholeNode">If <see langword="true"/> removes whole node in the case of loop, otherwise removes only one edge.</param>
238266
/// <returns>Sorting result.</returns>
267+
[return: DotNetNotNull]
268+
[JBNotNull]
239269
public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
240270
IEnumerable<Node<TNodeItem, TConnectionItem>> nodes,
241271
out List<NodeConnection<TNodeItem, TConnectionItem>> removedEdges,
@@ -250,6 +280,8 @@ public static IEnumerable<TNodeItem> Sort<TNodeItem, TConnectionItem>(
250280
/// <param name="removedEdges">Edges removed to make graph non-cyclic.</param>
251281
/// <param name="removeWholeNode">If <see langword="true"/> removes whole node in the case of loop, otherwise removes only one edge.</param>
252282
/// <returns>Sorting result.</returns>
283+
[return: DotNetNotNull]
284+
[JBNotNull]
253285
public static IReadOnlyList<TNodeItem> SortToList<TNodeItem, TConnectionItem>(
254286
IEnumerable<Node<TNodeItem, TConnectionItem>> nodes,
255287
out List<NodeConnection<TNodeItem, TConnectionItem>> removedEdges,

0 commit comments

Comments
 (0)