Package com.cedarsoftware.util
Class UniqueIdGenerator
java.lang.Object
com.cedarsoftware.util.UniqueIdGenerator
Generates guaranteed unique, time-based, monotonically increasing IDs within a distributed environment.
Each ID encodes three pieces of information:
- Timestamp - milliseconds since epoch (1970)
- Sequence number - counter for multiple IDs within same millisecond
- Server ID - unique identifier (0-99) for machine/instance in cluster
Cluster Support
Server IDs are determined in the following priority order:- Environment variable JAVA_UTIL_CLUSTERID (0-99)
- Kubernetes Pod ID (extracted from metadata)
- VMware Tanzu instance ID
- Cloud Foundry instance index (CF_INSTANCE_INDEX)
- Hash of hostname modulo 100
- Random number (0-99) if all else fails
Available APIs
Two ID generation methods are provided with different characteristics:getUniqueId() - Format: timestampMs(13-14 digits).sequence(3 digits).serverId(2 digits) - Rate: Up to 1,000 IDs per millisecond - Range: Until year 5138 - Example: 1234567890123456.789.99 getUniqueId19() - Format: timestampMs(13 digits).sequence(4 digits).serverId(2 digits) - Rate: Up to 10,000 IDs per millisecond - Range: Until year 2286 (positive values) - Example: 1234567890123.9999.99
Guarantees
The generator provides the following guarantees:- IDs are unique across JVM restarts on the same machine
- IDs are unique across machines when proper server IDs are configured
- IDs are strictly monotonically increasing (each ID > previous ID)
- System clock regression is handled gracefully
- High sequence numbers cause waiting for next millisecond
- Author:
- John DeRegnaucourt ([email protected]), Roger Judd (@HonorKnight on GitHub) for adding code to ensure increasing order
Copyright (c) Cedar Software LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
License
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
-
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic Date
getDate
(long uniqueId) Extracts the date-time from an ID generated bygetUniqueId()
.static Date
getDate19
(long uniqueId) Extracts the date-time from an ID generated bygetUniqueId19()
.static Instant
getInstant
(long uniqueId) Extracts the date-time from an ID generated bygetUniqueId()
.static Instant
getInstant19
(long uniqueId19) Extracts the date-time from an ID generated bygetUniqueId19()
.static long
Generates a unique, monotonically increasing ID with millisecond precision that's cluster-safe.static long
Generates a unique, monotonically increasing 19-digit ID optimized for higher throughput.
-
Field Details
-
JAVA_UTIL_CLUSTERID
- See Also:
-
KUBERNETES_POD_NAME
- See Also:
-
TANZU_INSTANCE_ID
- See Also:
-
CF_INSTANCE_INDEX
- See Also:
-
-
Method Details
-
getUniqueId
public static long getUniqueId()Generates a unique, monotonically increasing ID with millisecond precision that's cluster-safe.ID Format
The returned long value contains three components:[timestamp: 13-14 digits][sequence: 3 digits][serverId: 2 digits] Example: 1234567890123456.789.99 (dots for clarity, actual value has no dots)
Characteristics
- Supports up to 1,000 unique IDs per millisecond (sequence 000-999)
- Generates positive values until year 5138
- Guaranteed monotonically increasing even across millisecond boundaries
- Thread-safe through internal locking
- Handles system clock regression gracefully
- Blocks when sequence number exhausted within a millisecond
- Returns:
- A unique, time-based ID encoded as a long value
- See Also:
-
getUniqueId19
public static long getUniqueId19()Generates a unique, monotonically increasing 19-digit ID optimized for higher throughput.ID Format
The returned long value contains three components:[timestamp: 13 digits][sequence: 4 digits][serverId: 2 digits] Example: 1234567890123.9999.99 (dots for clarity, actual value has no dots)
Characteristics
- Supports up to 10,000 unique IDs per millisecond (sequence 0000-9999)
- Generates positive values until year 2286 (after which values may be negative)
- Guaranteed monotonically increasing even across millisecond boundaries
- Thread-safe through internal locking
- Handles system clock regression gracefully
- Blocks when sequence number exhausted within a millisecond
Performance Comparison
This method is optimized for higher throughput compared togetUniqueId()
:- Supports 10x more IDs per millisecond (10,000 vs 1,000)
- Trades timestamp range for increased sequence capacity
- Recommended for high-throughput scenarios through year 2286
- Returns:
- A unique, time-based ID encoded as a long value
- See Also:
-
getDate
Extracts the date-time from an ID generated bygetUniqueId()
.- Parameters:
uniqueId
- A unique ID previously generated bygetUniqueId()
- Returns:
- The Date representing when the ID was generated, accurate to the millisecond
- Throws:
IllegalArgumentException
- if the ID was not generated bygetUniqueId()
-
getDate19
Extracts the date-time from an ID generated bygetUniqueId19()
.- Parameters:
uniqueId
- A unique ID previously generated bygetUniqueId19()
- Returns:
- The Date representing when the ID was generated, accurate to the millisecond
- Throws:
IllegalArgumentException
- if the ID was not generated bygetUniqueId19()
-
getInstant
Extracts the date-time from an ID generated bygetUniqueId()
.- Parameters:
uniqueId
- A unique ID previously generated bygetUniqueId()
- Returns:
- The Instant representing when the ID was generated, accurate to the millisecond
- Throws:
IllegalArgumentException
- if the ID was not generated bygetUniqueId()
-
getInstant19
Extracts the date-time from an ID generated bygetUniqueId19()
.- Parameters:
uniqueId19
- A unique ID previously generated bygetUniqueId19()
- Returns:
- The Instant representing when the ID was generated, accurate to the millisecond
- Throws:
IllegalArgumentException
- if the ID was not generated bygetUniqueId19()
-