Skip to content

Conversation

@cigaly
Copy link
Contributor

@cigaly cigaly commented Jul 27, 2024

Jira issue HHH-18377

Implementation of UUID Versioin 6 and UUID Version 7


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


@cigaly cigaly force-pushed the HHH-18377 branch 3 times, most recently from 5b0017a to 066a676 Compare July 29, 2024 15:28
@cigaly cigaly marked this pull request as ready for review July 29, 2024 16:21
@CaptainGlac1er
Copy link

How will it handle if a separate server generates the same id into the same database? Will it recreate a new ID automatically and try again?

@sebersole
Copy link
Member

How will it handle if a separate server generates the same id into the same database? Will it recreate a new ID automatically and try again?

No.

Copy link
Member

@sebersole sebersole left a comment

Choose a reason for hiding this comment

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

I left a few comments about odd references to UUID#randomUUID(). Let's clean those up.

Additionally, you write great detail about what each value generator does. But you do it on #generateUuid. I'd prefer to see those on the class Javadoc, because...

Another thing we should do here is to add values for these into UuidGenerator.Style. Its probably best to have these link to the class Javadoc for the corresponding value-generator.

@cigaly cigaly force-pushed the HHH-18377 branch 2 times, most recently from 5134d12 to e44c59b Compare September 19, 2024 05:43
@sebersole
Copy link
Member

A few naming related points here...

  1. Not a fan of the enum names (UUIDV6, UUIDV7). How about VERSION6 and VERSION7 (or VERSION_6...)? Or since they are RFC compliant, RFC_6 and RFC_7?
  2. The value generator names should use {Type}Strategy pattern to match with the others. E.g. Version6Strategy.

I'll need to pull this locally to squash the commits before I apply. I can apply the name changes at that time if you prefer.

Thanks again for the work on this!

@cigaly
Copy link
Contributor Author

cigaly commented Sep 19, 2024

A few naming related points here...

1. Not a fan of the enum names (UUIDV6, UUIDV7).  How about VERSION6 and VERSION7 (or VERSION_6...)?  Or since they are RFC compliant, RFC_6 and RFC_7?

2. The value generator names should use `{Type}Strategy` pattern to match with the others.  E.g. `Version6Strategy`.

Changed both things.

I'll need to pull this locally to squash the commits before I apply. I can apply the name changes at that time if you prefer.

I've squashed everything into two commits, one for implementation, other for test case. Hope that this is OK?

Thanks again for the work on this!

You're welcome. Happy if I can help. Not that I was too busy lately.

@sebersole
Copy link
Member

sebersole commented Sep 19, 2024

In general, we like the test/impl split for the PR as it shows (1) what is addressed and (2) how it was addressed.

When we apply them, though, we generally (not always) squash to one as it makes it easier to cherry-pick to other branches. This we won't be backporting, so its less important. Long story short, 2 commits is fine here.

Copy link
Member

@sebersole sebersole left a comment

Choose a reason for hiding this comment

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

A few minor suggestions/requests. Let me know what you think. FWIW I left "suggested changes" in those places to make it easy to apply if you agree.

* <li>14 bits - the clock sequence, resets to 0 when timestamp changes. </li>
* <li>48 bits - pseudorandom data to provide uniqueness.</li>
* </ul>
*
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
*
*
* @apiNote Version 6 is field-compatible with Version 1, with the time bits reordered for improved DB locality.
*

*/
@Override
public int getGeneratedVersion() {
// UUIDv6 is a field-compatible version of UUIDv1, reordered for improved DB locality
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// UUIDv6 is a field-compatible version of UUIDv1, reordered for improved DB locality

Comment on lines +88 to +89
* @param session session
*
* @return UUID version 6
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param session session
*
* @return UUID version 6
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
* Generates a Version 6 compliant {@linkplain UUID} value.
*
* @return A Version 6 compliant {@linkplain UUID}.
*
* @see UuidValueGenerator#generateUuid

* <li>14 bits - counter to guarantee additional monotonicity, resets to 0 when timestamp changes. </li>
* <li>48 bits - pseudorandom data to provide uniqueness.</li>
* </ul>
*
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
*
*
* @apiNote A Version 7 UUID 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.
*

Comment on lines +69 to +71
/*
* 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.
*/
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/*
* 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.
*/

Comment on lines +86 to +87
* @param session session
*
* @return UUID version 7
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param session session
*
* @return UUID version 7
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)
* Generates a Version 7 {@linkplain UUID}.
*
* @return A Version version 7 {@linkplain UUID}.
* @see UuidValueGenerator#generateUuid(SharedSessionContractImplementor)

@sebersole
Copy link
Member

Also, clearly we need to address the failures :)

Execution failed for task ':hibernate-core:compileTestJava'.
> Compilation failed; see the compiler error output for details.

@cigaly
Copy link
Contributor Author

cigaly commented Sep 19, 2024

Also, clearly we need to address the failures :)

Execution failed for task ':hibernate-core:compileTestJava'.
> Compilation failed; see the compiler error output for details.

One will expect that IDE should know to make basic refactoring things like renaming classes :-)

@sebersole
Copy link
Member

Applied manually. Thanks!

@sebersole sebersole closed this Sep 23, 2024
@beikov
Copy link
Member

beikov commented Sep 26, 2024

I'm getting test errors quite consistently. I didn't have a single success of the v6 test so far:

java.lang.AssertionError: 
Expecting actual:
  "1ef7be82-786f-69e5-8000-5b0eb9699e10"
to be greater than:
  "1ef7be82-786f-69e5-bfff-e4cda4de4e50"

	at org.hibernate.orm.test.id.uuid.rfc9562.UUidV6V7GenetartorTest.testMonotonicity(UUidV6V7GenetartorTest.java:43)
	at org.hibernate.orm.test.id.uuid.rfc9562.UUidV6V7GenetartorTest.testMonotonicityUuid6(UUidV6V7GenetartorTest.java:26)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Running with jdk-17.0.12+7 on Windows 11 if it matters. I don't know how the implementation works, but it seems broken.

@cigaly
Copy link
Contributor Author

cigaly commented Sep 26, 2024

It seems that there is pretty stupid bug :-( I'll check and fix that.

@beikov
Copy link
Member

beikov commented Sep 26, 2024

I just ran into another (unrelated but possibly similar) error, which is related to the fact that on Windows, the time source has a precision of 7 digits after the decimal separator.

@cigaly
Copy link
Contributor Author

cigaly commented Sep 26, 2024

I've located that problem and will fix it ASAP

@cigaly cigaly mentioned this pull request Sep 26, 2024
@cigaly
Copy link
Contributor Author

cigaly commented Sep 26, 2024

@beikov I've created new pull request #9020 with updates to both UUID v6 and v7 generation

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants