2020-11-04 15:59:33 +00:00
|
|
|
|
// SPDX-License-Identifier: MIT
|
2020-12-04 11:15:29 +00:00
|
|
|
|
// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved.
|
2020-11-04 15:59:33 +00:00
|
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
|
|
extension Array {
|
|
|
|
|
|
|
|
|
|
/// Returns an array containing the results of mapping the given closure over the sequence’s
|
|
|
|
|
/// elements concurrently.
|
|
|
|
|
///
|
|
|
|
|
/// - Parameters:
|
|
|
|
|
/// - queue: The queue for performing concurrent computations.
|
|
|
|
|
/// If the given queue is serial, the values are mapped in a serial fashion.
|
|
|
|
|
/// Pass `nil` to perform computations on the current queue.
|
|
|
|
|
/// - transform: the block to perform concurrent computations over the given element.
|
|
|
|
|
/// - Returns: an array of concurrently computed values.
|
|
|
|
|
func concurrentMap<U>(queue: DispatchQueue?, _ transform: (Element) -> U) -> [U] {
|
|
|
|
|
var result = [U?](repeating: nil, count: self.count)
|
|
|
|
|
let resultQueue = DispatchQueue(label: "ConcurrentMapQueue")
|
|
|
|
|
|
|
|
|
|
let execute = queue?.sync ?? { $0() }
|
|
|
|
|
|
|
|
|
|
execute {
|
2020-12-02 14:08:45 +00:00
|
|
|
|
DispatchQueue.concurrentPerform(iterations: self.count) { index in
|
2020-11-04 15:59:33 +00:00
|
|
|
|
let value = transform(self[index])
|
|
|
|
|
resultQueue.sync {
|
|
|
|
|
result[index] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.map { $0! }
|
|
|
|
|
}
|
|
|
|
|
}
|