diff --git a/Sources/PNDependencyGraph/PNNode.swift b/Sources/PNDependencyGraph/PNNode.swift index 321c31c..5e21e87 100644 --- a/Sources/PNDependencyGraph/PNNode.swift +++ b/Sources/PNDependencyGraph/PNNode.swift @@ -1,23 +1,64 @@ import Foundation +/// A node in a dependency graph. +/// +/// The `PNNode` class represents a single node within a dependency graph. Each node +/// has a unique identifier and can have dependencies on other nodes. +/// +/// Example usage: +/// ```swift +/// let node = PNNode(identifier: "node1") +/// let dependency = PNNode(identifier: "node2") +/// node.addDependency(node: dependency) +/// ``` public final class PNNode: @unchecked Sendable, Equatable { + /// Compares two `PNNode` instances for equality. + /// + /// Two nodes are considered equal if they are the same instance (identity comparison). + /// + /// - Parameters: + /// - lhs: The left-hand side node to compare. + /// - rhs: The right-hand side node to compare. + /// - Returns: `true` if the nodes are identical; otherwise, `false`. public static func == (lhs: PNNode, rhs: PNNode) -> Bool { lhs === rhs } + /// A unique identifier for the node. public let identifier: String + + /// The dependencies of this node. + /// + /// This property returns an array of nodes that this node depends on. + /// The dependencies are thread-safe and can be accessed from multiple threads. public var dependencies: [PNNode] { synchronization.withLock { unsafeDependencies } } + + /// The internal storage for dependencies. + /// + /// This is used internally to store the actual dependencies in a thread-safe manner. private var unsafeDependencies: [PNNode] = [] + + /// A lock used to synchronize access to dependencies. + /// + /// This ensures that the `dependencies` property can be safely accessed from multiple threads. private let synchronization = NSLock() + /// Initializes a new instance of `PNNode` with the specified identifier. + /// + /// - Parameter newIdentifier: A unique identifier for the node. init(identifier newIdentifier: String) { identifier = newIdentifier } + /// Adds a dependency to this node. + /// + /// This method adds a node to the list of dependencies for this node. + /// + /// - Parameter node: The node that this node depends on. public func addDependency(node: PNNode) { synchronization.withLock { unsafeDependencies.append(node) diff --git a/Sources/PNDependencyGraph/Visitors/PNMultithreadVisitor.swift b/Sources/PNDependencyGraph/Visitors/PNMultithreadVisitor.swift index 0d0b909..8c74626 100644 --- a/Sources/PNDependencyGraph/Visitors/PNMultithreadVisitor.swift +++ b/Sources/PNDependencyGraph/Visitors/PNMultithreadVisitor.swift @@ -1,14 +1,37 @@ import Foundation +/// A multithreaded visitor for traversing a compiled dependency graph. +/// +/// The `PNMultithreadVisitor` class allows for concurrent traversal of a dependency graph, +/// executing node visits in parallel using an operation queue. It ensures that the first +/// node is visited synchronously while all other nodes are processed in parallel. +/// +/// Example usage: +/// ```swift +/// let visitor = PNMultithreadVisitor(graph: myGraph) +/// visitor.visit { node in +/// print("Visiting node: \(node)") +/// } +/// ``` public final class PNMultithreadVisitor { private let graph: PNCompiledGraph private let queue = OperationQueue() + + /// Initializes a new instance of `PNMultithreadVisitor` with the specified graph. + /// + /// - Parameter newGraph: The compiled dependency graph to visit. public init(graph newGraph: PNCompiledGraph) { graph = newGraph queue.qualityOfService = .userInitiated queue.maxConcurrentOperationCount = graph.nodes.count - 1 } + /// Traverses the dependency graph, visiting each node. + /// + /// The first node in the graph is visited synchronously, while all other nodes + /// are processed concurrently in an operation queue. + /// + /// - Parameter completion: A closure to be called for each visited node. public func visit(completion: @Sendable @escaping (PNNode) -> Void) { guard let first = graph.nodes.first else { return diff --git a/Sources/PNDependencyGraph/Visitors/PNSingleThreadVisitor.swift b/Sources/PNDependencyGraph/Visitors/PNSingleThreadVisitor.swift index 62739c1..1864836 100644 --- a/Sources/PNDependencyGraph/Visitors/PNSingleThreadVisitor.swift +++ b/Sources/PNDependencyGraph/Visitors/PNSingleThreadVisitor.swift @@ -1,9 +1,31 @@ public final class PNSingleThreadVisitor { + /// A single-threaded visitor for traversing a compiled dependency graph. + /// + /// The `PNSingleThreadVisitor` class allows for sequential traversal of a dependency graph, + /// executing node visits in a single thread. All nodes are processed in the order they appear + /// in the graph. + /// + /// Example usage: + /// ```swift + /// let visitor = PNSingleThreadVisitor(graph: myGraph) + /// visitor.visit { node in + /// print("Visiting node: \(node)") + /// } + /// ``` private let graph: PNCompiledGraph + + /// Initializes a new instance of `PNSingleThreadVisitor` with the specified graph. + /// + /// - Parameter graph: The compiled dependency graph to visit. public init(graph: PNCompiledGraph) { self.graph = graph } + /// Traverses the dependency graph, visiting each node in sequence. + /// + /// All nodes in the graph are visited one after another in the order they appear. + /// + /// - Parameter completion: A closure to be called for each visited node. public func visit(completion: (PNNode) -> Void) { for node in graph.nodes { completion(node)