雪花算法-PHP

<?php
namespace App;

class SnowFlake
{  
    //開始時間,固定一個小于當前時間的毫秒數(shù)即可  
    const twepoch =  1474992000000;//2016/9/28 0:0:0  
  
    //機器標識占的位數(shù)  
    const workerIdBits = 10;  
  
    //毫秒內(nèi)自增數(shù)點的位數(shù)  
    const sequenceBits = 12;  
  
    protected $workId = 0;  
  
    //要用靜態(tài)變量  
    static $lastTimestamp = -1;  
    static $sequence = 0;  
  
  
    function __construct($workId){  
        //機器ID范圍判斷  
        $maxWorkerId = -1 ^ (-1 << self::workerIdBits);  
        if($workId > $maxWorkerId || $workId< 0){  
            throw new Exception("workerId can't be greater than ".$maxWorkerId." or less than 0");  
        }  
        //賦值  
        $this->workId = $workId;  
    }  
  
    //生成一個ID  
    public  function nextId(){
        $timestamp = $this->timeGen();  
        $lastTimestamp = self::$lastTimestamp;  
        //判斷時鐘是否正常  
        if ($timestamp < $lastTimestamp) {  
            throw new Exception("Clock moved backwards.  Refusing to generate id for %d milliseconds", ($lastTimestamp - $timestamp));  
        }  
        //生成唯一序列  
        if ($lastTimestamp == $timestamp) {  
            $sequenceMask = -1 ^ (-1 << self::sequenceBits);  
            self::$sequence = (self::$sequence + 1) & $sequenceMask;  
            if (self::$sequence == 0) {  
                $timestamp = $this->tilNextMillis($lastTimestamp);  
            }  
        } else {  
            self::$sequence = 0;  
        }  
        self::$lastTimestamp = $timestamp;  
        //  
        //時間毫秒/數(shù)據(jù)中心ID/機器ID,要左移的位數(shù)  
        $timestampLeftShift = self::sequenceBits + self::workerIdBits;  
        $workerIdShift = self::sequenceBits;  
        //組合3段數(shù)據(jù)返回: 時間戳.工作機器.序列  
        $nextId = (($timestamp - self::twepoch) << $timestampLeftShift) | ($this->workId << $workerIdShift) | self::$sequence;  
        return $nextId;  
    }  
  
    //取當前時間毫秒  
    protected function timeGen(){  
        $timestramp = (float)sprintf("%.0f", microtime(true) * 1000);  
        return  $timestramp;  
    }  
  
    //取下一毫秒  
    protected function tilNextMillis($lastTimestamp) {  
        $timestamp = $this->timeGen();  
        while ($timestamp <= $lastTimestamp) {  
            $timestamp = $this->timeGen();  
        }  
        return $timestamp;  
    }  
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容