(*
Delphi版雪花算法
作者:不得闲 QQ:75492895
用于生成Int64位的唯一值ID,WorkerID用于区分工作站,
ID会随着时间增加位数,每毫秒可生成4096个ID
用法:
创建全局变量:snow: TDxSnowflake;
创建对象:snow := TDxSnowflake.Create; // 不要忘了在退出时释放snow.Free;
调用:
snow.WorkerID:=100;
snow.DatacenterId:=22;
mmo1.Lines.Add( FormatFloat('#0',snow.Generate));
*)
unit DxSnowflake;
interface
uses
System.SysUtils, System.SyncObjs, System.Generics.Collections, System.DateUtils;
type
TWorkerID = 0..1023;
TdatacenterId = 0..1023;
TDxSnowflake = class
private
FWorkerID: TWorkerID;
FdatacenterId: TdatacenterId;
FLocker: TCriticalSection;
fTime: Int64;
fstep: Int64;
public
constructor Create;
destructor Destroy; override;
property WorkerID: TWorkerID read FWorkerID write FWorkerID;
property DatacenterId: TdatacenterId read FdatacenterId write FdatacenterId;
function Generate: Int64;
end;
implementation
const
Epoch: Int64 = 1568185522000; // 北京时间2018-10-15号
// 工作站的节点位数
WorkerNodeBits: Byte = 5;
//机构数据中心位数
DatacenterNodeBits: Byte = 5;
// 序列号的节点数
StepBits: Byte = 12;
nodeShift: Byte = 12;
var
WorkerNodeMax, DatacenterNodeMax: Int64;
nodeMask: Int64;
stepMask: Int64;
workerIdShift: Byte;
datacenterIdShift: Byte;
timeShift: Byte;
procedure InitNodeInfo;
begin
workerIdShift := StepBits;
datacenterIdShift := StepBits + WorkerNodeBits;
timeShift := StepBits + WorkerNodeBits + DatacenterNodeBits;
WorkerNodeMax := -1 xor (-1 shl WorkerNodeBits);
DatacenterNodeMax := -1 xor (-1 shl DatacenterNodeBits);
nodeMask := WorkerNodeMax shl StepBits;
stepMask := -1 xor (-1 shl StepBits);
end;
{ TDxSnowflake }
constructor TDxSnowflake.Create;
begin
FLocker := TCriticalSection.Create;
end;
destructor TDxSnowflake.Destroy;
begin
FLocker.Free;
inherited;
end;
function TDxSnowflake.Generate: Int64;
var
curtime: Int64;
begin
FLocker.Acquire;
try
curtime := DateTimeToUnix(Now) * 1000;
if curtime = fTime then
begin
fstep := (fstep + 1) and stepMask;
if fstep = 0 then
begin
while curtime <= fTime do
curtime := DateTimeToUnix(Now) * 1000;
end;
end
else
fstep := 0;
fTime := curtime;
Result := ((curtime - Epoch) shl timeShift)
or (FdatacenterId shl datacenterIdShift) or (FWorkerID shl workerIdShift) or fstep;
finally
FLocker.Release;
end;
end;
initialization
InitNodeInfo;
end.
Delphi版雪花算法
猜你喜欢
转载自blog.csdn.net/y281252548/article/details/100736974
今日推荐
周排行