Skip to content

Instantly share code, notes, and snippets.

@ABridoux
Last active October 13, 2023 09:42
Show Gist options
  • Select an option

  • Save ABridoux/43a4c1dab95f80cd1cdbb0905d628de3 to your computer and use it in GitHub Desktop.

Select an option

Save ABridoux/43a4c1dab95f80cd1cdbb0905d628de3 to your computer and use it in GitHub Desktop.

Revisions

  1. ABridoux revised this gist Oct 11, 2023. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions AsyncQueue.swift
    Original file line number Diff line number Diff line change
    @@ -11,15 +11,15 @@ struct Queue<Element> {

    extension Queue {
    mutating func enqueue(_ element: Element) {
    enqueueArray.append(element) // O(1)
    enqueueArray.append(element)
    }

    mutating func dequeue() -> Element? {
    if dequeueArray.isEmpty {
    dequeueArray = enqueueArray.reversed() // O(n)
    enqueueArray.removeAll() // O(n)
    dequeueArray = enqueueArray.reversed()
    enqueueArray.removeAll()
    }
    return dequeueArray.popLast() // O(1)
    return dequeueArray.popLast()
    }
    }

  2. ABridoux created this gist Oct 11, 2023.
    83 changes: 83 additions & 0 deletions AsyncQueue.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,83 @@
    // MARK: - Queue

    struct Queue<Element> {
    private var enqueueArray: [Element] = []
    private var dequeueArray: [Element] = []

    var isEmpty: Bool {
    enqueueArray.isEmpty && dequeueArray.isEmpty
    }
    }

    extension Queue {
    mutating func enqueue(_ element: Element) {
    enqueueArray.append(element) // O(1)
    }

    mutating func dequeue() -> Element? {
    if dequeueArray.isEmpty {
    dequeueArray = enqueueArray.reversed() // O(n)
    enqueueArray.removeAll() // O(n)
    }
    return dequeueArray.popLast() // O(1)
    }
    }

    extension Queue {
    mutating func removeAll() {
    enqueueArray.removeAll()
    dequeueArray.removeAll()
    }
    }

    // MARK: - AsyncQueue

    actor AsyncQueue<Element> {
    private var queue = Queue<Element>()

    private var nextContinuation: CheckedContinuation<Element, Never>?

    nonisolated var elements: Elements { Elements(queue: self) }
    }

    extension AsyncQueue {
    func enqueue(_ element: Element) {
    if let nextContinuation {
    nextContinuation.resume(returning: element)
    self.nextContinuation = nil
    } else {
    queue.enqueue(element)
    }
    }
    }

    // MARK: - AsyncIteratorProtocol

    extension AsyncQueue: AsyncIteratorProtocol {

    func next() async -> Element? {
    guard nextContinuation == nil else { return nil }

    if let next = queue.dequeue() {
    return next
    } else {
    return await withCheckedContinuation { nextContinuation = $0 }
    }
    }
    }

    // MARK: - Elements

    extension AsyncQueue {

    struct Elements: AsyncSequence {

    typealias AsyncIterator = AsyncQueue

    let queue: AsyncQueue

    func makeAsyncIterator() -> AsyncQueue {
    queue
    }
    }
    }