You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.7 KiB
Java
94 lines
2.7 KiB
Java
package com.engine.common.util.genid;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
public class SnowflakeId {
|
|
private static final Logger logger = LoggerFactory.getLogger(SnowflakeId.class);
|
|
private Worker worker;
|
|
private long startTime = this._curSecond();
|
|
private long time;
|
|
private long segment = 0L;
|
|
private long workerId = this.getWorker().getWorkerId();
|
|
private long sequence = 0L;
|
|
private static final long segmentBits = 9L;
|
|
private static final long workerIdBits = 10L;
|
|
private static final long sequenceBits = 13L;
|
|
private static final long timestampShift = 32L;
|
|
private static final long segmentShift = 23L;
|
|
private static final long workerIdShift = 13L;
|
|
private static final long sequenceMask = 8191L;
|
|
private static final long maxSegment = 511L;
|
|
private long twepoch = 1483200000L;
|
|
private long _counter = 0L;
|
|
|
|
public SnowflakeId() {
|
|
this.time = this.startTime - this.twepoch;
|
|
}
|
|
|
|
public Worker getWorker() {
|
|
return (Worker)(this.worker == null ? new DefaultWorker() : this.worker);
|
|
}
|
|
|
|
public void setWorker(Worker worker) {
|
|
this.worker = worker;
|
|
}
|
|
|
|
public synchronized long get() {
|
|
long id = this.getNextId();
|
|
this.testSpeedLimit();
|
|
return id;
|
|
}
|
|
|
|
public synchronized long[] getRangeId(int sizeOfIds) {
|
|
long[] r = new long[]{this.getNextId(), 0L};
|
|
this.sequence = this.sequence + (long)sizeOfIds - 1L - 1L;
|
|
this._counter = this._counter + (long)sizeOfIds - 1L - 1L;
|
|
if (this.sequence >> 13 > 0L) {
|
|
this.sequence &= 8191L;
|
|
if (this.segment >= 511L) {
|
|
++this.time;
|
|
this.segment = 0L;
|
|
} else {
|
|
++this.segment;
|
|
}
|
|
}
|
|
|
|
r[1] = this.getNextId();
|
|
this.testSpeedLimit();
|
|
return r;
|
|
}
|
|
|
|
private long getNextId() {
|
|
++this.sequence;
|
|
++this._counter;
|
|
if (this.sequence >> 13 > 0L) {
|
|
if (this.segment >= 511L) {
|
|
++this.time;
|
|
} else {
|
|
this.sequence = 0L;
|
|
++this.segment;
|
|
}
|
|
}
|
|
|
|
return this.time << 32 | this.segment << 23 | this.workerId << 13 | this.sequence;
|
|
}
|
|
|
|
private long _curSecond() {
|
|
return System.currentTimeMillis() / 1000L;
|
|
}
|
|
|
|
private synchronized void testSpeedLimit() {
|
|
long spentTime = this._curSecond() - this.startTime + 1L;
|
|
if (spentTime <= 0L || spentTime << 22 <= this._counter) {
|
|
try {
|
|
this.wait(10L);
|
|
this.testSpeedLimit();
|
|
} catch (Exception var4) {
|
|
logger.error(var4.getMessage(), var4);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|