55 lines
1.7 KiB
Java
55 lines
1.7 KiB
Java
package net.xnzn.utils;
|
|
|
|
import com.google.common.base.Preconditions;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.ZoneId;
|
|
|
|
public class Id {
|
|
private static final long EPOCH = LocalDateTime.of(2021, 12, 29, 9, 2).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
|
private static final long SEQUENCE_BITS = 12L;
|
|
private static final long WORKER_ID_BITS = 10L;
|
|
static final long WORKER_ID_MAX_VALUE = 1024L;
|
|
private static final long SEQUENCE_MASK = 4095L;
|
|
private static final long WORKER_ID_LEFT_SHIFT_BITS = 12L;
|
|
private static final long TIMESTAMP_LEFT_SHIFT_BITS = 22L;
|
|
static Long WORKER_ID;
|
|
private static long SEQUENCE;
|
|
private static long LAST_TIME;
|
|
|
|
public Id(Long workerId) {
|
|
WORKER_ID = workerId;
|
|
}
|
|
|
|
public static long next() {
|
|
return nextKey();
|
|
}
|
|
|
|
public static String nextString() {
|
|
return String.valueOf(next());
|
|
}
|
|
|
|
private static synchronized long nextKey() {
|
|
long currentMillis = System.currentTimeMillis();
|
|
Preconditions.checkState(LAST_TIME <= currentMillis, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", LAST_TIME, currentMillis);
|
|
if (LAST_TIME == currentMillis) {
|
|
if (0L == (SEQUENCE = SEQUENCE + 1L & 4095L)) {
|
|
currentMillis = waitUntilNextTime(currentMillis);
|
|
}
|
|
} else {
|
|
SEQUENCE = 0L;
|
|
}
|
|
|
|
LAST_TIME = currentMillis;
|
|
return currentMillis - EPOCH << 22 | WORKER_ID << 12 | SEQUENCE;
|
|
}
|
|
|
|
private static long waitUntilNextTime(final long lastTime) {
|
|
long time;
|
|
for(time = System.currentTimeMillis(); time <= lastTime; time = System.currentTimeMillis()) {
|
|
}
|
|
|
|
return time;
|
|
}
|
|
}
|