Created
June 16, 2024 01:42
-
-
Save yaakov-h/39a5d93e40c0e01b5f074be75032b545 to your computer and use it in GitHub Desktop.
faster version of https://gist.github.com/vcsjones/7e893b22555331d86698148d39b40235
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics.CodeAnalysis; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
using System.Security.Cryptography; | |
public readonly struct UUIDv7 { | |
private readonly InteriorStruct _interior; | |
public UUIDv7() { | |
InteriorStruct.Fill(ref _interior); | |
} | |
public byte[] GetBytes() => _interior.AsReadOnlySpan().ToArray(); | |
public void CopyTo(Span<byte> destination) => _interior.AsReadOnlySpan().CopyTo(destination); | |
public override string ToString() => Convert.ToHexString(_interior.AsReadOnlySpan()); | |
public readonly override int GetHashCode() { | |
HashCode hc = new(); | |
hc.AddBytes(_interior.AsReadOnlySpan()); | |
return hc.ToHashCode(); | |
} | |
[InlineArray(SIZE)] | |
private struct InteriorStruct { | |
private const int SIZE = 16; | |
private byte _element; | |
public static void Fill(ref InteriorStruct uuid) { | |
Span<byte> value = MemoryMarshal.CreateSpan(ref uuid._element, SIZE); | |
RandomNumberGenerator.Fill(value[6..]); | |
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); | |
var timestampBytes = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref timestamp, length: 1)); | |
timestampBytes[..6].CopyTo(value[..6]); | |
value[..6].Reverse(); | |
// version and variant | |
value[6] = (byte)((value[6] & 0x0F) | 0x70); | |
value[8] = (byte)((value[8] & 0x3F) | 0x80); | |
} | |
[UnscopedRef] | |
internal ReadOnlySpan<byte> AsReadOnlySpan() => MemoryMarshal.CreateReadOnlySpan(ref _element, SIZE); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A slightly faster
Fill
(I think):