lib.lists.toposort: avoid extra function calls while recursing

This commit is contained in:
Eman Resu
2026-06-24 18:29:21 -04:00
parent 099a322b3a
commit 7d2f66c0ad
+25 -19
View File
@@ -1247,27 +1247,33 @@ rec {
:::
*/
toposort =
before: list:
before:
let
dfsthis = listDfs true before list;
toporest = toposort before (dfsthis.visited ++ dfsthis.rest);
dfs = listDfs true before;
recurse =
list:
let
dfsthis = dfs list;
toporest = recurse (dfsthis.visited ++ dfsthis.rest);
in
if length list < 2 then
# finish
{ result = list; }
else if dfsthis ? cycle then
# there's a cycle, starting from the current vertex, return it
{
cycle = reverseList ([ dfsthis.cycle ] ++ dfsthis.visited);
inherit (dfsthis) loops;
}
else if toporest ? cycle then
# there's a cycle somewhere else in the graph, return it
toporest
# Slow, but short. Can be made a bit faster with an explicit stack.
else
# there are no cycles
{ result = [ dfsthis.minimal ] ++ toporest.result; };
in
if length list < 2 then
# finish
{ result = list; }
else if dfsthis ? cycle then
# there's a cycle, starting from the current vertex, return it
{
cycle = reverseList ([ dfsthis.cycle ] ++ dfsthis.visited);
inherit (dfsthis) loops;
}
else if toporest ? cycle then
# there's a cycle somewhere else in the graph, return it
toporest
# Slow, but short. Can be made a bit faster with an explicit stack.
else
# there are no cycles
{ result = [ dfsthis.minimal ] ++ toporest.result; };
recurse;
/**
Sort a list based on a comparator function which compares two