Skip to content

Commit

Permalink
Add examples for package manager and spreadsheet (#13)
Browse files Browse the repository at this point in the history
The examples help me to understand how to define the API. Later, they
can be used for tests and for documentation.

See pull request #13
  • Loading branch information
ikelax authored Jan 31, 2025
1 parent 06fd03e commit 8c7e8b2
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 14 deletions.
16 changes: 2 additions & 14 deletions Sources/SwiftDependencyGraphs/DependencyGraph.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,10 @@ public struct DependencyGraph<V> where V: Hashable, V: Identifiable {

// For efficiency, two hashsets are maintained.

/// Incoming edges of a vertex are directed edges that the vertex is the destination.
///
/// The edge `v --> w` (or `(v, w)`) is an incoming edge of `w`, but not of `v`.
/// In this case, `w` is a key and `v` its value.
///
/// - Note: Informally speaking, `v` is adjacent to `w`, or a neighbour of `w`, and
/// `w` is targeted by `v`'s arrow.
/// The dictionary maps the edge `v --> w` as `[w: v]`. `w` is the key and `v` the value.
public internal(set) var incomingEdges: [V.ID: OrderedSet<V>] = [:]

/// Outgoing edges of a vertex are directed edges that the vertex is the origin.
///
/// The edge `v --> w` (or `(v, w)`) is an outgoing edge of `v`, but not of `w`.
/// In this case, `v` is a key and `w` its value.
///
/// - Note: Informally speaking, `v` is adjacent to `w`, or a neighbour of `w`, and
/// its arrow points to `w`.
/// The dictionary maps the edge `v --> w` as `[v: w]`. `v` is the key and `w` the value.
public internal(set) var outgoingEdges: [V.ID: OrderedSet<V>] = [:]

func contains(vertex: V) -> Bool {
Expand Down
5 changes: 5 additions & 0 deletions Tests/Examples/PackageManager/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
struct Package: Identifiable, Hashable {
let id: String
let name: String
let author: String
}
25 changes: 25 additions & 0 deletions Tests/Examples/PackageManager/PackageGraph.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import DependencyGraphs

// A -> B means that A depends on B
typealias PackageGraph = DependencyGraph<Package>

extension PackageGraph {
func findAllDependencies(of package: Package) -> [Package] {
// Traverse the graph starting from package
// and collect vertices visited
[]
}

// This should be in `DependencyGraph`.
func insert(package: Package, withDependencies dependencies: [Package]) {
// Call `insert` method in `DependencyGraph`.
// `insert` also inserts the dependencies and checks
// if circular dependencies would be introduced.
}

func findDependents(of package: Package) -> [Package] {
// Traverse graph in reverse direction
// and collect packages.
[]
}
}
5 changes: 5 additions & 0 deletions Tests/Examples/SpreadSheet/Cell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
struct Cell: Identifiable, Hashable {
let id: Coordinate
let computedValue: Int
let expression: String
}
4 changes: 4 additions & 0 deletions Tests/Examples/SpreadSheet/Coordinate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct Coordinate: Hashable {
let row: Int
let column: Int
}
36 changes: 36 additions & 0 deletions Tests/Examples/SpreadSheet/SpreadSheet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import DependencyGraphs

// A -> B means that A depends on B
typealias SpreadSheet = DependencyGraph<Cell>

extension SpreadSheet {
// This should be in `DependencyGraph`.
func insert(cell: Cell, withDependencies dependencies: [Cell]) {
// Call `insert` method in `DependencyGraph`.
// `inserts` also inserts the dependencies of `cell`
// and checks if circular dependencies would be introduced.
}

func update(cell: Cell, with newExpression: String) {
compute(expression: newExpression)
// Call `update` method in `DependencyGraph`
// to update `expression` and `computedValue` for `cell`.
// `update` also updates the dependencies of `cell`
// and checks if circular dependencies would be introduced.
// We need to recompute values of cells that depend on `cell`.
// Traverse graph with dfs starting from `cell`
// and update their values.
}

func compute(expression: String) -> Double {
// Parse expression and get cell names C it depends on.
// Find C in `vertices` dictionary.
// We don't need to recompute value of C.
// Compute expression.
0.0
}

// This should be in `DependencyGraph`.
// There is no domain specific logic here.
func remove(cell: Cell) {}
}

0 comments on commit 8c7e8b2

Please sign in to comment.