shz.core.id.SFIdProducer Maven / Gradle / Ivy
package shz.core.id;
import shz.core.ToString;
public class SFIdProducer implements IdProducer {
public static final SFIdProducer DEFAULT = new SFIdProducer(new IdInfo());
private final long totalBits;
protected final IdInfo idInfo;
private final long datacenterIdResult, workerIdResult;
/**
* 起始时间戳,id中有效值 ,这个值的设置直接影响到id的使用年限
*/
protected long startTimestamp = 1604764800000L;
/**
* 最后时间戳,防止时钟回拨
*/
private long lastTimestamp;
public SFIdProducer(IdInfo idInfo) {
totalBits = idInfo.datacenterIdBits + idInfo.workerIdBits + idInfo.timestampBits + idInfo.sequenceBits;
if (totalBits > 63L || totalBits < 52L) throw new IllegalArgumentException("id位数取值范围:52-63");
if (idInfo.datacenterId > (~(-1L << idInfo.datacenterIdBits)) || idInfo.datacenterId < 0L)
throw new IllegalArgumentException(ToString.format("中心节点取值范围:0-%d", ~(-1L << idInfo.datacenterIdBits)));
if (idInfo.workerId > (~(-1L << idInfo.workerIdBits)) || idInfo.workerId < 0L)
throw new IllegalArgumentException(ToString.format("工作节点取值范围:0-%d", ~(-1L << idInfo.workerIdBits)));
this.idInfo = idInfo;
datacenterIdResult = this.idInfo.datacenterId << (this.idInfo.sequenceBits + this.idInfo.workerIdBits);
workerIdResult = this.idInfo.workerId << this.idInfo.sequenceBits;
}
public final void setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
}
public final void setLastTimestamp(long lastTimestamp) {
this.lastTimestamp = lastTimestamp;
}
/**
* 保存最后时间戳
*/
protected void saveLastTimestamp(long lastTimestamp) {
}
/**
* 同一毫秒内的自增序列
*/
private long sequence;
@Override
public final synchronized Long next() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp)
throw new RuntimeException(ToString.format("时钟回拨:%d毫秒", lastTimestamp - timestamp));
if (timestamp == lastTimestamp) {
sequence = (sequence + 1) & (~(-1L << idInfo.sequenceBits));
if (sequence == 0L) {
do {
timestamp = System.currentTimeMillis();
} while (timestamp <= lastTimestamp);
saveLastTimestamp(timestamp);
}
} else {
sequence = 0L;
saveLastTimestamp(timestamp);
}
lastTimestamp = timestamp;
long timestampVal = (timestamp - startTimestamp) << (idInfo.sequenceBits + idInfo.workerIdBits + idInfo.datacenterIdBits);
return (timestampVal & (~(-1L << totalBits)))
| datacenterIdResult
| workerIdResult
| sequence;
}
@Override
public final IdInfo analyze(Long id) {
if (id == null) return null;
IdInfo idInfo = new IdInfo();
//可能是被截取的时间戳
idInfo.timestamp = (id >>> (this.idInfo.sequenceBits + this.idInfo.workerIdBits + this.idInfo.datacenterIdBits)) + startTimestamp;
idInfo.datacenterId = id >>> (this.idInfo.sequenceBits + this.idInfo.workerIdBits) & (~(-1L << this.idInfo.datacenterIdBits));
idInfo.workerId = id >>> this.idInfo.sequenceBits & (~(-1L << this.idInfo.workerIdBits));
idInfo.sequence = id & (~(-1L << this.idInfo.sequenceBits));
idInfo.datacenterIdBits = this.idInfo.datacenterIdBits;
idInfo.workerIdBits = this.idInfo.workerIdBits;
idInfo.timestampBits = this.idInfo.timestampBits;
idInfo.sequenceBits = this.idInfo.sequenceBits;
return idInfo;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy