雪花算法(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. flutter入门之常见的flutter问题汇总(转)

    1. 使用AppBar后如何去掉左边的返回箭头.左边的图标对应的是leading,源代码如下(吐槽一下,CSDN暂不支持dart语言): Widget leading = widget.leading ...

  2. Jerry带您了解Restful ABAP Programming模型系列之二:Action和Validation的实现

    相信通过Jerry的前一篇文章 30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用,想必大家对Restful ABAP Programming模型已经有 ...

  3. (二)react-native开发系列之windows开发环境配置

    之前写了react-native在mac上得环境搭建,但是如果只开发android的话,只要用windows系统就可以了,下面就来说下react-native的windows开发环境配置. 1.下载配 ...

  4. 二进制部署kubernetes集群(下篇)

    1.k8S核心资源管理方法 1.1.陈述式资源管理方法 1.1.1.管理名称空间资源 1.1.1.1.查看名称空间 [root@hdss7-21 ~]# kubectl get namespace N ...

  5. 蓝桥杯 ALGO-156 表达式计算 JAVA代码 栈的应用

     算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB      问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个 ...

  6. 刷题小tips

    自从认真做题以后,结合自己的做题体验以及网上前人的总结经验贴,罗列下列的小建议: 1.为了避免每一次都要重复输入测试数据的麻烦,利用输入重定向文件 我是只把标准输入stdin重定位到in.txt,然后 ...

  7. [课本10.1.4]JDBC数据库连接池- C3P0数据源--通过构造方法创建数据源对象--通过配置文件创建数据源对象[推荐]

    JDBC- C3P0数据源 /*重点提醒*/ 连接数据库的较低的jar包版本会与较高版本的mysql版本有冲突; 通过把mysql 8.0的版本降到5.5, jar包仍使用较高的 mysql-conn ...

  8. python练习题(二)

    题目: 已知以下几期双色球号码(最后一个数字为蓝球), 2019080 03 06 08 20 24 32 07 2019079 01 03 06 09 19 31 16 2019078 01 17 ...

  9. Java锁--CyclicBarrier

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3533995.html CyclicBarrier简介 CyclicBarrier是一个同步辅助类,允许一 ...

  10. 关于LinkedList for OpenJDK

    概述      LinkedList采用底层采用双向链表结构,与ArrayList的数组结构不一样.LinkedList因数据结构不一样,不需要申请连续内存,可以利用碎片内存.元素保存数据内容外还需要 ...