Skip to content

Commit

Permalink
Update UUID.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Taiizor committed Dec 29, 2024
1 parent f6246f0 commit 2eb24e9
Showing 1 changed file with 26 additions and 15 deletions.
41 changes: 26 additions & 15 deletions src/UUID/Constructor/UUID.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ public readonly partial struct UUID(ulong timestamp, ulong random) : IEquatable<
/// </summary>
internal readonly ulong _timestamp = timestamp;

/// <summary>
/// Lock object for thread-safe counter operations.
/// Ensures monotonic ordering of UUIDs generated within the same millisecond.
/// </summary>
private static readonly object _counterLock = new();

/// <summary>
/// Characters used in Base32 encoding.
/// </summary>
Expand Down Expand Up @@ -229,24 +223,41 @@ public ushort GetMonotonicCounter()
/// <returns>A 12-bit counter value that ensures monotonic ordering</returns>
/// <remarks>
/// This method ensures that UUIDs generated within the same millisecond
/// maintain a strict ordering through the use of a 12-bit counter.
/// maintain a strict ordering through the use of a 12-bit counter and Interlocked operations.
/// The counter resets when moving to a new millisecond.
/// If the counter overflows (reaches 4095), the method will wait for the next millisecond.
/// Thread safety is achieved using atomic operations instead of locks.
/// </remarks>
private static int GetMonotonicCounter(long timestamp)
{
lock (_counterLock)
while (true)
{
if (timestamp > _lastTimestamp)
long lastTimestamp = Interlocked.Read(ref _lastTimestamp);

if (timestamp > lastTimestamp)
{
_counter = 0;
_lastTimestamp = timestamp;
if (Interlocked.CompareExchange(ref _lastTimestamp, timestamp, lastTimestamp) == lastTimestamp)
{
Interlocked.Exchange(ref _counter, 0);

return 0;
}
}
else if (timestamp == _lastTimestamp)
else if (timestamp == lastTimestamp)
{
_counter = (_counter + 1) & 0xFFF; // 12-bit counter
int currentCounter = Interlocked.Increment(ref _counter) & 0xFFF; // 12-bit counter

if (currentCounter != 0)
{
return currentCounter;
}

Thread.Sleep(0);
}
else
{
return Interlocked.Add(ref _counter, 0) & 0xFFF;
}

return _counter;
}
}

Expand Down

0 comments on commit 2eb24e9

Please sign in to comment.