001package top.cenze.utils;
002
003/**
004 * 雪花算法工具
005 *
006 * @author chengze
007 * @date 2023-11-14 22:24
008 */
009public class SnowflakeUtil {
010
011    //机群所占位数
012    private final static int fleetBit = 5;
013    //机器码所占位数
014    private final static int machineBit = 5;
015    //自增序列所占位数
016    private final static int sequenceBit = 12;
017
018    //机器码位移量
019    private final static int machineDisplacement = sequenceBit;
020    //机群位移量
021    private final static int fleetDisplacement = machineBit + sequenceBit;
022    //时间戳位移量
023    private final static int timeDisplacement = fleetBit + machineBit + sequenceBit;
024
025    //参照时间(2018-01-01 00:00:00)
026    private final static long referenceTime = 1514736000000L;
027
028    //自增序列最大值
029    private final static int sequenceMax = -1^(-1<<12);
030
031    //自增序列
032    private static int sequence = 0;
033
034    //上一次生成自增序列的时间
035    private static long lastTimeStamp = -1L;
036
037    /*
038     * @DescrIPtion 获取全局唯一ID
039     * @Param [fleetCode, machineCode]
040     * @return long
041     */
042    public static synchronized long getNextId(int fleetCode, int machineCode){
043        long currentTimeStamp = getCurrentTimeStamp();
044        if (lastTimeStamp == currentTimeStamp){
045            if (sequence >= sequenceMax){
046                currentTimeStamp = getNextTimeStamp();
047                lastTimeStamp = currentTimeStamp;
048                sequence = 0;
049            } else {
050                sequence++;
051            }
052
053        } else if (lastTimeStamp < currentTimeStamp){
054            sequence = 0;
055            lastTimeStamp = currentTimeStamp;
056        } else if (lastTimeStamp > currentTimeStamp){
057
058        }
059        long id = (currentTimeStamp-referenceTime) << timeDisplacement |
060                fleetCode << fleetDisplacement |
061                machineCode << machineDisplacement |
062                sequence;
063        return id;
064
065    }
066
067    /*
068     * @DescrIPtion 获取当前时间戳,精确到毫秒
069     * @Param []
070     * @return long
071     */
072    private static long getCurrentTimeStamp(){
073        return System.currentTimeMillis();
074    }
075
076    /*
077     * @DescrIPtion 当前毫秒自增序列已经达到最大值,等待获取下一毫秒
078     * @Param []
079     * @return long
080     */
081    private static long getNextTimeStamp(){
082        long timeStamp = getCurrentTimeStamp();
083        while (timeStamp <= lastTimeStamp){
084            timeStamp = getCurrentTimeStamp();
085        }
086        return timeStamp;
087    }
088}