Guest User

Untitled

a guest
Apr 25th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.33 KB | None | 0 0
  1. import Foundation
  2.  
  3. //
  4. // Pool.swift
  5. //
  6.  
  7. open class Pool<T> {
  8.  
  9. // MARK: Initialization
  10. /**
  11. - parameter maxElementCount: Specifies the maximum number of element that the pool can manage.
  12. - parameter factory: Closure used to create new items for the pool.
  13. */
  14. public init(maxElementCount: Int, factory: @escaping () throws -> T) {
  15. self.factory = factory
  16. self.maxElementCount = maxElementCount
  17. self.semaphore = DispatchSemaphore(value: maxElementCount)
  18. }
  19.  
  20. // MARK: Setting and Getting Attributes
  21. /// The maximum number of element that the pool can manage.
  22. public let maxElementCount: Int
  23.  
  24. /// Closure used to create new items for the pool.
  25. public let factory: () throws -> T
  26.  
  27. // MARK: Storage
  28. var elements = [T]()
  29.  
  30. var elementCount = 0
  31.  
  32. // MARK: Concurrency Management
  33.  
  34. private let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".Pool")
  35.  
  36. private let semaphore: DispatchSemaphore
  37.  
  38. // MARK: Accessing Elements
  39. public func dequeue() throws -> T {
  40.  
  41. // when count reaches zero, calls to the semaphore will block
  42. guard self.semaphore.wait(timeout: .distantFuture) == .success else {
  43. throw PoolError.drawTimeOut
  44. }
  45.  
  46. return try self.queue.sync {
  47.  
  48. guard self.elements.isEmpty, self.elementCount < self.maxElementCount else {
  49.  
  50. // Use an existing element
  51. return self.elements.removeFirst()
  52. }
  53.  
  54. // Create a new element
  55. do {
  56. let element = try self.factory()
  57. self.elementCount += 1
  58.  
  59. return element
  60.  
  61. } catch {
  62. self.semaphore.signal()
  63. throw PoolError.factoryError(error)
  64. }
  65. }
  66. }
  67.  
  68. public func enqueue(_ element: T, completion: (() -> Void)? = nil) {
  69.  
  70. self.queue.async {
  71. self.elements.append(element)
  72. self.semaphore.signal()
  73. completion?()
  74. }
  75. }
  76.  
  77. deinit {
  78. for _ in 0..<self.elementCount {
  79. self.semaphore.signal()
  80. }
  81. }
  82. }
  83.  
  84. public enum PoolError: Swift.Error {
  85. case drawTimeOut
  86. case factoryError(Swift.Error)
  87. }
Add Comment
Please, Sign In to add comment