Added Alternative DependencySorter to deal with cycles#219
Open
Added Alternative DependencySorter to deal with cycles#219
Conversation
…list of dependencies without cycles
Author
|
@luigi-rosso, got an implementation of this using Tarjan's algorithm going. the nice guys here actually implemented the algorithm in a pretty portable way: (https://github.com/dart-lang/graphs - BSD license) class TarjansDependencySorter extends DependencySorter {
HashSet<ActorComponent> _cycleNodes;
HashSet<ActorComponent> get cycleNodes => _cycleNodes;
TarjansDependencySorter() {
_perm = HashSet<ActorComponent>();
_temp = HashSet<ActorComponent>();
_cycleNodes = HashSet<ActorComponent>();
}
@override
List<ActorComponent> sort(ActorComponent root) {
_order = <ActorComponent>[];
if (visit(root)) {
return _order;
} else {
_perm.clear();
_temp.clear();
_cycleNodes.clear();
_order.clear();
// returns a list of cycles, which themselves
var cycles = stronglyConnectedComponents<ActorComponent>(
[root], (ActorComponent node) => node.dependents);
cycles.forEach((cycle) {
// looks like the algorithm places each node in
// a single item list if its not part of a cycle
if (cycle.length > 1) {
cycle.forEach((cycleMember) {
_cycleNodes.add(cycleMember);
});
}
});
// visit again, this time skip any nodes that we know are part of a cycle
visit(root, cycleNodes: _cycleNodes);
}
return _order;
}
}feels a bit cleaner perhaps |
…ile so that vscode finds it (wants the file to end in _test.dart).
Contributor
|
YES! This is awesome. I made two minor tweaks: Renamed the test file to *_test.dart so that VSCode and the test cli find it (seems to want the file to end in _test.dart). Moved the cycles tracking out of DependencySorter completely to keep it a little cleaner/faster (no need to instance and pass cycles hash set around prematurely). |
luigi-rosso
reviewed
Jan 10, 2020
mjtalbot
commented
Jan 13, 2020
| } | ||
|
|
||
| @override | ||
| bool visit(ActorComponent n) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Couple of outstanding questions:
tests:
Manually tested drawing the penguin using this dependency sorter.
Added some tests to keep track of some scenarios I've been trying to make sure work. not sure if we want to fit tests in like this
To run the tests
pub run test test/test_dependency_sorter.dartdoes the trick.Some gotchas:
the order that the nodes are evaluated is not the same as in the original Dependency Sorter
Alternatives:
this looks pretty promising really. looks like a an established algorithm to find all cycles: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm.
Using this we could simply use the current algorithm, and if it detects cycles, find all nodes with cycles and then re run the current algorithm, skipping over any nodes that are part of a cycle. We'll of course lose a little bit