|
1 | 1 | using System; |
| 2 | +using System.Diagnostics; |
2 | 3 | using NHibernate.Engine; |
3 | 4 |
|
4 | 5 | namespace NHibernate.Id |
@@ -36,34 +37,32 @@ public partial class GuidCombGenerator : IIdentifierGenerator |
36 | 37 | /// <returns>The new identifier as a <see cref="Guid"/>.</returns> |
37 | 38 | public object Generate(ISessionImplementor session, object obj) |
38 | 39 | { |
39 | | - return GenerateComb(); |
| 40 | + return GenerateComb(Guid.NewGuid(), DateTime.UtcNow); |
40 | 41 | } |
41 | 42 |
|
42 | 43 | /// <summary> |
43 | 44 | /// Generate a new <see cref="Guid"/> using the comb algorithm. |
44 | 45 | /// </summary> |
45 | | - private Guid GenerateComb() |
| 46 | + protected static Guid GenerateComb(Guid guid, DateTime utcNow) |
46 | 47 | { |
47 | | - byte[] guidArray = Guid.NewGuid().ToByteArray(); |
48 | | - |
49 | | - DateTime now = DateTime.UtcNow; |
50 | | - |
| 48 | +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER |
| 49 | + Span<byte> guidArray = stackalloc byte[16]; |
| 50 | + guid.TryWriteBytes(guidArray); |
| 51 | +#else |
| 52 | + var guidArray = guid.ToByteArray(); |
| 53 | +#endif |
51 | 54 | // Get the days and milliseconds which will be used to build the byte string |
52 | | - TimeSpan days = new TimeSpan(now.Ticks - BaseDateTicks); |
53 | | - TimeSpan msecs = now.TimeOfDay; |
54 | | - |
55 | | - // Convert to a byte array |
| 55 | + var ts = new TimeSpan(utcNow.Ticks - BaseDateTicks); |
| 56 | + var days = ts.Days; |
| 57 | + guidArray[10] = (byte) (days >> 8); |
| 58 | + guidArray[11] = (byte) days; |
| 59 | + |
56 | 60 | // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 |
57 | | - byte[] daysArray = BitConverter.GetBytes(days.Days); |
58 | | - byte[] msecsArray = BitConverter.GetBytes((long) (msecs.TotalMilliseconds / 3.333333)); |
59 | | - |
60 | | - // Reverse the bytes to match SQL Servers ordering |
61 | | - Array.Reverse(daysArray); |
62 | | - Array.Reverse(msecsArray); |
63 | | - |
64 | | - // Copy the bytes into the guid |
65 | | - Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2); |
66 | | - Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4); |
| 61 | + var msecs = (long) (utcNow.TimeOfDay.TotalMilliseconds / 3.333333); |
| 62 | + guidArray[12] = (byte) (msecs >> 24); |
| 63 | + guidArray[13] = (byte) (msecs >> 16); |
| 64 | + guidArray[14] = (byte) (msecs >> 8); |
| 65 | + guidArray[15] = (byte) msecs; |
67 | 66 |
|
68 | 67 | return new Guid(guidArray); |
69 | 68 | } |
|
0 commit comments