Files
idgenerator/Delphi/source/Core/uSnowWorkerM3.pas
2022-10-17 11:34:58 +08:00

92 lines
2.4 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 uSnowWorkerM3;
interface
uses System.SysUtils, System.DateUtils, uSnowWorkerM1, uIdGeneratorOptions, System.SyncObjs;
/// <summary>
/// 雪花漂移算法支持数据中心ID和秒级时间戳
/// </summary>
type
TSnowWorkerM3 = class(TSnowWorkerM1)
protected
FDataCenterId: Cardinal;
FDataCenterIdBitLength: Byte;
FTimestampType: Byte;
protected
/// <summary>
/// 数据中心ID默认0
/// </summary>
property DataCenterId: Cardinal read FDataCenterId default 0;
/// <summary>
/// 数据中心ID长度默认0
/// </summary>
property DataCenterIdBitLength: Byte read FDataCenterIdBitLength default 0;
/// <summary>
/// 时间戳类型0-毫秒1-秒默认0
/// </summary>
property TimestampType: Byte read FTimestampType default 0;
protected
function CalcId(UseTimeTick: Int64): Int64; override;
function CalcTurnBackId(UseTimeTick: Int64): Int64; override;
function GetCurrentTimeTick(): Int64; override;
public
constructor Create(options: TIdGeneratorOptions); overload;
end;
implementation
{ TSnowWorkerM3 }
constructor TSnowWorkerM3.Create(options: TIdGeneratorOptions);
begin
// 秒级时间戳类型
FTimestampType := options.TimestampType;
// DataCenter相关
FDataCenterId := options.DataCenterId;
FDataCenterIdBitLength := options.DataCenterIdBitLength;
if (FTimestampType = 1) then
begin
FTopOverCostCount := 0;
end;
FTimestampShift := Byte(DataCenterIdBitLength + WorkerIdBitLength + SeqBitLength);
inherited Create(options);
end;
function TSnowWorkerM3.CalcId(UseTimeTick: Int64): Int64;
begin
Result := ((UseTimeTick shl FTimestampShift) + (Int64(DataCenterId) shl DataCenterIdBitLength) +
(Int64(WorkerId) shl SeqBitLength) + Int64(FCurrentSeqNumber));
Inc(FCurrentSeqNumber);
end;
function TSnowWorkerM3.CalcTurnBackId(UseTimeTick: Int64): Int64;
begin
Result := ((UseTimeTick shl FTimestampShift) + (Int64(DataCenterId) shl DataCenterIdBitLength) +
(Int64(WorkerId) shl SeqBitLength) + FTurnBackIndex);
Dec(FTurnBackTimeTick);
end;
function TSnowWorkerM3.GetCurrentTimeTick: Int64;
var
Millis: Int64;
begin
if (TimestampType = 0) then
begin
Millis := GetMillisecondTimeStamp();
Result := Millis - FBaseTime;
end
else
begin
Millis := GetSecondTimeStamp();
Result := Millis - FBaseTime;
end;
end;
end.