mirror of
				https://github.com/GayPizzaSpecifications/darwin-apk.git
				synced 2025-11-04 07:59:38 +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