internal static unsafe int HashCore(int hashFunction, Array array, int elementSize) { int hash; if (array == null || array.Length == 0) { hash = HashHelper.Hash4(hashFunction, 0); } else if (elementSize != 0) // if it's an array of blittable types... { GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); // pin the array so we can get a pointer to the raw bytes try // NOTE: GCHandle is relatively slow... { hash = BinaryUtility.Hash(hashFunction, Marshal.UnsafeAddrOfPinnedArrayElement(array, 0).ToPointer(), array.Length * elementSize); } finally { handle.Free(); } } else { hash = 0; string[] strings = array as string[]; if (strings != null) // we have to special-case the non-blittable types that have custom MultiHashProvider implementations, because { // the generic code below will only use the generic MultiHashProvider. this is string[] and IMultiHashable[] for (int i = 0; i < strings.Length; i++) { hash ^= MultiHashProvider <string> .Default.GetHashCode(hashFunction, strings[i]); } } else { IMultiHashable[] hashables = array as IMultiHashable[]; if (hashables != null) { for (int i = 0; i < hashables.Length; i++) { hash ^= hashables[i].GetHashCode(hashFunction); } } else { for (int i = 0; i < array.Length; i++) { hash ^= MultiHashProvider <object> .Default.GetHashCode(hashFunction, array.GetValue(i)); } } } } return(hash); }
public unsafe override int GetHashCode(int hashFunction, string item) { if (hashFunction == 0) { return(item == null ? 0 : item.GetHashCode()); } else if (string.IsNullOrEmpty(item)) { // use an arbitrary non-zero value for empty strings to differentiate them from null strings, as both are common cases return(HashHelper.Hash4(hashFunction, item == null ? 0 : 0x8E5211CC)); } else { fixed(char *chars = item) return(BinaryUtility.Hash(hashFunction, chars, item.Length * sizeof(char))); } }
public unsafe override int GetHashCode(int hashFunction, byte[] array) { return(BinaryUtility.Hash(hashFunction, array)); }