Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions lib/snowflake.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ defmodule Snowflake do
"""
use Application

@typedoc """
Snowflakes are unique IDs generated by combining the current epoch time and
the generating machine ID.
"""
@type t :: non_neg_integer

@typedoc """
Number of milliseconds since January 1, 1970, Midnight
"""
@type unix_timestamp :: non_neg_integer

@typedoc """
Number of milliseconds since the beginning of the configured epoch
"""
@type epoch_timestamp :: non_neg_integer

def start(_type, _args) do
import Supervisor.Spec

Expand All @@ -16,9 +32,9 @@ defmodule Snowflake do

@doc """
Generates a snowflake ID, each call is guaranteed to return a different ID
that is sequantially larger than the previous ID.
that is sequentially larger than the previous ID.
"""
@spec next_id() :: {:ok, integer} |
@spec next_id() :: {:ok, t} |
{:error, :backwards_clock}
def next_id() do
GenServer.call(Snowflake.Generator, :next_id)
Expand Down
12 changes: 6 additions & 6 deletions lib/snowflake/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ defmodule Snowflake.Util do

@doc """
First Snowflake for timestamp, useful if you have a timestamp and want
to find snowflakes before or after a certain millesecond
to find snowflakes before or after a certain millisecond
"""
@spec first_snowflake_for_timestamp(integer) :: integer
@spec first_snowflake_for_timestamp(Snowflake.unix_timestamp()) :: Snowflake.t()
def first_snowflake_for_timestamp(timestamp) do
ts = timestamp - Snowflake.Helper.epoch()

<< new_id :: unsigned-integer-size(64)>> = <<
ts :: unsigned-integer-size(42),
0 :: unsigned-integer-size(10),
Expand All @@ -28,23 +28,23 @@ defmodule Snowflake.Util do
@doc """
Get timestamp in ms from your config epoch from any snowflake ID
"""
@spec timestamp_of_id(integer) :: integer
@spec timestamp_of_id(Snowflake.t()) :: Snowflake.epoch_timestamp()
def timestamp_of_id(id) do
id >>> 22
end

@doc """
Get timestamp from computer epoch - January 1, 1970, Midnight
"""
@spec real_timestamp_of_id(integer) :: integer
@spec real_timestamp_of_id(Snowflake.t()) :: Snowflake.unix_timestamp()
def real_timestamp_of_id(id) do
timestamp_of_id(id) + Snowflake.Helper.epoch()
end

@doc """
Get bucket value based on segments of N days
"""
@spec bucket(integer, atom, integer) :: integer
@spec bucket(integer, atom, Snowflake.t()) :: integer
def bucket(units, unit_type, id) do
round(timestamp_of_id(id) / bucket_size(unit_type, units))
end
Expand Down