View Source TimeQueue.GbTrees (time_queue v0.9.6)

Implements a timers queue based on gb_trees.

The queue keys are a two-tuple composed of the timestamp of an event 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 event from the queue and returns the new queue.

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

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

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

Adds a new event 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.

peek_entry(tq) deprecated

Alias for peek_event/1.

peek_entry(tq, now) deprecated

Alias for peek_event/2.

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

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

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

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

pop_entry(tq) deprecated

Alias for pop_event/1.

pop_entry(tq, now) deprecated

Alias for pop_event/2.

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

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

Returns the number of entries in the queue.

Provides a GenServer compatible timeout from the queue.

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

Returns the value of a queue event.

Link to this section Types

Specs

enqueue_return() :: {:ok, tref(), t()}

Specs

event()

Specs

event_value() :: any()

Specs

id()

Specs

peek_event_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, event()}

Specs

peek_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, event_value()}

Specs

pop_event_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, event(), t()}

Specs

pop_return() ::
  :empty | {:delay, tref(), non_neg_integer()} | {:ok, event_value(), t()}

Specs

t()

Specs

timespec() :: {pos_integer(), timespec_unit()}

Specs

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

Specs

timestamp_ms() :: pos_integer()

Specs

tref()

Specs

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

Link to this section Functions

Specs

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

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

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

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

Link to this function

delete_val(tq, unwanted)

View Source

Specs

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.

Specs

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

Adds a new event 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)

View Source

Specs

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

Adds a new event 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(tq, ts, val)

View Source

Specs

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

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

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

Specs

filter(t(), (event() -> boolean())) :: 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.

Specs

filter_val(t(), (any() -> boolean())) :: 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 event value.

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

Specs

new() :: t()

Creates an empty time queue.

iex> tq = TimeQueue.GbTrees.new()
iex> TimeQueue.GbTrees.peek_event(tq)
:empty

Specs

peek(t()) :: peek_return()

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

See peek/2.

Specs

peek(t(), now :: 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_event/2, peek wil only return {:ok, value} when a timeout is reached whereas peek_event will return {:ok, event}.

This function is deprecated. Use peek_event/1 instead.

Specs

peek_entry(t()) :: peek_event_return()

Alias for peek_event/1.

This function is deprecated. Use peek_event/2 instead.

Specs

peek_entry(t(), now :: timestamp_ms()) :: peek_event_return()

Alias for peek_event/2.

Specs

peek_event(t()) :: peek_event_return()

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

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

See peek_event/2.

Specs

peek_event(t(), now :: timestamp_ms()) :: peek_event_return()

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

Possible return values are:

  • :empty
  • {:ok, event} if the timestamp of the first event is <= to the given current time.
  • {:delay, tref, ms} if the timestamp of the first event 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_event(tq, _now = 20)
iex> {:ok, _} = TimeQueue.GbTrees.peek_event(tq, _now = 100)

Specs

pop(t()) :: pop_return()

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

See pop/2.

Specs

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

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

Much like pop_event/2 but the tuple returned when an event 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 event is <= to the given current time. The event is deleted from new_queue.
  • {:delay, tref, ms} if the timestamp of the first event 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
This function is deprecated. Use pop_event/1 instead.

Specs

pop_entry(t()) :: pop_event_return()

Alias for pop_event/1.

This function is deprecated. Use pop_event/2 instead.

Specs

pop_entry(t(), now :: timestamp_ms()) :: pop_event_return()

Alias for pop_event/2.

Specs

pop_event(t()) :: pop_event_return()

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

See pop_event/2.

Specs

pop_event(t(), now :: timestamp_ms()) :: pop_event_return()

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

Possible return values are:

  • :empty
  • {:ok, event, new_queue} if the timestamp of the first event is <= to the given current time. The event is deleted from new_queue.
  • {:delay, tref, ms} if the timestamp of the first event 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_event(tq, _now = 20)
iex> {:ok, _, _} = TimeQueue.GbTrees.pop_event(tq, _now = 100)

Specs

size(t()) :: integer()

Returns the number of entries in the queue.

Link to this function

timeout(tq, now \\ now())

View Source

Specs

timeout(t(), now :: timestamp_ms()) :: non_neg_integer() | :infinity

Provides a GenServer compatible timeout from the queue.

Accepts the current time as a second argument or will default to the current system time.

Returns:

  • :infinity when the queue is empty.
  • 0 when there the next event time has been reached.
  • The delay to the next event otherwise.

Specs

tref(event()) :: any()

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

iex> tq = TimeQueue.GbTrees.new()
iex> {:ok, tref, tq} = TimeQueue.GbTrees.enqueue(tq, 10, :my_value)
iex> Process.sleep(10)
iex> {:ok, event} = TimeQueue.GbTrees.peek_event(tq)
iex> tref == TimeQueue.GbTrees.tref(event)
true

Specs

value(event()) :: any()

Returns the value of a queue event.

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