public static uint CalculateRaw(string buf, int len, XXHash32Block context, int startFrom = int.MaxValue) { fixed(char *buffer = buf) { return(CalculateInline((byte *)buffer, len * sizeof(char), context, startFrom)); } }
public static uint Calculate(string value, Encoding encoder, XXHash32Block context, int startFrom = int.MaxValue) { var buf = encoder.GetBytes(value); fixed(byte *buffer = buf) { return(CalculateInline(buffer, buf.Length, context, startFrom)); } }
public static uint Calculate(int[] buf, int len, XXHash32Block context, int startFrom = int.MaxValue) { if (len == -1) len = buf.Length; fixed(int *buffer = buf) { return(CalculateInline((byte *)buffer, len * sizeof(int), context, startFrom)); } }
public static unsafe uint CalculateInline(byte *buffer, int len, XXHash32Block context, int startFrom = int.MaxValue) { Contract.Requires(buffer != null); Contract.Requires(context != null); Contract.Requires(len >= 0); Contract.Requires(startFrom < len || startFrom == int.MaxValue); unchecked { uint h32; byte *bEnd = buffer + len; if (len >= 16) { byte *limit = bEnd - 16; int iterations = Math.Min((int)((bEnd - buffer) / (4 * sizeof(uint))), startFrom / (4 * sizeof(uint))); int bucketNumber = Math.Min(iterations, context.Values.Length); // Retrieve the preprocessed context var state = context.Values[bucketNumber]; // Advance the buffer to the position buffer += iterations * 4 * sizeof(uint); while (buffer <= limit) { state.V1 += *((uint *)buffer) * XXHash32Constants.PRIME32_2; buffer += sizeof(uint); state.V2 += *((uint *)buffer) * XXHash32Constants.PRIME32_2; buffer += sizeof(uint); state.V3 += *((uint *)buffer) * XXHash32Constants.PRIME32_2; buffer += sizeof(uint); state.V4 += *((uint *)buffer) * XXHash32Constants.PRIME32_2; buffer += sizeof(uint); state.V1 = Bits.RotateLeft32(state.V1, 13); state.V2 = Bits.RotateLeft32(state.V2, 13); state.V3 = Bits.RotateLeft32(state.V3, 13); state.V4 = Bits.RotateLeft32(state.V4, 13); state.V1 *= XXHash32Constants.PRIME32_1; state.V2 *= XXHash32Constants.PRIME32_1; state.V3 *= XXHash32Constants.PRIME32_1; state.V4 *= XXHash32Constants.PRIME32_1; } h32 = Bits.RotateLeft32(state.V1, 1) + Bits.RotateLeft32(state.V2, 7) + Bits.RotateLeft32(state.V3, 12) + Bits.RotateLeft32(state.V4, 18); } else { h32 = context.Seed + XXHash32Constants.PRIME32_5; } h32 += (uint)len; while (buffer + 4 <= bEnd) { h32 += *((uint *)buffer) * XXHash32Constants.PRIME32_3; h32 = Bits.RotateLeft32(h32, 17) * XXHash32Constants.PRIME32_4; buffer += 4; } while (buffer < bEnd) { h32 += (uint)(*buffer) * XXHash32Constants.PRIME32_5; h32 = Bits.RotateLeft32(h32, 11) * XXHash32Constants.PRIME32_1; buffer++; } h32 ^= h32 >> 15; h32 *= XXHash32Constants.PRIME32_2; h32 ^= h32 >> 13; h32 *= XXHash32Constants.PRIME32_3; h32 ^= h32 >> 16; return(h32); } }
public static unsafe uint Calculate(byte *buffer, int len, XXHash32Block context, int startFrom = int.MaxValue) { return(CalculateInline(buffer, len, context, startFrom)); }