18 using System.Runtime.CompilerServices;
19 using System.Runtime.InteropServices;
21 namespace SiliconStudio.Core.Storage
23 [StructLayout(LayoutKind.Sequential, Pack = 4)]
26 private readonly uint seed;
27 const uint C1 = 0x239b961b;
28 const uint C2 = 0xab0e9789;
29 const uint C3 = 0x38b34ae5;
30 const uint C4 = 0xa1e38b93;
37 H1 = H2 = H3 = H4 = seed;
46 public uint Seed {
get {
return seed; } }
54 private uint currentBlock1;
55 private uint currentBlock2;
56 private uint currentBlock3;
57 private uint currentBlock4;
62 H1 = H2 = H3 = H4 = Seed;
70 [MethodImpl(MethodImplOptions.AggressiveInlining)]
74 uint k1 = 0, k2 = 0, k3 = 0, k4 = 0;
76 var remainder = Length % 16;
78 fixed (uint* currentBlockStart = ¤tBlock1)
80 var tail = (byte*)currentBlockStart;
85 case 15: k4 ^= (uint)tail[14] << 16;
goto case 14;
86 case 14: k4 ^= (uint)tail[13] << 8;
goto case 13;
87 case 13: k4 ^= (uint)tail[12] << 0;
goto case 12;
88 case 12: k3 ^= (uint)tail[11] << 24;
goto case 11;
89 case 11: k3 ^= (uint)tail[10] << 16;
goto case 10;
90 case 10: k3 ^= (uint)tail[9] << 8;
goto case 9;
91 case 9: k3 ^= (uint)tail[8] << 0;
goto case 8;
92 case 8: k2 ^= (uint)tail[7] << 24;
goto case 7;
93 case 7: k2 ^= (uint)tail[6] << 16;
goto case 6;
94 case 6: k2 ^= (uint)tail[5] << 8;
goto case 5;
95 case 5: k2 ^= (uint)tail[4] << 0;
goto case 4;
96 case 4: k1 ^= (uint)tail[3] << 24;
goto case 3;
97 case 3: k1 ^= (uint)tail[2] << 16;
goto case 2;
98 case 2: k1 ^= (uint)tail[1] << 8;
goto case 1;
99 case 1: k1 ^= (uint)tail[0] << 0;
break;
103 var h4 = H4 ^ RotateLeft((k4 * C4), 18) * C1;
104 var h3 = H3 ^ RotateLeft((k3 * C3), 17) * C4;
105 var h2 = H2 ^ RotateLeft((k2 * C2), 16) * C3;
106 var h1 = H1 ^ RotateLeft((k1 * C1), 15) * C2;
108 uint len = (uint)Length;
110 h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
112 h1 += (h2 + h3 + h4);
113 h2 += h1; h3 += h1; h4 += h1;
120 h1 += (h2 + h3 + h4);
121 h2 += h1; h3 += h1; h4 += h1;
125 var h = (uint*)&result;
140 fixed (uint* currentBlockStart = ¤tBlock1)
142 var currentBlock = (byte*)currentBlockStart;
144 var position = Length++ % 16;
146 currentBlock[position] = value;
150 BodyCore(currentBlock);
165 fixed (byte* bufferStart = buffer)
167 Write(bufferStart + offset, count);
178 public void Write(byte* buffer,
int length)
180 if (buffer == null)
throw new ArgumentNullException(
"buffer");
182 fixed (uint* currentBlockStart = ¤tBlock1)
184 var currentBlock = (byte*)currentBlockStart;
186 var position = Length % 16;
193 var remainder = 16 - position;
195 var partialLength = length;
196 if (partialLength > remainder)
197 partialLength = remainder;
199 Utilities.CopyMemory((IntPtr)currentBlock + position, (IntPtr)buffer, partialLength);
200 buffer += partialLength;
201 length -= partialLength;
203 if (partialLength == remainder)
205 BodyCore(currentBlock);
211 int blocks = length / 16;
212 length -= blocks * 16;
224 Utilities.CopyMemory((IntPtr)currentBlock, (IntPtr)buffer, length);
230 [MethodImpl(MethodImplOptions.AggressiveInlining)]
231 private void BodyCore(byte* data)
233 uint*
b = (uint*)data;
236 H1 ^= RotateLeft((*b++ * C1), 15) * C2;
237 H1 = (RotateLeft(H1, 19) + H2) * 5 + 0x561ccd1b;
240 H2 ^= RotateLeft((*b++ * C2), 16) * C3;
241 H2 = (RotateLeft(H2, 17) + H3) * 5 + 0x0bcaa747;
244 H3 ^= RotateLeft((*b++ * C3), 17) * C4;
245 H3 = (RotateLeft(H3, 15) + H4) * 5 + 0x96cd1c35;
248 H4 ^= RotateLeft((*b++ * C4), 18) * C1;
249 H4 = (RotateLeft(H4, 13) + H1) * 5 + 0x32ac3b17;
252 [MethodImpl(MethodImplOptions.AggressiveInlining)]
253 private static uint RotateLeft(uint x, byte r)
255 return (x << r) | (x >> (32 - r));
258 [MethodImpl(MethodImplOptions.AggressiveInlining)]
259 private static uint FMix(uint h)
262 h = (h ^ (h >> 16)) * 0x85ebca6b;
263 h = (h ^ (h >> 13)) * 0xc2b2ae35;
264 return h ^ (h >> 16);
ObjectId ComputeHash()
Gets the current calculated hash.
void Write(byte[] buffer, int offset, int count)
Writes a buffer of byte to this builder.
void WriteByte(byte value)
Writes a byte to the builder.
A hash to uniquely identify data.
void Write(byte *buffer, int length)
Writes a buffer of byte to this builder.