雪花算法(DELPHI实现)

生成ID能够按照时间有序生成。

分布式系统内不会产生重复id(用workerId来做区分)。

自增ID:对于数据敏感场景不宜使用,且不适合于分布式场景。

GUID:采用无意义字符串,数据量增大时造成访问过慢,且不宜排序。

算法描述:

  • 最高位是符号位,始终为0,不可用。
  • 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。
  • 10位的机器标识,10位的长度最多支持部署1024个节点。
  • 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。

在delphi7下面,测试通过。

下面的算法,适用于单机构生成不重复ID。

unit Snowflake;

interface

uses
SysUtils, SyncObjs, DateUtils; type
TSnowflake = class
private
FMachineID: integer; //机器号
FLocker: TCriticalSection;
fTime: Int64; //时间戳
fsn: int64; //序列
public
constructor Create;
destructor Destroy; override;
property MachineID: Integer read FMachineID write FMachineID;
function Generate: Int64;
end; implementation const
Epoch: int64 = 1539615188000; //北京时间2018-10-15号
MachineBits: Byte = 10; //机器号10位 0..1023
snBits: Byte = 12; //序列号12位
timeShift: Byte = 22; //时间戳左移位数=序列号12位+机器号10位
machineShift: Byte = 12; //工作站左移位数
snMask: Word = 4095; //12位的计数序列号支持每个节点每毫秒产生4096个ID序号 { TSnowflake } constructor TSnowflake.Create;
begin
FLocker := TCriticalSection.Create;
end; destructor TSnowflake.Destroy;
begin
FLocker.Free;
inherited;
end; function TSnowflake.Generate: Int64;
var
curtime: Int64;
begin
FLocker.Acquire;
try
curtime := DateTimeToUnix(Now) * 1000;
if curtime = fTime then
begin
fsn := (fsn + 1) and snMask;
if fsn = 0 then
begin
while curtime <= fTime do
curtime := DateTimeToUnix(Now) * 1000;
end;
end
else
fsn := 0;
fTime := curtime;
Result := (curtime - Epoch) shl timeShift or FMachineID shl machineShift or fsn;
finally
FLocker.Release;
end;
end; initialization end.

 下面的算法,适用于连锁机构生成分布式ID:

unit Snowflake;
{ 调用演示
procedure TForm1.Button1Click(Sender: TObject);
var s: TSnowflake;
i: Integer;
begin
s := TSnowflake.Create;
s.OrgID := 8;
s.MachineID :=10;
for i:=1 to 30 do
begin
Memo1.Lines.Add(IntToStr(s.Generate));
end;
s.Free;
end;
}
interface uses
SysUtils, SyncObjs, DateUtils; type
TSnowflake = class
private
FOrgID: Integer; //机构号
FMachineID: integer; //机器号
FLocker: TCriticalSection;
fTime: Int64; //时间戳
fsn: int64; //序列
public
constructor Create;
destructor Destroy; override;
property MachineID: Integer read FMachineID write FMachineID;
property OrgID: Integer read FOrgID write FOrgID;
function Generate: Int64;
end; implementation const
Epoch: int64 = 1539615188000; //北京时间2018-10-15号 curtime := DateTimeToUnix(Now) * 1000;
OrgBits: Byte = 5; //机构号 0..31
MachineBits: Byte = 5; //机器号 0..31
snBits: Byte = 12; //序列号12位
timeShift: Byte = 22; //时间戳左移位数=序列号位数+机器号位数+机构号位数
orgShift: Byte = 17; //机构号左移位数=序列号位数+机器号位数
machineShift: Byte = 12; //工作站左移位数=序列号位数
snMask: Word = 4095; //12位的计数序列号支持每个节点每毫秒产生4096个ID序号 { TSnowflake } constructor TSnowflake.Create;
begin
FLocker := TCriticalSection.Create;
end; destructor TSnowflake.Destroy;
begin
FLocker.Free;
inherited;
end; function TSnowflake.Generate: Int64;
var
curtime: Int64;
begin
FLocker.Acquire;
try
curtime := DateTimeToUnix(Now) * 1000;
if curtime = fTime then
begin
fsn := (fsn + 1) and snMask;
if fsn = 0 then
begin
while curtime <= fTime do
curtime := DateTimeToUnix(Now) * 1000;
end;
end
else
fsn := 0;
fTime := curtime;
Result := (curtime - Epoch) shl timeShift
or FOrgID shl orgShift
or FMachineID shl machineShift
or fsn;
finally
FLocker.Release;
end;
end; initialization end.

  

 

  演示效果:

雪花算法(DELPHI实现)的更多相关文章

  1. 雪花算法(snowflake)delphi版

    雪花算法简单描述: + 最高位是符号位,始终为0,不可用. + 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序. + 10位的机器标识,1 ...

  2. Snowflake(雪花算法)的JavaScript实现

    现在好多的ID都是服务器端生成的,当然JS也可以生成GUID或者UUID之类的,但是如果想要有序……这时就想到了雪花算法,但是都知道JS中Number的最大值为Number.MAX_SAFE_INTE ...

  3. ID 生成器 雪花算法

    https://blog.csdn.net/wangming520liwei/article/details/80843248 ID 生成器 雪花算法 2018年06月28日 14:58:43 wan ...

  4. 分布式系统-主键唯一id,订单编号生成-雪花算法-SnowFlake

    分布式系统下 我们每台设备(分布式系统-独立的应用空间-或者docker环境) * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作 ...

  5. 分布式Snowflake雪花算法

    前言 项目中主键ID生成方式比较多,但是哪种方式更能提高的我们的工作效率.项目质量.代码实用性以及健壮性呢,下面作了一下比较,目前雪花算法的优点还是很明显的. 优缺点比较 UUID(缺点:太长.没法排 ...

  6. 一个类似 Twitter 雪花算法 的 连续序号 ID 产生器 SeqIDGenerator

    项目地址 :     https://github.com/kelin-xycs/SeqIDGenerator 今天 QQ 群 里有网友问起产生唯一 ID 的方法 有哪些,  讨论了各种方法 . 有网 ...

  7. mybatis plus 主键生成 Twitter雪花算法 id 及修改id为字符型

    mybatis plus配置主键生成策略为2,就是 使用Twitter雪花算法 生成id spring boot中配置为: GlobalConfiguration conf = new GlobalC ...

  8. Twitter雪花算法 SnowFlake算法 的java实现

    概述 SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序. 原理 Sn ...

  9. .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块

    .Net Core ORM选择之路,哪个才适合你   因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别 ...

随机推荐

  1. java中级面试题

    1.Java中堆和栈有什么不同? 每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的.而堆是所有线程共享的一片公用内存区域.对象都在堆里创建,为了提 ...

  2. extjs6 创建工程和打包发布

    准备工作: 下载extjs6的开发包,我这里是试验版:ext-6.6.0-trial.zip.解压到某个目录,我这里解压到:D:\tools\about-ext\ext-6.6.0-trial 目录下 ...

  3. JavaIO模型--装饰者模式

    JavaIO体现出装饰者的设计模式 今天在学SparkRDD之前,听了一堂复习JavaIO的课,觉得讲得不错 Java的IO一直让我觉得一层一层的很麻烦,刚接触的时候,理不太清楚 只知道要分解为输入输 ...

  4. Android笔记(三十五) Android中AsyncTask

    AsyncTask<Params,Progress,Result> 是一个抽象类,通常继承这个抽象类需要指定如下几个泛型参数: 1.  Params :启动任务时出入参数的类型 2.  P ...

  5. const变量可以修改么?

    遇到了一个关于const修饰的变量值是否能修改问题,虽然我知道const变量在某些情况下可以通过指向它的指针来间接修改,但是对原理还是很模糊,今天就整理了一下. 一.三个试验压压惊 1.直接对cons ...

  6. 如何在windows server2016搭建DHCP服务器

    DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议.指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分 ...

  7. Android-jacoco代码覆盖率:单元测试覆盖率+功能测试覆盖率

    参考:https://docs.gradle.org/current/dsl/org.gradle.testing.jacoco.tasks.JacocoCoverageVerification.ht ...

  8. Latex快速注释掉多行

    最简单的方法就是选中你想要注释掉的内容,同时按住Ctrl+Alt+Shift+→

  9. win10 水晶报表安装包

    windows 10 64 VS2013安装 CR For VS 13_0_18 安装过程没有报错 安装成功http://downloads.businessobjects.com/akdlm/cr4 ...

  10. css3多列布局瀑布流加载样式

    看了一些网站的瀑布流加载,正好看到css3的多列属性,尝试着写了一个css做布局的瀑布流. 直接上代码: <!DOCTYPE html> <html lang="en&qu ...