Package com.fasterxml.uuid
Class UUIDTimer
java.lang.Object
com.fasterxml.uuid.UUIDTimer
UUIDTimer produces the time stamps required for time-based UUIDs.
It works as outlined in the UUID specification, with following
implementation:
- Java classes can only product time stamps with maximum resolution of one millisecond (at least before JDK 1.5). To compensate, an additional counter is used, so that more than one UUID can be generated between java clock updates. Counter may be used to generate up to 10000 UUIDs for each distinct java clock value.
- Due to even lower clock resolution on some platforms (older Windows versions use 55 msec resolution), timestamp value can also advanced ahead of physical value within limits (by default, up 100 millisecond ahead of reported), if necessary (ie. 10000 instances created before clock time advances).
- As an additional precaution, counter is initialized not to 0 but to a random 8-bit number, and each time clock changes, lowest 8-bits of counter are preserved. The purpose it to make likelyhood of multi-JVM multi-instance generators to collide, without significantly reducing max. UUID generation speed. Note though that using more than one generator (from separate JVMs) is strongly discouraged, so hopefully this enhancement isn't needed. This 8-bit offset has to be reduced from total max. UUID count to preserve ordering property of UUIDs (ie. one can see which UUID was generated first for given UUID generator); the resulting 9500 UUIDs isn't much different from the optimal choice.
- Finally, as of version 2.0 and onwards, optional external timestamp synchronization can be done. This is done similar to the way UUID specification suggests; except that since there is no way to lock the whole system, file-based locking is used. This works between multiple JVMs and Jug instances.
Some additional assumptions about calculating the timestamp:
- System.currentTimeMillis() is assumed to give time offset in UTC, or at least close enough thing to get correct timestamps. The alternate route would have to go through calendar object, use TimeZone offset to get to UTC, and then modify. Using currentTimeMillis should be much faster to allow rapid UUID creation.
- Similarly, the constant used for time offset between 1.1.1970 and start of Gregorian calendar is assumed to be correct (which seems to be the case when testing with Java calendars).
Note about synchronization: main synchronization point (as of version
3.1.1 and above) is getTimestamp(), so caller need not
synchronize access explicitly.
-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final UUIDClockClock used to get the time when a timestamp is requested.protected final RandomRandom number generator used to generate additional information to further reduce probability of collisions.protected final TimestampSynchronizerObject used to reliably ensure that no multiple JVMs generate UUIDs, and also that the time stamp value used for generating time-based UUIDs is monotonically increasing even if system clock moves backwards over a reboot (usually due to some system level problem). -
Constructor Summary
ConstructorsConstructorDescriptionUUIDTimer(Random rnd, TimestampSynchronizer sync) UUIDTimer(Random rnd, TimestampSynchronizer sync, UUIDClock clock) -
Method Summary
Modifier and TypeMethodDescriptionprotected final voidgetAndSetTimestamp(byte[] uuidBytes) intlongMethod that constructs unique timestamp suitable for use for constructing UUIDs.protected voidslowDown(long startTime, long actDiff) Simple utility method to use to wait for couple of milliseconds, to let system clock hopefully advance closer to the virtual timestamps used.static longtimestampToEpoch(long timestamp) Converts a UUID v1 or v6 timestamp (where unit is 100 nanoseconds), to Unix epoch timestamp (milliseconds since 01-Jan-1970 UTC)
-
Field Details
-
_syncer
Object used to reliably ensure that no multiple JVMs generate UUIDs, and also that the time stamp value used for generating time-based UUIDs is monotonically increasing even if system clock moves backwards over a reboot (usually due to some system level problem).See
TimestampSynchronizerfor details. -
_random
Random number generator used to generate additional information to further reduce probability of collisions. -
_clock
Clock used to get the time when a timestamp is requested.- Since:
- 3.3
-
-
Constructor Details
-
UUIDTimer
- Throws:
IOException
-
UUIDTimer
- Parameters:
rnd- Random-number generator to usesync- Synchronizer needed for multi-threaded timestamp accessclock- Provider for milli-second resolution timestamp- Throws:
IOException- if initialization ofsyncfails due to problem related to reading of persisted last-used timestamp- Since:
- 3.3
-
-
Method Details
-
getClockSequence
public int getClockSequence() -
getTimestamp
public long getTimestamp()Method that constructs unique timestamp suitable for use for constructing UUIDs. Default implementation is fully synchronized; sub-classes may choose to implement alternate strategies but due to existing usage and expectations should also be synchronized unless usage is specifically known not to require it.- Returns:
- 64-bit timestamp to use for constructing UUID
-
timestampToEpoch
public static long timestampToEpoch(long timestamp) Converts a UUID v1 or v6 timestamp (where unit is 100 nanoseconds), to Unix epoch timestamp (milliseconds since 01-Jan-1970 UTC)- Parameters:
timestamp- Timestamp used to create UUID versions 1 and 6- Returns:
- Unix epoch timestamp
- Since:
- 5.1
-
getAndSetTimestamp
protected final void getAndSetTimestamp(byte[] uuidBytes) -
slowDown
protected void slowDown(long startTime, long actDiff) Simple utility method to use to wait for couple of milliseconds, to let system clock hopefully advance closer to the virtual timestamps used. Delay is kept to just a millisecond or two, to prevent excessive blocking; but that should be enough to eventually synchronize physical clock with virtual clock values used for UUIDs.- Parameters:
actDiff- Number of milliseconds to wait for from current time point, to catch up
-