-
-
Save mischa-hildebrand/470c03131a144b8cad1bc8c71972e526 to your computer and use it in GitHub Desktop.
A simple Generic Queue with different priority Levels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/// Subclass this Class with a non generic Type. | |
/// - note: Please override the init function with a private | |
/// access modifactor and create a singleton, so you | |
/// can ensure that there are no more Queues as you | |
/// are expecting. | |
internal class QueueHandler<T> { | |
private var queues: Set<Queue<T>> | |
/// Checks if any Queue contains an Element waiting for execution. | |
internal final var isEmpty: Bool { | |
var isEmpty: Bool = true | |
queues.forEach { (queue) in | |
if queue.isEmpty == false { | |
isEmpty = false | |
} | |
} | |
return isEmpty | |
} | |
/// Initializes a new QueueHandler with a mainQueue | |
/// If you override this class make the init function private | |
/// and create a singleton of your `QueueHandler` Subclass. | |
internal init() { | |
queues = [Queue(priority: .mainQueue)] | |
} | |
/// Enqueue an Element into a given prioritie's Queue. | |
/// - parameters: | |
/// - element: Generic Element which can be Enqueued | |
/// - priority: Element of `QueuePriority` representing the Priority | |
/// which should be used for the execution of this particular | |
/// Element. | |
internal final func enqueue(_ element: T, with priority: Queue<T>.Priority = Queue<T>.Priority.mainQueue) { | |
queues.insert(Queue<T>(priority: priority)) | |
queues.first(where: { $0.priority == priority })?.enqueue(element) | |
} | |
/// Deques an Element with the highest priority first. | |
/// - returns: The highest prioritized generic Elemnent of any queue | |
internal final func dequeue() -> T? { | |
var element: T? | |
queues.sorted(by: >).forEach({ (queue) in | |
if !queue.isEmpty { | |
element = queue.dequeue() | |
return | |
} | |
}) | |
return element | |
} | |
/// Shows the next Element with a given Priority. | |
/// - parameters: | |
/// - priority: Element of `QueuePriority` representing the Priority | |
/// which should be used to retrieve the next Element of | |
/// the given Queueu. | |
internal final func peak(with priority: Queue<T>.Priority = Queue<T>.Priority.mainQueue) -> T? { | |
return queues.first(where: { $0.priority == priority })?.peek() | |
} | |
} | |
/// Implementation of a simple Queue Structure, which | |
/// can be initialized and compared with their initialized | |
/// Priority. | |
internal final class Queue<T> { | |
/// Different Priority Levels for Queue Objects | |
public enum Priority: Int { | |
case low = 0 | |
case medium = 1 | |
case high = 2 | |
/// The priority Type for using the main Queue. | |
fileprivate static var mainQueue: Priority { | |
return .medium | |
} | |
} | |
private var queue: Array<T> = [] | |
fileprivate let priority: Priority | |
fileprivate var isEmpty: Bool { | |
return queue.isEmpty | |
} | |
/// Creates a new Queue Structure with the Priority | |
/// of a MainQueue. | |
fileprivate init() { | |
priority = Priority.mainQueue | |
} | |
fileprivate init(priority: Priority = .medium) { | |
self.priority = priority | |
} | |
fileprivate final func enqueue(_ element: T) { | |
queue.append(element) | |
} | |
fileprivate final func dequeue() -> T? { | |
if !isEmpty { | |
return queue.removeFirst() | |
} else { | |
return nil | |
} | |
} | |
fileprivate final func peek() -> T? { | |
if !isEmpty { | |
return queue.first | |
} else { | |
return nil | |
} | |
} | |
} | |
/// To Compare multiple Queues and store them in a Set | |
/// we have to implement the hashValue which is defined | |
/// in the `Hashable` Protocol. | |
extension Queue: Hashable { | |
internal var hashValue: Int { | |
return priority.hashValue | |
} | |
} | |
/// Types that conform to `Hashable` need to conform to | |
/// `Equatable` as well. | |
extension Queue: Equatable { | |
static func == (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority == rhs.priority | |
} | |
static func != (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority != rhs.priority | |
} | |
} | |
/// To compare multiple Queues by their Priority we | |
/// also need to implement the Comparable Protocol. | |
extension Queue: Comparable { | |
static func < (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority.rawValue < rhs.priority.rawValue | |
} | |
static func > (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority.rawValue > rhs.priority.rawValue | |
} | |
static func <= (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority.rawValue <= rhs.priority.rawValue | |
} | |
static func >= (lhs: Queue, rhs: Queue) -> Bool { | |
return lhs.priority.rawValue >= rhs.priority.rawValue | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kayoslab: Ich hab noch etwas optimiert... ;)