Address minor organizational issues

This commit is contained in:
Feoramund
2024-06-22 18:21:32 -04:00
parent 95a9c9b016
commit 8b8f8c7f7d
3 changed files with 21 additions and 17 deletions
+4
View File
@@ -18,6 +18,10 @@ VERSION_7_COUNTER_SHIFT :: 64
@(private) @(private)
NO_CSPRNG_ERROR :: "The context random generator is not cryptographic. See the documentation for an example of how to set one up." NO_CSPRNG_ERROR :: "The context random generator is not cryptographic. See the documentation for an example of how to set one up."
@(private)
BIG_CLOCK_ERROR :: "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383 (0x3FFF)."
@(private)
VERSION_7_BIG_COUNTER_ERROR :: "This implementation of the version 7 UUID counter can only hold 12 bits of data, therefore no number greater than 4,095 (0xFFF)."
Read_Error :: enum { Read_Error :: enum {
None, None,
+16 -16
View File
@@ -17,7 +17,7 @@ Returns:
- result: The generated UUID. - result: The generated UUID.
*/ */
generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
assert(clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data; no number greater than 16,383.") assert(clock_seq <= 0x3FFF, BIG_CLOCK_ERROR)
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
@@ -89,13 +89,15 @@ Returns:
generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100
timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) uuid_timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals)
result |= transmute(Identifier)(timestamp & 0x0FFFFFFF_FFFFF000 << 68) result = transmute(Identifier)(
result |= transmute(Identifier)(timestamp & 0x00000000_00000FFF << 64) uuid_timestamp & 0x0FFFFFFF_FFFFF000 << 68 |
uuid_timestamp & 0x00000000_00000FFF << 64
)
if realized_clock_seq, ok := clock_seq.?; ok { if realized_clock_seq, ok := clock_seq.?; ok {
assert(realized_clock_seq <= 0x3FFF, "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383.") assert(realized_clock_seq <= 0x3FFF, BIG_CLOCK_ERROR)
result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8) result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8)
result[9] = cast(u8)realized_clock_seq result[9] = cast(u8)realized_clock_seq
} else { } else {
@@ -126,7 +128,7 @@ generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, times
Generate a version 7 UUID. Generate a version 7 UUID.
This UUID will be pseudorandom, save for 6 pre-determined version and variant This UUID will be pseudorandom, save for 6 pre-determined version and variant
bits and a 48 bit timestamp. bits and a 48-bit timestamp.
It is designed with time-based sorting in mind, such as for database usage, as It is designed with time-based sorting in mind, such as for database usage, as
the highest bits are allocated from the timestamp of when it is created. the highest bits are allocated from the timestamp of when it is created.
@@ -141,13 +143,11 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT result = transmute(Identifier)(cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT)
bytes_generated := rand.read(result[6:]) bytes_generated := rand.read(result[6:])
assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.") assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.")
result |= transmute(Identifier)temporary
result[VERSION_BYTE_INDEX] &= 0x0F result[VERSION_BYTE_INDEX] &= 0x0F
result[VERSION_BYTE_INDEX] |= 0x70 result[VERSION_BYTE_INDEX] |= 0x70
@@ -161,7 +161,7 @@ generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identif
Generate a version 7 UUID that has an incremented counter. Generate a version 7 UUID that has an incremented counter.
This UUID will be pseudorandom, save for 6 pre-determined version and variant This UUID will be pseudorandom, save for 6 pre-determined version and variant
bits, a 48 bit timestamp, and 12 bits of counter state. bits, a 48-bit timestamp, and 12 bits of counter state.
It is designed with time-based sorting in mind, such as for database usage, as It is designed with time-based sorting in mind, such as for database usage, as
the highest bits are allocated from the timestamp of when it is created. the highest bits are allocated from the timestamp of when it is created.
@@ -183,7 +183,7 @@ Example:
} }
Inputs: Inputs:
- counter: A 12-bit value, incremented each time a UUID is generated in a batch. - counter: A 12-bit value which should be incremented each time a UUID is generated in a batch.
- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. - timestamp: A timestamp from the `core:time` package, or `nil` to use the current time.
Returns: Returns:
@@ -191,17 +191,17 @@ Returns:
*/ */
generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) {
assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR)
assert(counter <= 0x0fff, "This implementation of the version 7 UUID does not support counters in excess of 12 bits (4,095).") assert(counter <= 0x0fff, VERSION_7_BIG_COUNTER_ERROR)
unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6
temporary := cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT result = transmute(Identifier)(
temporary |= cast(u128be)counter << VERSION_7_COUNTER_SHIFT cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT |
cast(u128be)counter << VERSION_7_COUNTER_SHIFT
)
bytes_generated := rand.read(result[8:]) bytes_generated := rand.read(result[8:])
assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.") assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.")
result |= transmute(Identifier)temporary
result[VERSION_BYTE_INDEX] &= 0x0F result[VERSION_BYTE_INDEX] &= 0x0F
result[VERSION_BYTE_INDEX] |= 0x70 result[VERSION_BYTE_INDEX] |= 0x70
+1 -1
View File
@@ -113,7 +113,7 @@ clock_seq :: proc "contextless" (id: Identifier) -> (clock_seq: u16) {
} }
/* /*
Get the node of a version 1 UUID. Get the node of a version 1 or version 6 UUID.
Inputs: Inputs:
- id: The identifier. - id: The identifier.