From bad12d706f01a9575dd17e42de2149150fc3f987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szak=C3=A1ts=20Alp=C3=A1r=20Zsolt?= Date: Thu, 11 Jul 2024 10:43:49 +0200 Subject: [PATCH 1/2] .NET Standard 2.0 compatibility --- src/FlakeId/FlakeId.csproj | 2 +- src/FlakeId/Id.cs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/FlakeId/FlakeId.csproj b/src/FlakeId/FlakeId.csproj index 05a79af..0a33ffe 100644 --- a/src/FlakeId/FlakeId.csproj +++ b/src/FlakeId/FlakeId.csproj @@ -1,7 +1,7 @@ - net8.0;net7.0;net6.0;net5.0;netstandard2.1 + net8.0;netstandard2.1;netstandard2.0 true Discord inspired Twitter like implementation of Snowflake IDs, focused on performance. Snowflakes are 64 bit, highly optimized, decentralized, K-ordered, unique identifiers. https://github.com/aevitas/flakeid diff --git a/src/FlakeId/Id.cs b/src/FlakeId/Id.cs index ede2957..efe0963 100644 --- a/src/FlakeId/Id.cs +++ b/src/FlakeId/Id.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Threading; using FlakeId.Extensions; @@ -142,7 +142,10 @@ private void CreateInternal(long timeStampMs = 0) long milliseconds = timeStampMs == 0 ? MonotonicTimer.ElapsedMilliseconds : timeStampMs; long timestamp = milliseconds & TimestampMask; int threadId = Thread.CurrentThread.ManagedThreadId & ThreadIdMask; - int processId = s_processId ??= Process.GetCurrentProcess().Id & ProcessIdMask; + // int processId = s_processId ??= Process.GetCurrentProcess().Id & ProcessIdMask; + if (s_processId is null) + s_processId = Process.GetCurrentProcess().Id & ProcessIdMask; + int processId = s_processId.Value; Interlocked.Increment(ref s_increment); From 2f57bd71dcf2841c2297d74525d0ab61cb0a6284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szak=C3=A1ts=20Alp=C3=A1r=20Zsolt?= Date: Thu, 11 Jul 2024 16:16:56 +0200 Subject: [PATCH 2/2] Update tests to support .NET Standard 2.0 Small changes in the code to build on lower (7.3) C# versions --- src/FlakeId.Tests/FlakeId.Tests.csproj | 2 +- src/FlakeId.Tests/IdExtensionsTests.cs | 81 +++++++------- src/FlakeId.Tests/IdTests.cs | 143 +++++++++++++------------ src/FlakeId.Tests/ParseTests.cs | 101 ++++++++--------- src/FlakeId/FlakeId.csproj | 2 +- 5 files changed, 166 insertions(+), 163 deletions(-) diff --git a/src/FlakeId.Tests/FlakeId.Tests.csproj b/src/FlakeId.Tests/FlakeId.Tests.csproj index f7f55d4..08ceca8 100644 --- a/src/FlakeId.Tests/FlakeId.Tests.csproj +++ b/src/FlakeId.Tests/FlakeId.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net461;net462;net47;net471;net472;net48;net481; false diff --git a/src/FlakeId.Tests/IdExtensionsTests.cs b/src/FlakeId.Tests/IdExtensionsTests.cs index 0b57df1..c4f3309 100644 --- a/src/FlakeId.Tests/IdExtensionsTests.cs +++ b/src/FlakeId.Tests/IdExtensionsTests.cs @@ -2,47 +2,48 @@ using FlakeId.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace FlakeId.Tests; - -[TestClass] -public class IdExtensionsTests +namespace FlakeId.Tests { - [TestMethod] - public void Id_ToDateTimeOffset() - { - Id id = Id.Create(); - DateTimeOffset timeStamp = id.ToDateTimeOffset(); - DateTimeOffset now = DateTimeOffset.Now; - TimeSpan delta = now - timeStamp; - - Assert.IsTrue(delta.Seconds <= 1); - } - - [TestMethod] - public void Id_ToUnixTimeMilliseconds() - { - Id id = Id.Create(); - long timestamp = id.ToUnixTimeMilliseconds(); - long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - - Assert.IsTrue(now - timestamp < 100); - } - - [TestMethod] - public void Id_IsValid() + [TestClass] + public class IdExtensionsTests { - Id id = Id.Create(); - bool isValid = id.IsSnowflake(); - - Assert.IsTrue(isValid); - } - - [TestMethod] - public void Id_ToStringIdentifier_ProducesValidId() - { - Id id = Id.Create(); - string s = id.ToStringIdentifier(); - - Assert.AreNotEqual(default, s); + [TestMethod] + public void Id_ToDateTimeOffset() + { + Id id = Id.Create(); + DateTimeOffset timeStamp = id.ToDateTimeOffset(); + DateTimeOffset now = DateTimeOffset.Now; + TimeSpan delta = now - timeStamp; + + Assert.IsTrue(delta.Seconds <= 1); + } + + [TestMethod] + public void Id_ToUnixTimeMilliseconds() + { + Id id = Id.Create(); + long timestamp = id.ToUnixTimeMilliseconds(); + long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + + Assert.IsTrue(now - timestamp < 100); + } + + [TestMethod] + public void Id_IsValid() + { + Id id = Id.Create(); + bool isValid = id.IsSnowflake(); + + Assert.IsTrue(isValid); + } + + [TestMethod] + public void Id_ToStringIdentifier_ProducesValidId() + { + Id id = Id.Create(); + string s = id.ToStringIdentifier(); + + Assert.AreNotEqual(default, s); + } } } diff --git a/src/FlakeId.Tests/IdTests.cs b/src/FlakeId.Tests/IdTests.cs index 23a2d60..1559f73 100644 --- a/src/FlakeId.Tests/IdTests.cs +++ b/src/FlakeId.Tests/IdTests.cs @@ -5,98 +5,99 @@ using FlakeId.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace FlakeId.Tests; - -[TestClass] -public class IdTests +namespace FlakeId.Tests { - [TestMethod] - public void Id_Create() - { - Id id = Id.Create(); - - Assert.IsTrue(id > 1); - } - - [TestMethod] - public void Id_CreateFromTimeStamp() + [TestClass] + public class IdTests { - DateTimeOffset now = DateTimeOffset.UtcNow; - long timeStamp = now.ToUnixTimeMilliseconds(); - Id id = Id.Create(timeStamp); + [TestMethod] + public void Id_Create() + { + Id id = Id.Create(); - Assert.AreEqual(timeStamp, id.ToUnixTimeMilliseconds()); - } + Assert.IsTrue(id > 1); + } - [TestMethod] - public void Id_CreateFromTimeStamp_RecentTimeStamp() - { - Assert.ThrowsException( - () => Id.Create(new DateTimeOffset(2010, 1, 1, 0, 0, 0, 0, TimeSpan.Zero).ToUnixTimeMilliseconds())); - } + [TestMethod] + public void Id_CreateFromTimeStamp() + { + DateTimeOffset now = DateTimeOffset.UtcNow; + long timeStamp = now.ToUnixTimeMilliseconds(); + Id id = Id.Create(timeStamp); - [TestMethod] - public void Id_CreateManyFast() - { - Id[] ids = Enumerable.Range(0, 1000).Select(_ => Id.Create()).ToArray(); + Assert.AreEqual(timeStamp, id.ToUnixTimeMilliseconds()); + } - foreach (Id id in ids) + [TestMethod] + public void Id_CreateFromTimeStamp_RecentTimeStamp() { - Assert.IsTrue(ids.Count(i => i == id) == 1); + Assert.ThrowsException( + () => Id.Create(new DateTimeOffset(2010, 1, 1, 0, 0, 0, 0, TimeSpan.Zero).ToUnixTimeMilliseconds())); } - } - - [TestMethod] - public async Task Id_CreateManyDelayed() - { - List ids = []; - for (int i = 0; i < 100; i++) + [TestMethod] + public void Id_CreateManyFast() { - ids.Add(Id.Create()); - await Task.Delay(TimeSpan.FromMilliseconds(5)); + Id[] ids = Enumerable.Range(0, 1000).Select(_ => Id.Create()).ToArray(); + + foreach (Id id in ids) + { + Assert.IsTrue(ids.Count(i => i == id) == 1); + } } - foreach (Id id in ids) + [TestMethod] + public async Task Id_CreateManyDelayed() { - Assert.IsTrue(ids.Count(i => i == id) == 1); + List ids = new List(); + + for (int i = 0; i < 100; i++) + { + ids.Add(Id.Create()); + await Task.Delay(TimeSpan.FromMilliseconds(5)); + } + + foreach (Id id in ids) + { + Assert.IsTrue(ids.Count(i => i == id) == 1); + } } - } - [TestMethod] - public void Id_Equality() - { - // This test should never fail so long as Id is a struct. - Id left = new(5956206959003041793); - Id right = new(5956206959003041793); + [TestMethod] + public void Id_Equality() + { + // This test should never fail so long as Id is a struct. + Id left = new Id(5956206959003041793); + Id right = new Id(5956206959003041793); - Assert.AreEqual(left, right); - } + Assert.AreEqual(left, right); + } - [TestMethod] - public void Id_Sortable() - { - // The sequence in which Ids are generated should be equal to a set of sorted Ids. - Id[] ids = Enumerable.Range(0, 1000).Select(_ => Id.Create()).ToArray(); - Id[] sorted = [.. ids.OrderBy(i => i)]; + [TestMethod] + public void Id_Sortable() + { + // The sequence in which Ids are generated should be equal to a set of sorted Ids. + Id[] ids = Enumerable.Range(0, 1000).Select(_ => Id.Create()).ToArray(); + Id[] sorted = ids.OrderBy(i => i).ToArray(); - Assert.IsTrue(ids.SequenceEqual(sorted)); - } + Assert.IsTrue(ids.SequenceEqual(sorted)); + } - [TestMethod] - public void Id_ToString() - { - long id = Id.Create(); + [TestMethod] + public void Id_ToString() + { + long id = Id.Create(); - Assert.AreEqual(id.ToString(), id.ToString()); - } + Assert.AreEqual(id.ToString(), id.ToString()); + } - [TestMethod] - public void Id_ContainsTimeZoneComponent() - { - DateTimeOffset timeStamp = new(2020, 1, 1, 0, 0, 0, TimeSpan.FromHours(7)); - Id id = Id.Create(timeStamp.ToUnixTimeMilliseconds()); + [TestMethod] + public void Id_ContainsTimeZoneComponent() + { + DateTimeOffset timeStamp = new DateTimeOffset(2020, 1, 1, 0, 0, 0, TimeSpan.FromHours(7)); + Id id = Id.Create(timeStamp.ToUnixTimeMilliseconds()); - Assert.AreEqual(timeStamp.ToUnixTimeMilliseconds(), id.ToUnixTimeMilliseconds()); + Assert.AreEqual(timeStamp.ToUnixTimeMilliseconds(), id.ToUnixTimeMilliseconds()); + } } } diff --git a/src/FlakeId.Tests/ParseTests.cs b/src/FlakeId.Tests/ParseTests.cs index 1472cfe..6de8f66 100644 --- a/src/FlakeId.Tests/ParseTests.cs +++ b/src/FlakeId.Tests/ParseTests.cs @@ -4,73 +4,74 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace FlakeId.Tests; - -[TestClass] -public class ParseTests +namespace FlakeId.Tests { - - - [TestMethod] - public void Id_Parse_Invalid() + [TestClass] + public class ParseTests { - const long value = 10; - Assert.ThrowsException(() => Id.Parse(value)); - } - [TestMethod] - public void Id_Parse() - { - long id = Id.Create(); + [TestMethod] + public void Id_Parse_Invalid() + { + const long value = 10; - Id.Parse(id); - } + Assert.ThrowsException(() => Id.Parse(value)); + } - [TestMethod] - public void Id_TryParse_Invalid() - { - const long value = 10; + [TestMethod] + public void Id_Parse() + { + long id = Id.Create(); - bool parse = Id.TryParse(value, out _); + Id.Parse(id); + } - Assert.IsFalse(parse); - } + [TestMethod] + public void Id_TryParse_Invalid() + { + const long value = 10; - [TestMethod] - public void Id_TryParse() - { - long id = Id.Create(); + bool parse = Id.TryParse(value, out _); - bool parse = Id.TryParse(id, out Id parsed); + Assert.IsFalse(parse); + } - Assert.IsTrue(parse); - Assert.AreEqual(id, parsed); - } + [TestMethod] + public void Id_TryParse() + { + long id = Id.Create(); - [TestMethod] - public void Id_TryParse_Many() - { - List ids = Enumerable.Range(0, 100_000).Select(_ => Id.Create()).ToList(); - List problematic = new(); + bool parse = Id.TryParse(id, out Id parsed); - bool failed = false; - foreach (var id in ids) + Assert.IsTrue(parse); + Assert.AreEqual(id, parsed); + } + + [TestMethod] + public void Id_TryParse_Many() { - if (!Id.TryParse(id, out Id parsed)) + List ids = Enumerable.Range(0, 100_000).Select(_ => Id.Create()).ToList(); + List problematic = new List(); + + bool failed = false; + foreach (var id in ids) { - Debug.WriteLine(id); - problematic.Add(id); - failed = true; + if (!Id.TryParse(id, out Id parsed)) + { + Debug.WriteLine(id); + problematic.Add(id); + failed = true; + } } - } - Assert.IsFalse(failed); - } + Assert.IsFalse(failed); + } - [TestMethod] - public void Id_TryParse_Problematic() - { - Id id = Id.Parse(1108047973760811023); + [TestMethod] + public void Id_TryParse_Problematic() + { + Id id = Id.Parse(1108047973760811023); + } } } diff --git a/src/FlakeId/FlakeId.csproj b/src/FlakeId/FlakeId.csproj index 0a33ffe..4de8148 100644 --- a/src/FlakeId/FlakeId.csproj +++ b/src/FlakeId/FlakeId.csproj @@ -8,7 +8,7 @@ snowflake, discord, discord id, unique id, uuid, flake, flake id aevitas false - 1.1.2 + 1.1.3 FlakeId FlakeId snowflake-96.png