Skip to content

Instantly share code, notes, and snippets.

@myl7
Created October 17, 2021 05:13
Show Gist options
  • Save myl7/3d5066df4800c557f8354b3b05927d85 to your computer and use it in GitHub Desktop.
Save myl7/3d5066df4800c557f8354b3b05927d85 to your computer and use it in GitHub Desktop.
snow flake, distributed (basicly) time-sortable ID generator in C#. Sleeps to avoid seq exhaustion and time reversal.
using System;
using System.Threading;
namespace Myl7Snowflake
{
public class Snowflake
{
private readonly ushort _machineId;
public Snowflake(ushort machineId)
{
_machineId = (ushort)(machineId & 0x3ff);
}
private readonly Mutex _mutex = new Mutex();
private long _pre = DateTimeOffset.Now.ToUnixTimeMilliseconds();
private ushort _seq;
public long Next()
{
_mutex.WaitOne();
var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
if (_pre < now)
{
_pre = now;
_seq = 0;
}
else
{
_seq = (ushort)((_seq + 1) & 0xfff);
if (_seq == 0)
{
_pre++;
if (now < _pre)
{
Thread.Sleep((int)(_pre - now));
}
}
}
var res = Gen();
_mutex.ReleaseMutex();
return res;
}
private long Gen()
{
var h = ((ulong)_pre & 0x1ffffffffff) << 22;
var m = (ulong)_machineId << 12;
var l = (ulong)_seq & 0xfff;
return (long)(h | m | l);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment