|
| 1 | +// DesignAlgorithmsKit |
| 2 | +// Structural Pattern: ThreadSafe Array |
| 3 | +// |
| 4 | +// A thread-safe wrapper around a standard Swift Array. |
| 5 | +// Uses ThreadSafe<[Element]> internally. |
| 6 | + |
| 7 | +import Foundation |
| 8 | + |
| 9 | +/// A thread-safe array wrapper. |
| 10 | +/// Provides safe concurrent access to an array using an internal lock. |
| 11 | +public final class ThreadSafeArray<Element>: @unchecked Sendable { |
| 12 | + private let storage: ThreadSafe<[Element]> |
| 13 | + |
| 14 | + public init(_ array: [Element] = []) { |
| 15 | + self.storage = ThreadSafe(array) |
| 16 | + } |
| 17 | + |
| 18 | + /// The number of elements in the array. |
| 19 | + public var count: Int { |
| 20 | + storage.read { $0.count } |
| 21 | + } |
| 22 | + |
| 23 | + /// A Boolean value indicating whether the collection is empty. |
| 24 | + public var isEmpty: Bool { |
| 25 | + storage.read { $0.isEmpty } |
| 26 | + } |
| 27 | + |
| 28 | + /// Adds a new element at the end of the array. |
| 29 | + public func append(_ newElement: Element) { |
| 30 | + storage.write { $0.append(newElement) } |
| 31 | + } |
| 32 | + |
| 33 | + /// Adds the elements of a sequence to the end of the array. |
| 34 | + public func append<S>(contentsOf newElements: S) where S : Sequence, Element == S.Element { |
| 35 | + storage.write { $0.append(contentsOf: newElements) } |
| 36 | + } |
| 37 | + |
| 38 | + /// Removes and returns the element at the specified position. |
| 39 | + public func remove(at index: Int) -> Element { |
| 40 | + storage.write { $0.remove(at: index) } |
| 41 | + } |
| 42 | + |
| 43 | + /// Removes all elements from the array. |
| 44 | + public func removeAll(keepingCapacity keepCapacity: Bool = false) { |
| 45 | + storage.write { $0.removeAll(keepingCapacity: keepCapacity) } |
| 46 | + } |
| 47 | + |
| 48 | + /// Accesses the element at the specified position. |
| 49 | + /// Note: This is not efficient for iteration. Use `read` or `map` for batch operations. |
| 50 | + public subscript(index: Int) -> Element { |
| 51 | + get { |
| 52 | + storage.read { $0[index] } |
| 53 | + } |
| 54 | + set { |
| 55 | + storage.write { $0[index] = newValue } |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + /// Returns an array containing the results of mapping the given closure over the sequence’s elements. |
| 60 | + public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T] { |
| 61 | + try storage.read { try $0.map(transform) } |
| 62 | + } |
| 63 | + |
| 64 | + /// Returns an array containing the non-nil results of calling the given transformation with each element of this sequence. |
| 65 | + public func compactMap<T>(_ transform: (Element) throws -> T?) rethrows -> [T] { |
| 66 | + try storage.read { try $0.compactMap(transform) } |
| 67 | + } |
| 68 | + |
| 69 | + /// Returns an array containing, in order, the elements of the sequence that satisfy the given predicate. |
| 70 | + public func filter(_ isIncluded: (Element) throws -> Bool) rethrows -> [Element] { |
| 71 | + try storage.read { try $0.filter(isIncluded) } |
| 72 | + } |
| 73 | + |
| 74 | + /// Returns the first element of the sequence that satisfies the given predicate. |
| 75 | + public func first(where predicate: (Element) throws -> Bool) rethrows -> Element? { |
| 76 | + try storage.read { try $0.first(where: predicate) } |
| 77 | + } |
| 78 | + |
| 79 | + /// Returns a Boolean value indicating whether the sequence contains an element that satisfies the given predicate. |
| 80 | + public func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool { |
| 81 | + try storage.read { try $0.contains(where: predicate) } |
| 82 | + } |
| 83 | + |
| 84 | + /// Returns a new array containing the elements of this array. |
| 85 | + public var allElements: [Element] { |
| 86 | + storage.read { $0 } |
| 87 | + } |
| 88 | + |
| 89 | + /// Execute a block with the array for reading |
| 90 | + public func read<Result>(_ block: ([Element]) throws -> Result) rethrows -> Result { |
| 91 | + try storage.read(block) |
| 92 | + } |
| 93 | + |
| 94 | + /// Execute a block with the array for writing |
| 95 | + public func write<Result>(_ block: (inout [Element]) throws -> Result) rethrows -> Result { |
| 96 | + try storage.write(block) |
| 97 | + } |
| 98 | +} |
0 commit comments