mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-05 14:31:31 +00:00
Implement simple order sort
This commit is contained in:
@ -50,6 +50,62 @@ public class ApkPackageGraph {
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkPackageGraph {
|
||||
public func orderSort(breakCycles: Bool = true) throws(SortError) -> [ApkPackageGraphNode] {
|
||||
var stack = [ApkPackageGraphNode]()
|
||||
var resolving = Set<ApkIndex.Index>()
|
||||
var visited = Set<ApkIndex.Index>()
|
||||
var ignoring = Set<ApkIndex.Index>()
|
||||
for node in self.shallowIsolates {
|
||||
try orderSort(node, &stack, &resolving, &visited, &ignoring, breakCycles)
|
||||
}
|
||||
return stack
|
||||
}
|
||||
|
||||
internal func orderSort(
|
||||
_ node: ApkPackageGraphNode,
|
||||
_ stack: inout [ApkPackageGraphNode],
|
||||
_ resolving: inout Set<ApkIndex.Index>,
|
||||
_ visited: inout Set<ApkIndex.Index>,
|
||||
_ ignoring: inout Set<ApkIndex.Index>,
|
||||
_ breakCycles: Bool
|
||||
) throws(SortError) {
|
||||
for dep in node.children {
|
||||
let depID = dep.packageID
|
||||
guard !ignoring.contains(depID) else {
|
||||
continue
|
||||
}
|
||||
|
||||
guard !resolving.contains(depID) else {
|
||||
throw .cyclicDependency(cycles: "\(node) -> \(dep)")
|
||||
}
|
||||
|
||||
if !visited.contains(depID) {
|
||||
resolving.insert(depID)
|
||||
let depNode = self._nodes[depID]
|
||||
do {
|
||||
try orderSort(depNode, &stack, &resolving, &visited, &ignoring, breakCycles)
|
||||
} catch {
|
||||
guard breakCycles else {
|
||||
throw error
|
||||
}
|
||||
|
||||
stack.append(depNode)
|
||||
ignoring.insert(depID)
|
||||
try orderSort(depNode, &stack, &resolving, &visited, &ignoring, breakCycles)
|
||||
ignoring.remove(depID)
|
||||
}
|
||||
resolving.remove(depID)
|
||||
visited.insert(depID)
|
||||
}
|
||||
}
|
||||
|
||||
if !stack.contains(node) {
|
||||
stack.append(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ApkPackageGraph {
|
||||
func findDependencyCycle(node: ApkPackageGraphNode) -> (ApkPackageGraphNode, ApkPackageGraphNode)? {
|
||||
var resolving = Set<Int>()
|
||||
|
@ -30,7 +30,11 @@ struct DpkGraphCommand: AsyncParsableCommand {
|
||||
try graph.deepIsolates.map { $0.package.nameDescription }.joined(separator: "\n")
|
||||
.write(to: URL(filePath: "deepIsolates.txt"), atomically: false, encoding: .utf8)
|
||||
|
||||
timerStart = DispatchTime.now()
|
||||
#if false
|
||||
let sorted = try graph.parallelOrderSort()
|
||||
print("Parallel sort took \(timerStart.distance(to: .now()).seconds) seconds")
|
||||
|
||||
if var out = TextFileWriter(URL(filePath: "sorted.txt")) {
|
||||
for (i, set) in sorted.enumerated() {
|
||||
print("\(i):\n", to: &out)
|
||||
@ -39,6 +43,13 @@ struct DpkGraphCommand: AsyncParsableCommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
let sorted = try graph.orderSort()
|
||||
print("Order sort took \(timerStart.distance(to: .now()).seconds) seconds")
|
||||
|
||||
try sorted.map(String.init).joined(separator: "\n")
|
||||
.write(to: URL(filePath: "sorted.txt"), atomically: false, encoding: .utf8)
|
||||
#endif
|
||||
} catch {
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
|
Reference in New Issue
Block a user