基于php雪花算法工具类Snowflake -来自chatGPT

php 复制代码
<?php

class Snowflake {
    // 定义Snowflake算法的各个参数
    private $workerIdBits = 5;
    private $datacenterIdBits = 5;
    private $sequenceBits = 12;

    private $workerIdShift;
    private $datacenterIdShift;
    private $timestampLeftShift;

    private $maxWorkerId;
    private $maxDatacenterId;
    private $sequenceMask;

    private $workerId;
    private $datacenterId;
    private $sequence = 0;
    private $lastTimestamp = -1;

    public function __construct($workerId, $datacenterId) {
        // 计算位偏移量
        $this->workerIdShift = $this->sequenceBits;
        $this->datacenterIdShift = $this->sequenceBits + $this->workerIdBits;
        $this->timestampLeftShift = $this->sequenceBits + $this->workerIdBits + $this->datacenterIdBits;

        // 计算最大ID
        $this->maxWorkerId = -1 ^ (-1 << $this->workerIdBits);
        $this->maxDatacenterId = -1 ^ (-1 << $this->datacenterIdBits);
        $this->sequenceMask = -1 ^ (-1 << $this->sequenceBits);

        // 初始化参数
        $this->workerId = $workerId;
        $this->datacenterId = $datacenterId;
    }

    // 生成下一个唯一ID
    public function generateId() {
        // 获取当前时间戳(毫秒级)
        $timestamp = floor(microtime(true) * 1000);

        // 如果当前时间小于上次生成ID的时间戳,则抛出异常
        if ($timestamp < $this->lastTimestamp) {
            throw new Exception("Invalid system clock!");
        }

        // 如果当前时间戳与上次时间戳相同,则自增序列号
        if ($timestamp == $this->lastTimestamp) {
            $this->sequence = ($this->sequence + 1) & $this->sequenceMask;

            // 如果序列号等于0,则需要进入下一毫秒重新生成ID
            if ($this->sequence == 0) {
                $timestamp = $this->waitNextMillis($this->lastTimestamp);
            }
        } else {
            $this->sequence = 0;
        }

        // 保存最后生成ID的时间戳
        $this->lastTimestamp = $timestamp;

        // 生成最终的唯一ID
        $uniqueId = (($timestamp << $this->timestampLeftShift) |
                     ($this->datacenterId << $this->datacenterIdShift) |
                     ($this->workerId << $this->workerIdShift) |
                     $this->sequence);

        return $uniqueId;
    }

    // 阻塞到下一个毫秒,直到获得新的时间戳
    private function waitNextMillis($lastTimestamp) {
        $timestamp = floor(microtime(true) * 1000);
        while ($timestamp <= $lastTimestamp) {
            usleep(1000);
            $timestamp = floor(microtime(true) * 1000);
        }
        return $timestamp;
    }
}

// 测试方法
$snowflake = new Snowflake(1, 1);
for ($i = 0; $i < 10; $i++) {
    $uniqueId = $snowflake->generateId();
    echo $uniqueId . "\n";
}

?>

在上述代码中,我们创建了一个名为Snowflake的类,该类用于生成Snowflake算法的唯一ID。它具有以下主要属性和方法:

  • __construct($workerId, $datacenterId):初始化Snowflake算法的参数,包括工作节点ID(workerId)和数据中心ID(datacenterId)。
  • generateId():生成下一个唯一ID。
  • waitNextMillis($lastTimestamp):阻塞到下一个毫秒,直到获得新的时间戳。

在测试方法中,我们创建了一个Snowflake实例,并使用其generateId()方法生成了10个唯一ID,并打印出来。

相关推荐
啊森要自信17 分钟前
【GUI自动化测试】Python 自动化测试框架 pytest 全面指南:基础语法、核心特性(参数化 / Fixture)及项目实操
开发语言·python·ui·单元测试·pytest
赵谨言28 分钟前
基于python智能家居环境质量分析系统的设计与实现
开发语言·经验分享·python·智能家居
qq_2529241928 分钟前
PHP 8.0+ 编译器级优化与语言运行时演进
php·学习php·php入门
元亓亓亓40 分钟前
考研408--组成原理--day1
开发语言·javascript·考研·计组
仰泳的熊猫1 小时前
LeetCode:538. 把二叉搜索树转换为累加树/1038. 从二叉搜索树到更大和树
数据结构·c++·算法·leetcode
Yurko131 小时前
【C语言】环境安装(图文)与介绍
c语言·开发语言·学习
仲星(._.)1 小时前
C语言:字符函数和字符串函数
c语言·开发语言
kyle~1 小时前
C++---向上取整
开发语言·c++
QX_hao1 小时前
【Go】--扩容机制
开发语言·golang
weixin_307779131 小时前
Clickhouse导出库的表、视图、用户和角色定义的SQL语句
开发语言·数据库·算法·clickhouse·自动化