All Downloads are FREE. Search and download functionalities are using the official Maven repository.

im.shs.tick.sequence.seq.impl.DefaultRangeSequence Maven / Gradle / Ivy

package im.shs.tick.sequence.seq.impl;

import im.shs.tick.core.Env;
import im.shs.tick.core.utils.SpringUtil;
import im.shs.tick.sequence.exception.SeqException;
import im.shs.tick.sequence.range.BizName;
import im.shs.tick.sequence.range.SeqRange;
import im.shs.tick.sequence.range.SeqRangeMgr;
import im.shs.tick.sequence.seq.RangeSequence;
import im.shs.tick.sequence.seq.format.GenerateNoFormat;
import im.shs.tick.core.utils.RandomType;
import im.shs.tick.core.utils.StringUtil;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 序列号区间生成器接口默认实现
 * 根据biz name 自增
 */
public class DefaultRangeSequence implements RangeSequence {

	private static Map seqRangeMap = new ConcurrentHashMap<>(8);

	/**
	 * 获取区间是加一把独占锁防止资源冲突
	 */
	private final Lock lock = new ReentrantLock();

	/**
	 * 序列号区间管理器
	 */
	private SeqRangeMgr seqRangeMgr;

	/**
	 * 当前序列号区间
	 */
	private volatile SeqRange currentRange;

	/**
	 * 需要获取区间的业务名称
	 */
	private BizName bizName;

	/**
	 * 格式
	 */
	private GenerateNoFormat format;

	/**
	 * 前缀
	 */
	private String bizPrefix;

	/**
	 * 是否添加环境参数
	 */
	private boolean addEnv;

	/**
	 * 添加随机数位数
	 */
	private int addRandom = 0;

	@Override
	public long nextValue() throws SeqException {
		String name = bizName.create();

		currentRange = seqRangeMap.get(name);
		//当前区间不存在,重新获取一个区间
		if (null == currentRange) {
			lock.lock();
			try {
				if (null == currentRange) {
					currentRange = seqRangeMgr.nextRange(name);
					seqRangeMap.put(name, currentRange);
				}
			} finally {
				lock.unlock();
			}
		}

		//当value值为-1时,表明区间的序列号已经分配完,需要重新获取区间
		long value = currentRange.getAndIncrement();
		if (value == -1) {
			lock.lock();
			try {
				for (; ; ) {
					if (currentRange.isOver()) {
						currentRange = seqRangeMgr.nextRange(name);
					}

					value = currentRange.getAndIncrement();
					if (value == -1) {
						continue;
					}

					break;
				}
			} finally {
				lock.unlock();
			}
		}

		if (value < 0) {
			throw new SeqException("Sequence value overflow, value = " + value);
		}

		return value;
	}

	/**
	 * 下一个生成序号(带格式)
	 *
	 * @return
	 * @throws SeqException
	 */
	@Override
	public String nextNo() throws SeqException {
		StringBuilder noBuilder = new StringBuilder();
		noBuilder.append(this.bizPrefix);
		if (this.addEnv) {
			Env profile = null;
			try {
				profile = SpringUtil.getActiveProfile();
			} catch (Exception e) {
				profile = Env.DEV;
			}

			switch (profile) {
				case DEV:
					noBuilder.append("1");
					break;
				case TEST:
					noBuilder.append("2");
					break;
				case PROD:
					noBuilder.append("3");
					break;
				default:
			}
		}
		switch (this.format) {
			case NONE:
				break;
			case DATE:
			case DATETIME:
			case DATETIME_MS:
			case TIME:
				noBuilder.append(this.format.getFmt());
			default:
		}
		if (this.addRandom > 0) {
			noBuilder.append(StringUtil.random(this.addRandom, RandomType.INT));
		}
		return noBuilder.append(String.format("%05d", nextValue())).toString();
	}

	@Override
	public void setSeqRangeMgr(SeqRangeMgr seqRangeMgr) {
		this.seqRangeMgr = seqRangeMgr;
	}

	@Override
	public void setName(BizName name) {
		this.bizName = name;
	}

	@Override
	public void setFormat(GenerateNoFormat format) {
		this.format = format;
	}

	@Override
	public void setBizPrefix(String bizPrefix) {
		this.bizPrefix = bizPrefix;
	}

	@Override
	public void setAddEnv(boolean addEnv) {
		this.addEnv = addEnv;
	}

	@Override
	public void setAddRandom(int addRandom) {
		this.addRandom = addRandom;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy