Exid exception (exid v0.1.0)

View Source

Exid is an Elixir implementation of the globally unique ID generator xid, suited for web scale.

Exid uses the MongoDB Object ID algorithm to generate globally unique IDs:

  • 4-byte value representing seconds since Unix epoch
  • 3-byte machine identifier
  • 2-byte process ID
  • 3-byte counter, starting with a random value

The binary representation is 12 bytes, compatible with MongoDB Object IDs. The string representation uses base32 hex (without padding) for better space efficiency.

Features:

  • Size: 12 bytes (96 bits), smaller than UUID, larger than snowflake
  • Base32 hex encoded (20 characters when encoded)
  • Non-configured, no need to set machine or data center IDs
  • K-ordered (sortable)
  • Embedded time with 1 second precision
  • Guaranteed uniqueness for 16,777,216 (2^24) unique IDs per second per host/process

Summary

Functions

Compares two IDs.

Extracts the 3-byte counter from an ID.

Converts a 12-byte binary to an ID.

Parses an ID from its base32 hex string representation.

Initializes the xid counter table. Must be called once at application startup.

Checks if an ID is nil (all zeros).

Extracts the 3-byte machine ID from an ID.

Generates a new globally unique ID using the current time.

Generates a new globally unique ID with the specified Unix timestamp.

Returns a nil ID (all zeros).

Extracts the 2-byte process ID from an ID.

Sorts a list of IDs in ascending order.

Extracts the Unix timestamp from an ID.

Returns the binary representation of an ID.

Converts an ID to its base32 hex string representation (20 characters).

Types

t()

@opaque t()

Functions

compare(id1, id2)

@spec compare(t(), t()) :: -1 | 0 | 1

Compares two IDs.

Returns:

  • -1 if the first ID is less than the second
  • 0 if the IDs are equal
  • 1 if the first ID is greater than the second

Examples

iex> id1 = Exid.new()
iex> id2 = Exid.new()
iex> Exid.compare(id1, id2) in [-1, 0, 1]
true

counter(id)

@spec counter(t()) :: integer()

Extracts the 3-byte counter from an ID.

Examples

iex> id = Exid.new()
iex> counter = Exid.counter(id)
iex> is_integer(counter)
true

from_bytes(bytes)

@spec from_bytes(binary()) :: {:ok, t()} | {:error, atom()}

Converts a 12-byte binary to an ID.

Returns {:ok, id} if valid, or {:error, reason} if invalid.

Examples

iex> bytes = Exid.new()
iex> {:ok, id} = Exid.from_bytes(bytes)
iex> id == bytes
true

from_string(str)

@spec from_string(String.t()) :: {:ok, t()} | {:error, atom()}

Parses an ID from its base32 hex string representation.

Returns {:ok, id} if valid, or {:error, reason} if invalid.

Examples

iex> {:ok, id} = Exid.from_string("c0nsb7f1en2k9b5ls9bg")
iex> byte_size(id)
12

init()

Initializes the xid counter table. Must be called once at application startup.

is_nil(id)

@spec is_nil(t()) :: boolean()

Checks if an ID is nil (all zeros).

Examples

iex> nil_id = <<0::96>>
iex> Exid.is_nil(nil_id)
true

machine(id)

@spec machine(t()) :: binary()

Extracts the 3-byte machine ID from an ID.

Examples

iex> id = Exid.new()
iex> machine = Exid.machine(id)
iex> byte_size(machine)
3

new()

@spec new() :: t()

Generates a new globally unique ID using the current time.

Examples

iex> id = Exid.new()
iex> is_binary(id)
true
iex> byte_size(id)
12

new_with_time(timestamp)

@spec new_with_time(non_neg_integer()) :: t()

Generates a new globally unique ID with the specified Unix timestamp.

Examples

iex> id = Exid.new_with_time(1234567890)
iex> byte_size(id)
12

nil_id()

@spec nil_id() :: t()

Returns a nil ID (all zeros).

Examples

iex> nil_id = Exid.nil_id()
iex> Exid.is_nil(nil_id)
true

pid(id)

@spec pid(t()) :: non_neg_integer()

Extracts the 2-byte process ID from an ID.

Examples

iex> id = Exid.new()
iex> pid = Exid.pid(id)
iex> is_integer(pid)
true

sort(ids)

@spec sort([t()]) :: [t()]

Sorts a list of IDs in ascending order.

Examples

iex> ids = [Exid.new(), Exid.new(), Exid.new()]
iex> sorted = Exid.sort(ids)
iex> length(sorted) == length(ids)
true

time(id)

@spec time(t()) :: non_neg_integer()

Extracts the Unix timestamp from an ID.

Examples

iex> id = Exid.new_with_time(1234567890)
iex> Exid.time(id)
1234567890

to_bytes(id)

@spec to_bytes(t()) :: binary()

Returns the binary representation of an ID.

Examples

iex> id = Exid.new()
iex> bytes = Exid.to_bytes(id)
iex> byte_size(bytes)
12

to_string(id)

@spec to_string(t()) :: String.t()

Converts an ID to its base32 hex string representation (20 characters).

The string uses characters [0-9a-v] for better sortability.

Examples

iex> id = Exid.new()
iex> str = Exid.to_string(id)
iex> String.length(str)
20
iex> String.match?(str, ~r/^[0-9a-v]{20}$/)
true