Skip to main content
Version: 2.x

TPriorityQueue

A TPriorityQueue[A] is a mutable queue that can participate in STM transactions. A TPriorityQueue contains values of type A for which an Ordering is defined. Unlike a TQueue, take returns the highest priority value (the value that is first in the specified ordering) as opposed to the first value offered to the queue. The ordering of elements sharing the same priority when taken from the queue is not guaranteed.

Creating a TPriorityQueue

You can create an empty TPriorityQueue using the empty constructor:

import zio._
import zio.stm._

val minQueue: STM[Nothing, TPriorityQueue[Int]] =
TPriorityQueue.empty

Notice that a TPriorityQueue is created with an implicit Ordering. By default, take will return the value that is first in the specified ordering. For example, in a queue of events ordered by time the earliest event would be taken first. If you want a different behavior you can use a custom Ordering.

val maxQueue: STM[Nothing, TPriorityQueue[Int]] =
TPriorityQueue.empty(Ordering[Int].reverse)

You can also create a TPriorityQueue initialized with specified elements using the fromIterable or make constructors". The fromIterable constructor takes a Iterable while the make constructor takes a variable arguments sequence of elements.

Offering elements to a TPriorityQueue

You can offer elements to a TPriorityQueue using the offer or offerAll methods. The offerAll method is more efficient if you want to offer more than one element to the queue at the same time.

val queue: STM[Nothing, TPriorityQueue[Int]] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
} yield queue

Taking elements from a TPriorityQueue

Take an element from a TPriorityQueue using the take. take will semantically block until there is at least one value in the queue to take. You can also use takeAll to immediately take all values that are currently in the queue, or takeUpTo to immediately take up to the specified number of elements from the queue.

val sorted: STM[Nothing, Chunk[Int]] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
sorted <- queue.takeAll
} yield sorted

You can also use takeOption method to take the first value from the queue if it exists without suspending or the peek method to observe the first element of the queue if it exists without removing it from the queue.

Sometimes you want to take a snapshot of the current state of the queue without modifying it. For this the toChunk combinator or its variants toList or toVector are extremely helpful. These will return an immutable collection that consists of all of the elements currently in the queue, leaving the state of the queue unchanged.

Size of a TPriorityQueue

You can check the size of the TPriorityQueue using the size method:


val size: STM[Nothing, Int] =
for {
queue <- TPriorityQueue.empty[Int]
_ <- queue.offerAll(List(2, 4, 6, 3, 5, 6))
size <- queue.size
} yield size