标签:begin end FLastTime Delphi TSnowflakeAlgorithm 雪花 毫秒 FNowTime ID
RAD Studio 10.2.3 测试√
单元文件
unit uAlgorithm;
interface
uses
Winapi.Windows, System.DateUtils, System.SysUtils;
type
// 算法
TAlgorithm = class
end;
// 雪花算法
{
雪花算法简单描述:
+ 最高位是符号位,始终为0,不可用。
+ 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。
+ 10位的机器标识,10位的长度最多支持部署1024个节点。
+ 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。
}
TSnowflakeAlgorithm = class(TAlgorithm)
private
FCS: TRTLCriticalSection; // 临界区
FNowTime: Int64; // 现在时间[单位: ms]
FLastTime: Int64; // 上个时间[单位: ms]
FMachineID: Integer; // 机器标识 0 .. 1023 [十进制 1023 = 二进制 1111111111 ]
FCount: Integer; // 计数序列号 0 .. 4095 [十进制 4095 = 二进制 111111111111 ]
public
constructor Create;
destructor Destroy; override;
function GetSnowflakeID: Int64; // 获取雪花ID
end;
var
G_SnowflakeAlgorithm: TSnowflakeAlgorithm;
implementation
{ TSnowflakeAlgorithm }
constructor TSnowflakeAlgorithm.Create;
begin
InitializeCriticalSection(FCS); // 初始化临界区
FMachineID := 999; // 固定的机器 ID
FLastTime := MilliSecondsBetween(Now, EncodeDateTime(1970, 1, 1, 8, 0, 0, 0));
FCount := 0;
end;
destructor TSnowflakeAlgorithm.Destroy;
begin
DeleteCriticalSection(FCS); // 删除临界区
inherited;
end;
function TSnowflakeAlgorithm.GetSnowflakeID: Int64;
begin
EnterCriticalSection(FCS);
try
FNowTime := MilliSecondsBetween(Now, EncodeDateTime(1970, 1, 1, 8, 0, 0, 0)); // 当前毫秒时间戳
if FLastTime = FNowTime then // 如果上一毫秒的时间 = 现在的时间
begin
if FCount > 4095 then // 如果同一毫秒内生成的 ID 个数 > 4096
begin
// Sleep(1); // 等待下一毫秒再进行生成
while FLastTime >= FNowTime do
begin
FNowTime := MilliSecondsBetween(Now, EncodeDateTime(1970, 1, 1, 8, 0, 0, 0));
end;
FLastTime := FNowTime; // 重新给上一毫秒时间 赋值
end;
end
else
begin
FCount := 0; // 初始化计数
FLastTime := FNowTime; // 重新给上一毫秒时间 赋值
end;
Result := (FNowTime shl 22) or (FMachineID shl 12) or FCount;
Inc(FCount); // 对计数变量进行自增
finally
LeaveCriticalSection(FCS);
end;
end;
end.
用法
procedure TForm1.Button_SnowflakeIDClick(Sender: TObject);
var
i: Integer;
begin
// 时间是从1970年1月1日8点到当前的间隔[单位: ms]
Memo1.Lines.Add('当前时间戳: ' + IntToStr(MilliSecondsBetween(Now, EncodeDateTime(1970, 1, 1, 8, 0, 0, 0))));
G_SnowflakeAlgorithm := TSnowflakeAlgorithm.Create;
for i := 0 to 100 do
begin
Memo1.Lines.Add((G_SnowflakeAlgorithm.GetSnowflakeID).ToString);
end;
G_SnowflakeAlgorithm.Free;
end;
运行结果
一点点笔记,以便以后翻阅。
标签:begin,end,FLastTime,Delphi,TSnowflakeAlgorithm,雪花,毫秒,FNowTime,ID 来源: https://blog.csdn.net/qq_44111597/article/details/116459032
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。