sahilpaudel
Generate Timebased UUID in elixir
Hey there,
I am using Cassandra and it takes id as of type timebased uuid so I was curious if there is a way or library in Elixir that can generate Timebased UUID for me.
Thanks.
Most Liked
kokolegorille
ksuid is sortable uuid
jc00ke
I’ll throw ecto_ulid out there too. ULID is a pretty nice ID type (and while I realize this post is about IDs in Cassandra) but its lack of support in Postgres turned into a PITA. I was storing it as a :binary_id since it’s a 128bit integer but querying by the human-readable format was impossible; I had to convert it manually and that got old.
Anyway, here’s a good write-up of the differences between ULID & KSUID. Both are likely great options for your use case.
Qqwy
A cursory look through Xandra’s documentation and source code shows that Xandra does not (yet?) expose any way to generate timeuuid’s in Elixir (but only encoding/decoding values genereated from within Cassandra).
I did find another library called ‘Cassandra’ which has not seen very much usage and has not been updated in a couple of years, but it does contain an internal (undocumented) module called Cassandra.UUID which seems to generate UUIDs in the desired format.
Looking at that module in a bit more detail, it seems like the actual work is offloaded to elixir_uuid (which is stable and widely used), and that Cassandra’s timeuuids are nothing else than ‘v1’ UUIDs.
So using elixir_uuid is probably the best approach
.
RodolfoSilva
cjbottaro
I just ported the Cassandra::Uuid::Generator code from the official Cassandra Ruby gem:
defmodule TimeUuid do
use Bitwise, only_operators: true
@gregorian_offset 122192928000000000
def new(date_time, jitter \\ nil) do
jitter = jitter || :rand.uniform(65536)
clock_id = :rand.uniform(65536)
node_id = generate_node_id()
usecs = DateTime.to_unix(date_time, :microsecond) + jitter
t = @gregorian_offset + usecs * 10
time_hi = t &&& 0x0fff000000000000
time_mid = t &&& 0x0000ffff00000000
time_low = t &&& 0x00000000ffffffff
version = 1
clock_id = clock_id &&& 0x3fff
node_id = node_id &&& 0xffffffffffff
variant = 0x8000
n = (time_low <<< 96) ||| (time_mid <<< 48) ||| (time_hi <<< 16)
n = n ||| (version <<< 76)
n = n ||| ((clock_id ||| variant) <<< 48)
n = n ||| node_id
<<n::integer-size(128)>>
|> UUID.binary_to_string!()
end
def generate_node_id do
:math.pow(2, 47)
|> trunc()
|> :rand.uniform()
|> Bitwise.bor(0x010000000000)
end
end







