package com.qianwen.core.sequence.sequence.impl;
|
|
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DateUtil;
|
import java.util.Date;
|
import java.util.Map;
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.ReentrantLock;
|
import com.qianwen.core.sequence.exception.SeqException;
|
import com.qianwen.core.sequence.range.BizName;
|
import com.qianwen.core.sequence.range.SeqRange;
|
import com.qianwen.core.sequence.range.SeqRangeMgr;
|
import com.qianwen.core.sequence.sequence.RangeSequence;
|
|
|
public class DefaultRangeSequence implements RangeSequence {
|
private final Lock lock = new ReentrantLock();
|
private SeqRangeMgr seqRangeMgr;
|
private volatile SeqRange currentRange;
|
private static Map<String, SeqRange> seqRangeMap = new ConcurrentHashMap(8);
|
private BizName bizName;
|
private Integer step;
|
private long startStep;
|
|
@Override // com.qianwen.core.sequence.sequence.RangeSequence
|
public void setSeqRangeMgr(SeqRangeMgr seqRangeMgr) {
|
this.seqRangeMgr = seqRangeMgr;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.RangeSequence
|
public void setName(BizName name) {
|
this.bizName = name;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.RangeSequence
|
public void setStep(Integer step) {
|
this.step = step;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.RangeSequence
|
public void setStartStep(long startStep) {
|
this.startStep = startStep;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.Sequence
|
public long nextValue() throws SeqException {
|
String name = this.bizName.create();
|
this.currentRange = seqRangeMap.get(name);
|
if (null == this.currentRange) {
|
this.lock.lock();
|
try {
|
if (null == this.currentRange) {
|
this.currentRange = this.seqRangeMgr.nextRange(name);
|
seqRangeMap.put(name, this.currentRange);
|
}
|
} finally {
|
}
|
}
|
long value = this.currentRange.getAndIncrement();
|
if (value == -1) {
|
this.lock.lock();
|
while (true) {
|
try {
|
if (this.currentRange.isOver()) {
|
this.currentRange = this.seqRangeMgr.nextRange(name);
|
seqRangeMap.put(name, this.currentRange);
|
}
|
value = this.currentRange.getAndIncrement();
|
if (value != -1) {
|
break;
|
}
|
} finally {
|
}
|
}
|
}
|
if (value < 0) {
|
throw new SeqException("Sequence value overflow, value = " + value);
|
}
|
return value;
|
}
|
|
@Override // com.qianwen.core.sequence.sequence.Sequence
|
public String nextNo() throws SeqException {
|
return String.format("%s%05d", DateUtil.format(new Date(), DatePattern.PURE_DATE_FORMAT), Long.valueOf(nextValue()));
|
}
|
}
|