Skip to content

Conversation

@tannergooding
Copy link
Member

This resolves #103658

@ghost ghost added needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners new-api-needs-documentation labels Jun 27, 2024
@ghost
Copy link

ghost commented Jun 27, 2024

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

1 similar comment
@ghost
Copy link

ghost commented Jun 27, 2024

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@tannergooding tannergooding added area-System.Runtime and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jun 28, 2024
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

@tannergooding tannergooding marked this pull request as ready for review June 28, 2024 02:59
public static Guid CreateVersion7(DateTimeOffset timestamp)
{
// This isn't the most optimal way, but we don't have an easy way to get
// secure random bytes in corelib without doing this, and its not terrible
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw, I don't think this comment is necessary.

But we could also do what the NewGuid impl itself does.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewGuid just defers down to the COM API on Windows so there's no benefit in duplicating things.

Ideally we'd be able to use System.Security.Cryptography.RandomNumberGenerator but that's at the wrong layer of the stack.


// 2^48 is roughly 8925.5 years, which from the Unix Epoch means we won't
// overflow until around July of 10,895. So there isn't much need to handle it
// particularly given that DateTimeOffset.MaxValue is December 31, 9999
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would need to be handied then if a larger value can't be passed in? Trying to understand the comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a comment that's explicitly covering why only taking 48-bits out of a 64-bit integer is okay, that we won't end up in a scenario where we're silently dropping information.

// particularly given that DateTimeOffset.MaxValue is December 31, 9999
long unix_ts_ms = timestamp.ToUnixTimeMilliseconds();

Unsafe.AsRef(in result._a) = (int)(unix_ts_ms >> 16);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to worry about sign extension here because unix_ts_ms will never be negative?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, I think it actually can be negative and we may need to detect this case. In particular, DateTimeOffset supports timestamps prior to the Unix Epoch and so can represent Jan 1st, 0001, meaning ToUnixTimeMilliseconds would return 0xFFFFC77CEDD32800 (-62135596800000).

The RFC specifies

UUIDv7 features a time-ordered value field derived from the widely implemented and well-known Unix Epoch timestamp source, the number of milliseconds since midnight 1 Jan 1970 UTC, leap seconds excluded.
and
48-bit big-endian unsigned number of the Unix Epoch timestamp in milliseconds

So negative timestamps would be an error case.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend System.Guid with a new creation API for v7

2 participants