diff --git a/BeefLibs/corlib/src/Collections/Dictionary.bf b/BeefLibs/corlib/src/Collections/Dictionary.bf index d308fcb4..d5d4f516 100644 --- a/BeefLibs/corlib/src/Collections/Dictionary.bf +++ b/BeefLibs/corlib/src/Collections/Dictionary.bf @@ -26,7 +26,7 @@ namespace System.Collections { public TKey mKey; // Key of entry public TValue mValue; // Value of entry - public int32 mHashCode; // Lower 31 bits of hash code, -1 if unused + public int_cosize mHashCode; // some bits of hash code, -1 if unused public int_cosize mNext; // Index of next entry, -1 if last } @@ -34,7 +34,7 @@ namespace System.Collections Entry* mEntries; int_cosize mAllocSize; int_cosize mCount; - int_cosize mFreeList; + int_cosize mFreeList; int_cosize mFreeCount; #if VERSION_DICTIONARY private int32 mVersion; @@ -294,12 +294,21 @@ namespace System.Collections return Enumerator(this, Enumerator.[Friend]KeyValuePair); } + static int_cosize GetKeyHash(int hashCode) + { + if (sizeof(int) == 4) + return (int32)hashCode & 0x7FFFFFFF; + if (sizeof(int_cosize) == 8) + return (int_cosize)(hashCode & 0x7FFFFFFF'FFFFFFFFL); + return ((int32)hashCode ^ (int32)(hashCode >> 33)) & 0x7FFFFFFF; + } + [DisableObjectAccessChecks] private int FindEntry(TKey key) { if (mBuckets != null) { - int hashCode = key.GetHashCode() & 0x7FFFFFFF; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); for (int i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext) { if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) return i; @@ -317,7 +326,7 @@ namespace System.Collections { if (mBuckets != null) { - int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); for (int_cosize i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext) { if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) return i; @@ -338,10 +347,10 @@ namespace System.Collections private void Insert(TKey key, TValue value, bool add) { if (mBuckets == null) Initialize(0); - int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF; - int_cosize targetBucket = hashCode % (int_cosize)mAllocSize; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); + int targetBucket = hashCode % mAllocSize; - for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) + for (int i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) { if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) { @@ -390,7 +399,7 @@ namespace System.Collections private bool Insert(TKey key, bool add, out TKey* keyPtr, out TValue* valuePtr, Entry** outOldData) { if (mBuckets == null) Initialize(0); - int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); int_cosize targetBucket = hashCode % (int_cosize)mAllocSize; for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) { @@ -446,9 +455,9 @@ namespace System.Collections private bool InsertAlt(TAltKey key, bool add, out TKey* keyPtr, out TValue* valuePtr, Entry** outOldData) where TAltKey : IHashable where bool : operator TKey == TAltKey { if (mBuckets == null) Initialize(0); - int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF; - int_cosize targetBucket = hashCode % (int_cosize)mAllocSize; - for (int_cosize i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) + int_cosize hashCode = GetKeyHash(key.GetHashCode()); + int targetBucket = hashCode % (int_cosize)mAllocSize; + for (int i = mBuckets[targetBucket]; i >= 0; i = mEntries[i].mNext) { if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) { @@ -529,7 +538,7 @@ namespace System.Collections { if (newEntries[i].mHashCode != -1) { - newEntries[i].mHashCode = (int32)newEntries[i].mKey.GetHashCode() & 0x7FFFFFFF; + newEntries[i].mHashCode = GetKeyHash(newEntries[i].mKey.GetHashCode()); } } } @@ -560,7 +569,7 @@ namespace System.Collections { if (mBuckets != null) { - int hashCode = key.GetHashCode() & 0x7FFFFFFF; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); int bucket = hashCode % (int_cosize)mAllocSize; int last = -1; for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) @@ -597,7 +606,7 @@ namespace System.Collections { if (mBuckets != null) { - int hashCode = key.GetHashCode() & 0x7FFFFFFF; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); int bucket = hashCode % (int_cosize)mAllocSize; int last = -1; for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) @@ -641,8 +650,8 @@ namespace System.Collections if (mBuckets != null) { - int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF; - int_cosize bucket = hashCode % (int_cosize)mAllocSize; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); + int bucket = hashCode % (int_cosize)mAllocSize; int_cosize last = -1; for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) { @@ -682,8 +691,8 @@ namespace System.Collections if (mBuckets != null) { - int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF; - int_cosize bucket = hashCode % (int_cosize)mAllocSize; + int_cosize hashCode = GetKeyHash(key.GetHashCode()); + int bucket = hashCode % (int_cosize)mAllocSize; int_cosize last = -1; for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) {