diff --git a/src/DryDB/IKeyEncoding.cs b/src/DryDB/IKeyEncoding.cs index d1e8f03..b015e47 100644 --- a/src/DryDB/IKeyEncoding.cs +++ b/src/DryDB/IKeyEncoding.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers.Binary; using System.Collections.Concurrent; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -262,11 +263,21 @@ public int Compare(ReadOnlySpan a, ReadOnlySpan b) /// byte-lexicographic order. Keys sharing an 8-byte prefix collide and fall back /// to the full comparison. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong GetKeyDigest(ReadOnlySpan key) { - var length = Math.Min(key.Length, sizeof(ulong)); + if (key.Length >= sizeof(ulong)) + { + // Read the first 8 bytes as a big-endian number: one unaligned load plus + // one byte-swap instruction (ldr + rev / mov + bswap). + return BinaryPrimitives.ReverseEndianness( + Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(key))); + } + + // Shorter keys only: a whole-ulong load would read past the key, so pack the + // bytes individually (zero padding the low bits). var digest = 0UL; - for (var i = 0; i < length; i++) + for (var i = 0; i < key.Length; i++) { digest |= (ulong)key[i] << (56 - i * 8); }