public static int GetHashCodeEx(this byte[] buffer) { const int CONSTANT = 17; int hashCode = 37; CommonArray common = new CommonArray(); common.ByteArray = buffer; int[] array = common.Int32Array; int length = buffer.Length; int remainder = length & 3; int len = length >> 2; int i = 0; while (i < len) { hashCode = CONSTANT * hashCode + array[i]; i++; } if (remainder > 0) { int shift = sizeof(uint) - remainder; hashCode = CONSTANT * hashCode + ((array[i] << shift) >> shift); } return hashCode; }
/// <summary> /// http://en.wikipedia.org/wiki/MurmurHash /// </summary> /// <param name="buffer"></param> /// <param name="seed"></param> /// <returns></returns> public static int MurMurHash3(this byte[] buffer, int seed = 37) { const uint c1 = 0xcc9e2d51; const uint c2 = 0x1b873593; const int r1 = 15; const int r2 = 13; const uint m = 5; const uint n = 0xe6546b64; uint hash = (uint)seed; CommonArray common = new CommonArray(); common.ByteArray = buffer; uint[] array = common.UInt32Array; int length = buffer.Length; int remainder = length & 3; int len = length >> 2; int i = 0; while (i < len) { uint k = array[i]; k *= c1; k = (k << r1) | (k >> (32 - r1)); //k = rotl32(k, r1); k *= c2; hash ^= k; hash = (hash << r2) | (hash >> (32 - r2)); //hash = rotl32(hash, r2); hash = hash * m + n; i++; } if (remainder > 0) { int shift = sizeof(uint) - remainder; uint k = (array[i] << shift) >> shift; k *= c1; k = (k << r1) | (k >> (32 - r1)); //k = rotl32(k, r1); k *= c2; hash ^= k; } hash ^= (uint)length; //hash = fmix(hash); hash ^= hash >> 16; hash *= 0x85ebca6b; hash ^= hash >> 13; hash *= 0xc2b2ae35; hash ^= hash >> 16; return (int)hash; }
public int Compare(byte[] x, byte[] y, int length) { CommonArray common = new CommonArray(); common.ByteArray = x; ulong[] array1 = common.UInt64Array; common.ByteArray = y; ulong[] array2 = common.UInt64Array; int len = length >> 3; int remainder = length & 7; int i = len; if (remainder > 0) { int shift = sizeof(ulong) - remainder; var v1 = (array1[i] << shift) >> shift; var v2 = (array2[i] << shift) >> shift; if (v1 < v2) { return(-1); } if (v1 > v2) { return(1); } } i--; while (i >= 0) { var v1 = array1[i]; var v2 = array2[i]; if (v1 < v2) { return(-1); } if (v1 > v2) { return(1); } i--; } return(0); }
public int Compare(byte[] x, byte[] y, int length) { CommonArray common = new CommonArray(); common.ByteArray = x; ulong[] array1 = common.UInt64Array; common.ByteArray = y; ulong[] array2 = common.UInt64Array; int len = length >> 3; for (int i = 0; i < len; i++) { var v1 = array1[i]; var v2 = array2[i]; if (v1 != v2) { for (int j = i << 3; ; j++) { byte b1 = x[j]; byte b2 = y[j]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } } } } int index = len << 3; switch (length & 7) { case 7: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 6; } case 6: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 5; } case 5: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 4; } case 4: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 3; } case 3: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 2; } case 2: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } index++; goto case 1; } case 1: { var b1 = x[index]; var b2 = y[index]; if (b1 < b2) { return(-1); } if (b1 > b2) { return(1); } break; } } return(0); }
public bool Equals(byte[] x, byte[] y) { if (x.Length != y.Length) { return(false); } CommonArray common = new CommonArray(); common.ByteArray = x; ulong[] array1 = common.UInt64Array; common.ByteArray = y; ulong[] array2 = common.UInt64Array; int length = x.Length; int len = length >> 3; int remainder = length & 7; int i = len; if (remainder > 0) { int shift = sizeof(ulong) - remainder; if ((array1[i] << shift) >> shift != (array2[i] << shift) >> shift) { return(false); } } i--; while (i >= 7) { if (array1[i] != array2[i] || array1[i - 1] != array2[i - 1] || array1[i - 2] != array2[i - 2] || array1[i - 3] != array2[i - 3] || array1[i - 4] != array2[i - 4] || array1[i - 5] != array2[i - 5] || array1[i - 6] != array2[i - 6] || array1[i - 7] != array2[i - 7]) { return(false); } i -= 8; } if (i >= 3) { if (array1[i] != array2[i] || array1[i - 1] != array2[i - 1] || array1[i - 2] != array2[i - 2] || array1[i - 3] != array2[i - 3]) { return(false); } i -= 4; } if (i >= 1) { if (array1[i] != array2[i] || array1[i - 1] != array2[i - 1]) { return(false); } i -= 2; } if (i >= 0) { if (array1[i] != array2[i]) { return(false); } //i -= 1; } return(true); }
public bool Equals(byte[] x, byte[] y) { if (x.Length != y.Length) { return(false); } CommonArray common = new CommonArray(); common.ByteArray = x; ulong[] array1 = common.UInt64Array; common.ByteArray = y; ulong[] array2 = common.UInt64Array; int length = x.Length; int remainder = length & 7; int len = length >> 3; int i = 0; while (i + 7 < len) { if (array1[i] != array2[i] || array1[i + 1] != array2[i + 1] || array1[i + 2] != array2[i + 2] || array1[i + 3] != array2[i + 3] || array1[i + 4] != array2[i + 4] || array1[i + 5] != array2[i + 5] || array1[i + 6] != array2[i + 6] || array1[i + 7] != array2[i + 7]) { return(false); } i += 8; } if (i + 3 < len) { if (array1[i] != array2[i] || array1[i + 1] != array2[i + 1] || array1[i + 2] != array2[i + 2] || array1[i + 3] != array2[i + 3]) { return(false); } i += 4; } if (i + 1 < len) { if (array1[i] != array2[i] || array1[i + 1] != array2[i + 1]) { return(false); } i += 2; } if (i < len) { if (array1[i] != array2[i]) { return(false); } i += 1; } if (remainder > 0) { int shift = sizeof(ulong) - remainder; if ((array1[i] << shift) >> shift != (array2[i] << shift) >> shift) { return(false); } } return(true); }
public static void Compress(BinaryWriter writer, long[] values, int index, int count, Helper helper) { writer.Write(VERSION); if (count == 0) return; long value = values[index]; CountCompression.Serialize(writer, (ulong)value); if (count == 1) return; Debug.Assert(count == helper.Count); if (!helper.IsReady) helper.Prepare(); index++; count--; int maxIndex = index + count - 1; helper.Serialize(writer); if (helper.Type == HelperType.Raw) { while (index <= maxIndex) writer.Write(values[index++]); return; } if (helper.Type == HelperType.OneStep) return; ulong maxDelta = helper.Delta; bool alwaysUseDelta = helper.AlwaysUseDelta; int bitCount = BitUtils.GetBitBounds(maxDelta); bool writeSign = helper.Type == HelperType.Delta; CommonArray common = new CommonArray(); int sizeBits = helper.SizeBits > 0 ? helper.SizeBits : (1 + 1 + 64) * (count - 1); common.ByteArray = new byte[(int)Math.Ceiling(sizeBits / 8.0)]; ulong[] data = common.UInt64Array; int bitIndex = 0; ulong delta; bool sign; //false - positive, true - negative for (; index <= maxIndex; index++) { long newValue = values[index]; if (newValue >= value) { sign = false; delta = (ulong)(newValue - value); } else { sign = true; delta = (ulong)(value - newValue); } if (alwaysUseDelta || delta <= maxDelta) { if (!alwaysUseDelta) { SetFlag(data, bitIndex/*, true*/); //use delta bitIndex++; } if (writeSign) { if (sign) SetFlag(data, bitIndex/*, sign*/); bitIndex++; } SetBits(data, bitIndex, delta, bitCount); bitIndex += bitCount; } else { //SetFlag(data, bitIndex, false); //don't use delta bitIndex++; SetValue(data, bitIndex, (ulong)newValue); bitIndex += 64; } value = newValue; } int bytesCount = (int)Math.Ceiling(bitIndex / 8.0); CountCompression.Serialize(writer, (ulong)bytesCount); writer.Write(common.ByteArray, 0, bytesCount); }
public static void Decompress(BinaryReader reader, Action<int, long> values, int count) { if (reader.ReadByte() != VERSION) throw new Exception("Invalid delta compression version."); if (count == 0) return; int index = 0; long value = (long)CountCompression.Deserialize(reader); values(index,value); if (count == 1) return; var helper = Helper.Deserialize(reader); index++; count--; int maxIndex = index + count - 1; if (helper.Type == HelperType.Raw) { while (index <= maxIndex) values(index++, reader.ReadInt64()); return; } if (helper.Type == HelperType.OneStep) { long step = (long)helper.Delta; if (helper.Sign == false) while (index <= maxIndex) values(index++, (value += step)); else while (index <= maxIndex) values(index++, (value -= step)); return; } bool readSign = helper.Type == HelperType.Delta; ulong maxDelta = helper.Delta; bool alwaysUseDelta = helper.AlwaysUseDelta; bool sign = helper.Sign; int bitCount = helper.DeltaBits; CommonArray common = new CommonArray(); int bytesCount = (int)CountCompression.Deserialize(reader); common.ByteArray = reader.ReadBytes(bytesCount); ulong[] data = common.UInt64Array; int bitIndex = 0; for (; index <= maxIndex; index++) { long newValue; bool useDelta = alwaysUseDelta || GetFlag(data, bitIndex++); if (useDelta) { if (readSign) { sign = GetFlag(data, bitIndex); bitIndex++; } long delta = (long)GetBits(data, bitIndex, bitCount); bitIndex += bitCount; newValue = sign ? value - delta : value + delta; } else { newValue = (long)GetValue(data, bitIndex); bitIndex += 64; } values(index, newValue); value = newValue; } }