Skip to content

Instantly share code, notes, and snippets.

@tkausch
Created January 26, 2022 22:55
Show Gist options
  • Save tkausch/1c5965e5f92fd0d6d8ec2267c1b4823b to your computer and use it in GitHub Desktop.
Save tkausch/1c5965e5f92fd0d6d8ec2267c1b4823b to your computer and use it in GitHub Desktop.
Fast Queue implementation using array RingBuffer
import Foundation
public struct Queue<T> {
private var array: Array<T?>
private var availableSpaceCount: Int
private var readIndex: Int
private var writeIndex: Int
public var isFull: Bool {
return availableSpaceCount == 0
}
public var isEmpty: Bool {
return availableSpaceCount == array.count
}
public init(capacity: Int) {
array = [T?](repeating: nil, count: capacity)
readIndex = 0
writeIndex = 0
availableSpaceCount = capacity
}
public mutating func enqueue(_ element: T) -> Bool {
guard !isFull else { return false }
defer {
// adjust invariants Dijkstra would love it :-)
writeIndex += 1
writeIndex %= array.count
availableSpaceCount -= 1
}
array[writeIndex] = element
return true
}
public mutating func dequeue() -> T? {
guard !isEmpty else {
return nil
}
defer {
// adjust invariants Dijkstra would love it :-)
array[readIndex] = nil
readIndex += 1
readIndex %= array.count
availableSpaceCount += 1
}
return array[readIndex]
}
public func peek() -> T? {
guard !isEmpty else {
return nil
}
return array[readIndex]
}
}
extension Queue: Sequence {
public func makeIterator() -> AnyIterator<T> {
var index = readIndex
var count = array.count - availableSpaceCount
return AnyIterator {
guard count > 0 else { return nil }
defer {
index += 1
index %= self.array.count
count -= 1
}
return self.array[index]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment