time_queue v0.8.1 TimeQueue.GbTrees

Implements a timers queue based on gb_trees.

The queue keys are a two-tuple composed of the timestamp of an entry and an unique integer.

No erlang timers or processes are used, as the queue is only a data structure. The advantage is that the queue can be persisted on storage and keep working after restarting the runtime. The queue maintain its own list of unique integers to avoir relying on BEAM unique integers as they are reset on restart.

The main drawback is that the queue entries must be manually checked for expired timers.

Link to this section Summary

Functions

Deletes an entry from the queue and returns the new queue.

Deletes all entries from the queue whose values are equal to unwanted.

Adds a new entry to the queue with a TTL and the current system time as now/0.

Adds a new entry to the queue with a TTL relative to the given timestamp in milliseconds.

Adds a new entry to the queue with an absolute timestamp.

Returns a new queue with entries for whom the given callback returned a truthy value.

Returns a new queue with entries for whom the given callback returned a truthy value.

Creates an empty time queue.

Returns the next value of the queue or a delay in milliseconds before the next value.

Returns the next value of the queue, or a delay, according to the given current time in milliseconds.

Returns the next entry of the queue or a delay in milliseconds before the next value.

Returns the next entry of the queue according to the given current time in milliseconds.

Extracts the next entry in the queue or returns a delay.

Extracts the next entry in the queue according to the given current time in milliseconds.

Extracts the next entry of the queue with the current system time as now/0.

Extracts the next entry of the queue according to the given current time in milliseconds.

Returns the numer of entries in the queue.

Returns the time reference of an queue entry. This reference is used as a key to identify a unique entry.

Returns the value of an queue entry.

Link to this section Types

Link to this type

enqueue_return()

enqueue_return() :: {:ok, tref(), t()}
Link to this opaque

entry()

(opaque)
entry()
Link to this type

entry_value()

entry_value() :: any()
Link to this opaque

id()

(opaque)
id()
Link to this type

peek_entry_return()

peek_entry_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, entry()}
Link to this type

peek_return()

peek_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, entry_value()}
Link to this type

pop_entry_return()

pop_entry_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, entry(), t()}
Link to this type

pop_return()

pop_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, entry_value(), t()}
Link to this opaque

t()

(opaque)
t()
Link to this type

timespec()

timespec() :: {pos_integer(), timespec_unit()}
Link to this type

timespec_unit()

timespec_unit() ::
  :ms
  | :second
  | :seconds
  | :minute
  | :minutes
  | :hour
  | :hours
  | :day
  | :days
  | :week
  | :weeks
Link to this type

timestamp_ms()

timestamp_ms() :: pos_integer()
Link to this opaque

tref()

(opaque)
tref()
Link to this type

ttl()

ttl() :: timespec() | integer()

Link to this section Functions

Link to this function

delete(tq, tref)

delete(t(), entry() | tref()) :: t()

Deletes an entry from the queue and returns the new queue.

It accepts a time reference or a full entry. When an entry is given, its time reference will be used to find the entry to delete, meaning the queue entry will be deleted even if the value of the passed entry was tampered.

The function does not fail if the entry cannot be found and simply returns the queue as-is.

Link to this function

delete_val(tq, unwanted)

delete_val(t(), any()) :: t()

Deletes all entries from the queue whose values are equal to unwanted.

This function is slow with gb_trees, see filter/2.

Link to this function

enqueue(tq, ttl, val)

enqueue(t(), ttl(), any()) :: enqueue_return()

Adds a new entry to the queue with a TTL and the current system time as now/0.

See enqueue/4.

Link to this function

enqueue(tq, ttl, val, now_ms)

enqueue(t(), ttl(), any(), now :: integer()) :: enqueue_return()

Adds a new entry to the queue with a TTL relative to the given timestamp in milliseconds.

Returns {:ok, tref, new_queue} where tref is a timer reference.

Link to this function

enqueue_abs(arg, ts, val)

enqueue_abs(t(), end_time :: integer(), value :: any()) :: enqueue_return()

Adds a new entry to the queue with an absolute timestamp.

Returns {:ok, tref, new_queue} where tref is a timer reference.

Link to this function

filter(arg, fun)

filter(t(), (entry() -> bool())) :: t()

Returns a new queue with entries for whom the given callback returned a truthy value.

With the gbtrees implementation, this operation is _very expensive as we convert the tree to and ordered list, filter the list, and convert back to a tree.

Link to this function

filter_val(tq, fun)

filter_val(t(), (any() -> bool())) :: t()

Returns a new queue with entries for whom the given callback returned a truthy value.

Unlinke filter/2, the callback is only passed the entry value.

This function is slow with gb_trees, see filter/2.

Link to this function

new()

new() :: t()

Creates an empty time queue.

iex> tq = TimeQueue.GbTrees.new()
iex> TimeQueue.GbTrees.peek_entry(tq)
:empty
Link to this function

peek(tq)

peek(t()) :: peek_return()

Returns the next value of the queue or a delay in milliseconds before the next value.

See peek/2.

Link to this function

peek(tq, now)

peek(t(), now_ms :: timestamp_ms()) :: peek_return()

Returns the next value of the queue, or a delay, according to the given current time in milliseconds.

Just like pop/2 vs.pop_entry/2, peek wil only return {:ok, value} when a timeout is reached whereas peek_entry will return {:ok, entry}.

Link to this function

peek_entry(tq)

peek_entry(t()) :: peek_entry_return()

Returns the next entry of the queue or a delay in milliseconds before the next value.

Entry values can be retrieved with TimeQueue.GbTrees.value/1.

See peek_entry/2.

Link to this function

peek_entry(arg, now)

peek_entry(t(), now_ms :: timestamp_ms()) :: peek_entry_return()

Returns the next entry of the queue according to the given current time in milliseconds.

Possible return values are:

  • :empty
  • {:ok, entry} if the timestamp of the first entry is <= to the given current time.
  • {:delay, tref, ms} if the timestamp of the first entry is > to the given current time. The remaining amount of milliseconds is returned.

Example

iex> {:ok, tref, tq} = TimeQueue.GbTrees.new() |> TimeQueue.GbTrees.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.GbTrees.peek_entry(tq, _now = 20)
iex> {:ok, _} = TimeQueue.GbTrees.peek_entry(tq, _now = 100)

Extracts the next entry in the queue or returns a delay.

See pop/2.

Link to this function

pop(tq, now)

pop(t(), now_ms :: timestamp_ms()) :: pop_return()

Extracts the next entry in the queue according to the given current time in milliseconds.

Much like pop_entry/2 but the tuple returned when an entry time is reached (returns with :ok) success will only contain the value inserted in the queue.

Possible return values are:

  • :empty
  • {:ok, value, new_queue} if the timestamp of the first entry is <= to the given current time. The entry is deleted from new_queue.
  • {:delay, tref, ms} if the timestamp of the first entry is > to the given current time. The remaining amount of milliseconds is returned.

Example

iex> {:ok, tref, tq} = TimeQueue.GbTrees.new() |> TimeQueue.GbTrees.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.GbTrees.pop(tq, _now = 20)
iex> {:ok, value, _} = TimeQueue.GbTrees.pop(tq, _now = 100)
iex> value
:hello
Link to this function

pop_entry(tq)

pop_entry(t()) :: pop_entry_return()

Extracts the next entry of the queue with the current system time as now/0.

See pop_entry/2.

Link to this function

pop_entry(arg, now)

pop_entry(t(), now_ms :: timestamp_ms()) :: pop_entry_return()

Extracts the next entry of the queue according to the given current time in milliseconds.

Possible return values are:

  • :empty
  • {:ok, entry, new_queue} if the timestamp of the first entry is <= to the given current time. The entry is deleted from new_queue.
  • {:delay, tref, ms} if the timestamp of the first entry is > to the given current time. The remaining amount of milliseconds is returned.

Example

iex> {:ok, tref, tq} = TimeQueue.GbTrees.new() |> TimeQueue.GbTrees.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.GbTrees.pop_entry(tq, _now = 20)
iex> {:ok, _, _} = TimeQueue.GbTrees.pop_entry(tq, _now = 100)
Link to this function

size(arg)

size(t()) :: integer()

Returns the numer of entries in the queue.

Link to this function

supports_encoding(arg1)

Link to this function

tref(arg)

tref(entry()) :: any()

Returns the time reference of an queue entry. This reference is used as a key to identify a unique entry.

iex> tq = TimeQueue.GbTrees.new()
iex> {:ok, tref, tq} = TimeQueue.GbTrees.enqueue(tq, 10, :my_value)
iex> Process.sleep(10)
iex> {:ok, entry} = TimeQueue.GbTrees.peek_entry(tq)
iex> tref == TimeQueue.GbTrees.tref(entry)
true
Link to this function

value(arg)

value(entry()) :: any()

Returns the value of an queue entry.

iex> tq = TimeQueue.GbTrees.new()
iex> {:ok, _, tq} = TimeQueue.GbTrees.enqueue(tq, 10, :my_value)
iex> Process.sleep(10)
iex> {:ok, entry} = TimeQueue.GbTrees.peek_entry(tq)
iex> TimeQueue.GbTrees.value(entry)
:my_value