Skip to content

Instantly share code, notes, and snippets.

@7u4
Created March 12, 2019 02:26
Show Gist options
  • Select an option

  • Save 7u4/fb90bd497ef659470316ec878df2fe85 to your computer and use it in GitHub Desktop.

Select an option

Save 7u4/fb90bd497ef659470316ec878df2fe85 to your computer and use it in GitHub Desktop.
sequential UUID using current time.Based on https://blog.2ndquadrant.com/sequential-uuid-generators/
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.time.Instant;
import java.util.UUID;
public final class UUIDUtils {
private static final int UUID_LENGTH = 16;
private static final int DEFAULT_INTERVAL_LENGTH = 60;
private static final int DEFAULT_INTERAVL_COUNT = 65536;
private static volatile SecureRandom numberGenerator = null;
/**
* Static factory to generate sequential UUID using current time
* <p>
* The timestamp-based sequential UUID generator define the group size
* and group count based on data extracted from current timestamp.
* <p>
* The interval_length (60 seconds by default) is defined as number of
* seconds where UUIDs share the same prefix). The prefix length is
* determined by the number of intervals (65536 by default, i.e. 2B).
* With these parameters the generator wraps around every ~45 days.
*
* @return A sequentialy generated {@code UUID} using current time
*/
public static UUID timeUUID() {
return timeUUID(DEFAULT_INTERVAL_LENGTH, DEFAULT_INTERAVL_COUNT);
}
/**
* Static factory to generate sequential UUID using current time
* <p>
* The timestamp-based sequential UUID generator define the group size
* and group count based on data extracted from current timestamp.
*
* @param intervalLength The number of seconds where {@code UUID} share the same prefix
* @param intervalCount Used to derive the prefix length
* @return A sequentialy generated {@code UUID} using current time
*/
public static UUID timeUUID(int intervalLength, int intervalCount) {
assert intervalLength > 1 : "length of interval must be a positive integer";
assert intervalCount > 1 : "number of intervals must be a positive integer";
SecureRandom ng = numberGenerator;
if (ng == null)
numberGenerator = ng = new SecureRandom();
int i;
ByteBuffer buffer = ByteBuffer.allocate(UUID_LENGTH);
long epoch = Instant.now().getEpochSecond();
byte[] val = Long.toString(epoch / intervalLength).getBytes();
int prefixBytes = 0;
while (intervalCount > 1) {
intervalCount /= 256;
prefixBytes++;
}
for (i = 0; i < prefixBytes; i++)
buffer.put(i, val[prefixBytes - 1 - i]);
byte[] randomBytes = new byte[UUID_LENGTH - prefixBytes];
ng.nextBytes(randomBytes);
for (i = 0; i < randomBytes.length; i++)
buffer.put(i + prefixBytes, randomBytes[i]);
return new UUID(buffer.getLong(), buffer.getLong());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment