代码拉取完成,页面将自动刷新
同步操作将从 星大派/Spw.Snowflake 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
using System;
namespace Spw.Snowflake
{
public class SnowFlakeCore
{
private static readonly DateTime MIN_DATETIME_UTC = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
/// <summary>
/// 序列号占用位数
/// </summary>
private const int SEQUENCE_BIT = 12;
/// <summary>
/// 机器标识占用位数
/// </summary>
private const int MACHINE_BIT = 5;
/// <summary>
/// 数据中心占用位数
/// </summary>
private const int DATA_CENTER_BIT = 5;
/// <summary>
/// 序列号最大值
/// </summary>
private const long MAX_SEQUENCE = -1 ^ (-1 << SEQUENCE_BIT);
/// <summary>
/// 最大机器标识
/// </summary>
private const long MAX_MACHINE = -1 ^ (-1 << MACHINE_BIT);
/// <summary>
/// 最大数据中心标识
/// </summary>
private const long MAX_DATA_CENTER = -1 ^ (-1 << DATA_CENTER_BIT);
/// <summary>
/// 序列号左移位数
/// </summary>
private const int SEQUENCE_LEFT_OFFSET = 0;
/// <summary>
/// 机器标识左移位数
/// </summary>
private const int MACHINE_LEFT_OFFSET = SEQUENCE_BIT;
/// <summary>
/// 数据中心左移标识
/// </summary>
private const int DATA_CENTER_LEFT_OFFSET = MACHINE_LEFT_OFFSET + MACHINE_BIT;
/// <summary>
/// 时间戳左移标识
/// </summary>
private const int TIMESTAMP_LEFT_OFFSET = DATA_CENTER_LEFT_OFFSET + DATA_CENTER_BIT;
/// <summary>
/// 起始时间戳
/// </summary>
private readonly long START_TIMESTAMP = 0;
/// <summary>
/// 当前数据中心标识
/// </summary>
private long _dataCenterId;
/// <summary>
/// 当前机器标识
/// </summary>
private long _machineId;
/// <summary>
/// 当前序列号
/// </summary>
private long _sequence;
/// <summary>
/// 最后时间戳
/// </summary>
private long _lastTimestamp = -1;
/// <summary>
/// id生成器锁
/// </summary>
private readonly object _mutex = new object();
/// <summary>
///
/// </summary>
/// <param name="startTimeStamp">起始时间戳</param>
/// <param name="dataCenterId">数据中心标识</param>
/// <param name="machineId">机器标识</param>
public SnowFlakeCore(long startTimeStamp, long dataCenterId, long machineId)
{
if (START_TIMESTAMP < 0)
throw new ArgumentOutOfRangeException($"{nameof(startTimeStamp)} must not less than zore");
if (dataCenterId > MAX_DATA_CENTER || dataCenterId < 0)
throw new ArgumentOutOfRangeException($"{nameof(dataCenterId)} must between 0 and {MAX_DATA_CENTER}");
if (machineId > MAX_MACHINE || machineId < 0)
throw new ArgumentOutOfRangeException($"{nameof(machineId)} must between 0 and {MAX_MACHINE}");
START_TIMESTAMP = startTimeStamp;
_dataCenterId = dataCenterId;
_machineId = machineId;
}
/// <summary>
/// 获取时间戳
/// </summary>
/// <returns></returns>
public static long GetUtcTimestamp() => Convert.ToInt64((DateTime.UtcNow - MIN_DATETIME_UTC).TotalMilliseconds);
/// <summary>
/// 获取下一个时间戳
/// </summary>
/// <returns></returns>
private long GetNextTimestamp()
{
var timestamp = GetUtcTimestamp();
for (; timestamp <= _lastTimestamp;)
{
timestamp = GetUtcTimestamp();
}
return timestamp;
}
/// <summary>
/// 生成id
/// </summary>
/// <returns></returns>
public long GenerateId()
{
lock (_mutex)
{
var timestamp = GetUtcTimestamp();
// 时钟被拨回
if (timestamp < _lastTimestamp)
throw new Exception($"Clock moved backwards, refusing to generate id!");
// 相同时间戳,增长序列号
if (timestamp == _lastTimestamp)
{
_sequence = (_sequence + 1) & MAX_SEQUENCE;
if (_sequence == 0)
timestamp = GetNextTimestamp();
}
// 不同时间戳,序列号归零
else
_sequence = 0;
_lastTimestamp = timestamp;
return
(_lastTimestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_OFFSET |
_dataCenterId << DATA_CENTER_LEFT_OFFSET |
_machineId << MACHINE_LEFT_OFFSET |
_sequence;
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。