mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-06 22:51:34 +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 {
|
extension ApkPackageGraph {
|
||||||
func findDependencyCycle(node: ApkPackageGraphNode) -> (ApkPackageGraphNode, ApkPackageGraphNode)? {
|
func findDependencyCycle(node: ApkPackageGraphNode) -> (ApkPackageGraphNode, ApkPackageGraphNode)? {
|
||||||
var resolving = Set<Int>()
|
var resolving = Set<Int>()
|
||||||
|
@ -30,7 +30,11 @@ struct DpkGraphCommand: AsyncParsableCommand {
|
|||||||
try graph.deepIsolates.map { $0.package.nameDescription }.joined(separator: "\n")
|
try graph.deepIsolates.map { $0.package.nameDescription }.joined(separator: "\n")
|
||||||
.write(to: URL(filePath: "deepIsolates.txt"), atomically: false, encoding: .utf8)
|
.write(to: URL(filePath: "deepIsolates.txt"), atomically: false, encoding: .utf8)
|
||||||
|
|
||||||
|
timerStart = DispatchTime.now()
|
||||||
|
#if false
|
||||||
let sorted = try graph.parallelOrderSort()
|
let sorted = try graph.parallelOrderSort()
|
||||||
|
print("Parallel sort took \(timerStart.distance(to: .now()).seconds) seconds")
|
||||||
|
|
||||||
if var out = TextFileWriter(URL(filePath: "sorted.txt")) {
|
if var out = TextFileWriter(URL(filePath: "sorted.txt")) {
|
||||||
for (i, set) in sorted.enumerated() {
|
for (i, set) in sorted.enumerated() {
|
||||||
print("\(i):\n", to: &out)
|
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 {
|
} catch {
|
||||||
fatalError(error.localizedDescription)
|
fatalError(error.localizedDescription)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user