Uh oh!
There was an error while loading. Please reload this page.
Generate entryUUID from a per-thread SecureRandom - #683
Conversation
The EntryUUID plugin runs for every LDAP add and used UUID.randomUUID(), which draws from a single shared SecureRandom whose engine is synchronized — one more monitor all concurrent adds serialize on. Generate the RFC 4122 version 4 UUID from a ThreadLocal<SecureRandom> instead: same format (version and variant bits set identically, verified against UUID.randomUUID), same uniqueness guarantees, no shared state. The deterministic DN-based UUID used for LDIF import is unchanged. No measurable local throughput change is expected or claimed: the add path is dominated by JE record-lock waits on shared index keys; this removes a JDK-internal serialization point that grows with core count.
prthakre
commented
Jul 20, 2026
Below code is another alternative: |
vharseko
commented
Jul 20, 2026
Thanks for the suggestion — the bit masks are correct and the output distribution is identical. However, |
prthakre
commented
Jul 20, 2026
Thanks for the deep dive, makes sense. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
Companion to #682 from the ADD/DELETE hot-path profiling. The EntryUUID
plugin runs for every LDAP add and used
UUID.randomUUID(), whichdraws from a single shared static
SecureRandomwhose engine(
SHA1PRNG/NativePRNG, provider-dependent) synchronizesnextBytes—one more JDK-internal monitor that all concurrent adds serialize on.
Change
Generate the RFC 4122 version 4 UUID from a
ThreadLocal<SecureRandom>: 16 random bytes with the version and variantbits set exactly as
UUID.randomUUID()sets them. Format verifiedstandalone — 200,000 generated UUIDs, all unique,
version()==4,variant()==2, matching the reference implementation. The deterministicDN-based UUID used for LDIF import (parallel-import reproducibility) is
unchanged.
Honest performance note
No local throughput change is expected or claimed on the benchmark host:
the concurrent add path is dominated by JE record-lock waits on shared
index keys (~822 s of
waitForLockper 80 s JFR window in the ADD/DELETEbaseline — see #682) and by the JE write-ahead log. The
SecureRandommonitor is held for microseconds; this removes a JDK-internal
serialization point whose relative weight grows with core count and add
rate — the same structural rationale as the rest of the series.
Testing
mvn -P precommit -pl opendj-server-legacy verify:EntryUUIDPluginTestCase(61 — behavioural validation of the generatedattribute through the UUID syntax),
AddOperationTestCase(137):198 tests, 0 failures. Plus the standalone 200k-UUID format check
described above.
Files
opendj-server-legacy/src/main/java/org/opends/server/plugins/EntryUUIDPlugin.java