Skip to content

Commit

Permalink
update comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanwinchester committed Apr 22, 2024
1 parent 327cb75 commit 4c96092
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# UUIDv7

[![CI](https://github.com/ryanwinchester/uuidv7/actions/workflows/ci.yml/badge.svg)](https://github.com/ryanwinchester/uuidv7/actions/workflows/ci.yml)
[![Hex.pm](https://img.shields.io/hexpm/v/uuid_v7)](https://hex.pm/packages/uuid_v7)
[![Hex.pm](https://img.shields.io/hexpm/dt/uuid_v7)](https://hex.pm/packages/uuid_v7)
[![Hex.pm](https://img.shields.io/hexpm/l/uuid_v7)](https://github.com/ryanwinchester/uuidv7/blob/main/LICENSE)
[![Hex.pm](https://img.shields.io/hexpm/v/uuid_v7)](https://hex.pm/packages/uuid_v7)
[![Hex.pm](https://img.shields.io/hexpm/dt/uuid_v7)](https://hex.pm/packages/uuid_v7)
[![Hex.pm](https://img.shields.io/hexpm/l/uuid_v7)](https://github.com/ryanwinchester/uuidv7/blob/main/LICENSE)

UUIDv7 for Elixir and (optionally) Ecto, using an 18-bit randomly-seeded counter.

Expand Down Expand Up @@ -72,6 +72,15 @@ defmodule MyApp.Blog.Post do
end
```

To use UUIDs for everything in your migrations, it's easiest to just add that as the
default type in your `config.exs`. e.g.:

```elixir
config :app, App.Repo,
migration_primary_key: [type: :binary_id],
migration_foreign_key: [type: :binary_id]
```

## Benchmarks

Run benchmarks with
Expand All @@ -83,6 +92,7 @@ MIX_ENV=bench mix run bench/filename.exs
Where `filename.exs` is the name of one of the benchmark files in the `bench` directory.

### Compared to `Uniq.UUID`

(which has no counter or time-leap protection. millisecond precision.)

#### String:
Expand Down
26 changes: 19 additions & 7 deletions lib/uuidv7.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ defmodule UUIDv7 do
"""
@type raw :: <<_::128>>

@version 7
@variant 2

@doc """
Generates a version 7 UUID using submilliseconds for increased clock precision.
Expand All @@ -51,14 +54,23 @@ defmodule UUIDv7 do
"""
def bingenerate do
# Generate the random seed for the counter, and `rand_b` for the UUID at
# the same time. This minimizes the number of random bytes needed.
<<rand_a::17, _::1, rand_b::38>> = :crypto.strong_rand_bytes(7)

{time, clock} = Clock.next(<<rand_a::17>>)
{time_ms, clock} = Clock.next(<<rand_a::17>>)

# Split up the counter to fit into the UUIDv7 format.
<<clock_a::big-unsigned-12, clock_b::big-unsigned-6>> = clock

<<time::big-unsigned-48, 7::4, clock_a::big-unsigned-12, 2::2, clock_b::big-unsigned-6,
rand_b::56>>
<<
time_ms::big-unsigned-48,
@version::4,
clock_a::big-unsigned-12,
@variant::2,
clock_b::big-unsigned-6,
rand_b::56
>>
end

@doc """
Expand All @@ -71,12 +83,12 @@ defmodule UUIDv7 do
"""
@spec extract_timestamp(t | raw) :: integer
def extract_timestamp(<<_::288>> = uuid) do
decode(uuid) |> extract_timestamp()
def extract_timestamp(<<timestamp_ms::big-unsigned-48, @version::4, _::76>>) do
timestamp_ms
end

def extract_timestamp(<<ms::big-unsigned-48, 7::4, _::76>>) do
ms
def extract_timestamp(<<_::288>> = uuid) do
decode(uuid) |> extract_timestamp()
end

@doc """
Expand Down

0 comments on commit 4c96092

Please sign in to comment.