1
0
mirror of synced 2025-12-18 11:08:03 +08:00
Files
SnowFlake-IdGenerator/Delphi/source/uDefaultIdGenerator.pas
2022-10-17 11:34:58 +08:00

138 lines
3.8 KiB
ObjectPascal
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
unit uDefaultIdGenerator;
interface
uses
uIIdGenerator, uISnowWorker, uIdGeneratorOptions, System.DateUtils, System.SysUtils;
type
TDefaultIdGenerator = class(TInterfacedObject, IIdGenerator)
private
SnowWorker: ISnowWorker;
public
constructor Create(options: TIdGeneratorOptions); overload;
function NewLong(): Int64;
end;
implementation
uses
uSnowWorkerM1, uSnowWorkerM2, uSnowWorkerM3;
{ TDefaultIdGenerator }
function GetMillisecondTimeStamp(ET: TDateTime): Int64;
var
ST: TDateTime;
begin
ST := EncodeDateTime(1970, 1, 1, 0, 0, 0, 0);
Result := MilliSecondsBetween(ET, ST) - 28800000; // 8*60*60*1000;
end;
constructor TDefaultIdGenerator.Create(options: TIdGeneratorOptions);
var
MaxLength, MaxWorkerIdNumber, MaxDataCenterIdNumber, MaxSeqNumber: Integer;
begin
if (options = nil) then
begin
raise Exception.Create('options error.');
end;
// 1.BaseTime
if (options.BaseTime < GetMillisecondTimeStamp(IncYear(Now(), -50))) or
(options.BaseTime > GetMillisecondTimeStamp(Now())) then
begin
raise Exception.Create('BaseTime error.');
end;
// 2.WorkerIdBitLength
if (options.TimestampType = 0) then
MaxLength := 22
else
MaxLength := 31; // 秒级时间戳时放大到31位
if (options.WorkerIdBitLength <= 0) then
begin
raise Exception.Create('WorkerIdBitLength error.(range:[1, 21])');
end;
if (options.DataCenterIdBitLength + options.WorkerIdBitLength + options.SeqBitLength > MaxLength) then
begin
raise Exception.Create('errorDataCenterIdBitLength + WorkerIdBitLength + SeqBitLength <= ' + IntToStr(MaxLength));
end;
// 3.WorkerId
MaxWorkerIdNumber := (1 shl options.WorkerIdBitLength) - 1;
if (MaxWorkerIdNumber = 0) then
begin
MaxWorkerIdNumber := 63;
end;
if ((options.WorkerId < 0) or (options.WorkerId > MaxWorkerIdNumber)) then
begin
raise Exception.Create('WorkerId error. (range:[0, ' + IntToStr(MaxWorkerIdNumber) + ']');
end;
MaxDataCenterIdNumber := (1 shl options.DataCenterIdBitLength) - 1;
if (options.DataCenterId < 0) or (options.DataCenterId > MaxDataCenterIdNumber) then
begin
raise Exception.Create('DataCenterId error. (range:[0, ' + IntToStr(MaxDataCenterIdNumber) + ']');
end;
// 4.SeqBitLength
if ((options.SeqBitLength < 2) or (options.SeqBitLength > 21)) then
begin
raise Exception.Create('SeqBitLength error. (range:[2, 21])');
end;
// 5.MaxSeqNumber
MaxSeqNumber := (1 shl options.SeqBitLength) - 1;
if (MaxSeqNumber = 0) then
begin
MaxSeqNumber := 63;
end;
if ((options.MaxSeqNumber < 0) or (options.MaxSeqNumber > MaxSeqNumber)) then
begin
raise Exception.Create('MaxSeqNumber error. (range:[1, ' + IntToStr(MaxSeqNumber) + ']');
end;
// 6.MinSeqNumber
if ((options.MinSeqNumber < 5) or (options.MinSeqNumber > MaxSeqNumber)) then
begin
raise Exception.Create('MinSeqNumber error. (range:[5, ' + IntToStr(MaxSeqNumber) + ']');
end;
// 7.TopOverCostCount
if ((options.TopOverCostCount < 0) or (options.TopOverCostCount > 10000)) then
begin
raise Exception.Create('TopOverCostCount error. (range:[0, 10000]');
end;
case (options.Method) of
2:
begin
SnowWorker := TSnowWorkerM2.Create(options);
end;
else
begin
if ((options.DataCenterIdBitLength = 0) and (options.TimestampType = 0)) then
begin
SnowWorker := TSnowWorkerM1.Create(options);
end
else
begin
SnowWorker := TSnowWorkerM3.Create(options);
end;
end;
end;
if (options.Method <> 2) then
begin
Sleep(500);
end;
end;
function TDefaultIdGenerator.NewLong(): Int64;
begin
Result := SnowWorker.NextId();
end;
end.