sharp-chat/SharpChatCommon/Snowflake/SnowflakeGenerator.cs
flashwave e17aed7c25
Switched to Index brand random Snowflakes instead of SharpIds.
If you were still handling message ids as integers in an environment that can't handle signed 64-bit integers you're going to be having a fun time after this update!
2025-04-25 20:05:57 +00:00

35 lines
1.4 KiB
C#

namespace SharpChat.Snowflake {
public class SnowflakeGenerator {
public const long MASK = 0x7FFFFFFFFFFFFFFF;
// previous default epoch was 1588377600000, but snowflakes are much larger than SharpIds
public const long EPOCH = 1356998400000;
public const byte SHIFT = 16;
public readonly long Epoch;
public readonly byte Shift;
public readonly long TimestampMask;
public readonly long SequenceMask;
public SnowflakeGenerator(long epoch = EPOCH, byte shift = SHIFT) {
if(epoch is < 0 or > MASK)
throw new ArgumentException("Epoch must be a positive int64.", nameof(epoch));
if(shift is < 1 or > 63)
throw new ArgumentException("Shift must be between or equal to 1 and 63", nameof(shift));
Epoch = epoch;
Shift = shift;
// i think Index only does this as a hack for how integers work in PHP but its gonna run Once per application instance lol
TimestampMask = ~(~0L << (63 - shift));
SequenceMask = ~(~0L << shift);
}
public long Now(DateTimeOffset? at = null) {
return Math.Max(0, (at ?? DateTimeOffset.UtcNow).ToUnixTimeMilliseconds() - Epoch);
}
public long Next(long sequence, DateTimeOffset? at = null) {
return ((Now(at) & TimestampMask) << Shift) | (sequence & SequenceMask);
}
}
}