Skip to content

Instantly share code, notes, and snippets.

@KamilLelonek
Created August 11, 2019 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KamilLelonek/56baff6f36c6c7fe0eded29a4dc8ffff to your computer and use it in GitHub Desktop.
Save KamilLelonek/56baff6f36c6c7fe0eded29a4dc8ffff to your computer and use it in GitHub Desktop.
defmodule GlobalId do
@moduledoc """
GlobalId module contains an implementation of a guaranteed globally unique id system.
It can be used for generating 64-bit unique IDs at high scale.
The IDs generated by this service are roughly time sortable.
"""
# NOTE: On production don't change it once set
epoch = {{1970, 1, 1}, {0, 0, 0}}
@epoch :calendar.datetime_to_gregorian_seconds(epoch)
@doc """
Please implement the following function.
Since the IDs use timestamp as the first component, they are time sortable.
64 bit non negative integer output
"""
# NOTE: On production track increasing sequence
@spec get_id(sequence :: non_neg_integer) :: non_neg_integer
def get_id(sequence) do
<<new_id::unsigned-integer-64>> =
<<timestamp()::unsigned-integer-42, node_id()::unsigned-integer-10,
sequence::unsigned-integer-12>>
new_id
end
@doc """
Returns your node id as an integer.
It will be greater than or equal to 0 and less than 1024.
It is guaranteed to be globally unique.
SIZE: 1024 = 2^10 - 10 bits
"""
@spec node_id() :: non_neg_integer
def node_id,
# NOTE: On production rely on node discovery
do: Enum.random(0..1024)
@doc """
Returns timestamp since the epoch in milliseconds.
The maximum timestamp that can be represented using 42 bits is 2^42 - 1,
or 4398046511103, which comes out to be Wednesday, May 15, 2109 7:35:11.103 AM.
That gives us 139 years with respect to a custom epoch.
defp epoch do
2
|> :math.pow(42)
|> Kernel.-(1)
|> round()
|> DateTime.from_unix!(:millisecond)
end
"""
@spec timestamp() :: non_neg_integer
def timestamp,
do: System.os_time(:millisecond) - @epoch
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment