|
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