From 82a108714ddc4a49c1f8876353eb4b667de892c5 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Fri, 19 Jun 2020 06:41:50 -0700 Subject: [PATCH] Added more 'alt' lookups --- BeefLibs/corlib/src/Collections/Dictionary.bf | 178 +++++++++++++++--- BeefLibs/corlib/src/Collections/List.bf | 38 ++++ IDE/src/FileWatcher.bf | 4 +- IDE/src/Workspace.bf | 2 +- IDE/src/ui/OpenFileInSolutionDialog.bf | 2 +- 5 files changed, 194 insertions(+), 30 deletions(-) diff --git a/BeefLibs/corlib/src/Collections/Dictionary.bf b/BeefLibs/corlib/src/Collections/Dictionary.bf index d3ea79ab..2206e3c9 100644 --- a/BeefLibs/corlib/src/Collections/Dictionary.bf +++ b/BeefLibs/corlib/src/Collections/Dictionary.bf @@ -151,6 +151,11 @@ namespace System.Collections return Insert(key, false, out keyPtr, out valuePtr, null); } + public bool TryAddAlt(TAltKey key, out TKey* keyPtr, out TValue* valuePtr) where TAltKey : IOpEquals, IHashable + { + return InsertAlt(key, false, out keyPtr, out valuePtr, null); + } + protected virtual (Entry*, int_cosize*) Alloc(int size) { int byteSize = size * (strideof(Entry) + sizeof(int_cosize)); @@ -246,6 +251,11 @@ namespace System.Collections return FindEntry(key) >= 0; } + public bool ContainsKeyAlt(TAltKey key) where TAltKey : IOpEquals, IHashable + { + return FindEntryAlt(key) >= 0; + } + public bool ContainsValue(TValue value) { if (value == null) @@ -309,8 +319,8 @@ namespace System.Collections { if (mBuckets != null) { - int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF; - for (int_cosize i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext) + int hashCode = key.GetHashCode() & 0x7FFFFFFF; + for (int i = mBuckets[hashCode % mAllocSize]; i >= 0; i = mEntries[i].mNext) { if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) return i; } @@ -323,7 +333,7 @@ namespace System.Collections return key == key2; } - private int FindEntryWith(TAltKey key) where TAltKey : IOpEquals, IHashable + private int FindEntryAlt(TAltKey key) where TAltKey : IOpEquals, IHashable { if (mBuckets != null) { @@ -453,6 +463,61 @@ namespace System.Collections return true; } + private bool InsertAlt(TAltKey key, bool add, out TKey* keyPtr, out TValue* valuePtr, Entry** outOldData) where TAltKey : IOpEquals, IHashable + { + 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) + { + if (mEntries[i].mHashCode == hashCode && (mEntries[i].mKey == key)) + { + if (add) + { + Runtime.FatalError("Adding duplicate entry"); + } + keyPtr = &mEntries[i].mKey; + valuePtr = &mEntries[i].mValue; + if (outOldData != null) + *outOldData = null; + return false; + } + } + int_cosize index; + Entry* oldData = null; + if (mFreeCount > 0) + { + index = mFreeList; + mFreeList = mEntries[index].mNext; + mFreeCount--; + } + else + { + if (mCount == mAllocSize) + { + oldData = Resize(false); + targetBucket = hashCode % (int_cosize)mAllocSize; + } + index = mCount; + mCount++; + } + + mEntries[index].mHashCode = hashCode; + mEntries[index].mNext = mBuckets[targetBucket]; + mBuckets[targetBucket] = index; +#if VERSION_DICTIONARY + mVersion++; +#endif + + keyPtr = &mEntries[index].mKey; + valuePtr = &mEntries[index].mValue; + if (outOldData != null) + *outOldData = oldData; + else + Free(oldData); + return true; + } + // Close to prime but faster to compute int_cosize GetPrimeish(int_cosize min) { @@ -513,18 +578,48 @@ namespace System.Collections public bool Remove(TKey key) { - if (key == null) - { - ThrowUnimplemented(); - //ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); - } - if (mBuckets != null) { - - int32 hashCode = (int32)key.GetHashCode() & 0x7FFFFFFF; - int_cosize bucket = hashCode % (int_cosize)mAllocSize; - int_cosize last = -1; + int hashCode = key.GetHashCode() & 0x7FFFFFFF; + int bucket = hashCode % (int_cosize)mAllocSize; + int last = -1; + for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) + { + if ((mEntries[i].mHashCode == hashCode) && (mEntries[i].mKey == key)) + { + if (last < 0) + { + mBuckets[bucket] = mEntries[i].mNext; + } + else + { + mEntries[last].mNext = mEntries[i].mNext; + } + mEntries[i].mHashCode = -1; + mEntries[i].mNext = mFreeList; +#if BF_ENABLE_REALTIME_LEAK_CHECK + mEntries[i].mKey = default; + mEntries[i].mValue = default; +#endif + mFreeList = i; + mFreeCount++; +#if VERSION_DICTIONARY + mVersion++; +#endif + return true; + } + } + } + return false; + } + + public bool RemoveAlt(TAltKey key) where TAltKey : IOpEquals, IHashable + { + if (mBuckets != null) + { + int hashCode = key.GetHashCode() & 0x7FFFFFFF; + int bucket = hashCode % (int_cosize)mAllocSize; + int last = -1; for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) { if ((mEntries[i].mHashCode == hashCode) && (mEntries[i].mKey == key)) @@ -602,6 +697,47 @@ namespace System.Collections return .Err; } + public Result<(TKey key, TValue value)> GetAndRemoveAlt(TAltKey key) where TAltKey : IOpEquals, IHashable + { + if (mBuckets != null) + { + + int_cosize hashCode = (int_cosize)key.GetHashCode() & 0x7FFFFFFF; + int_cosize bucket = hashCode % (int_cosize)mAllocSize; + int_cosize last = -1; + for (int_cosize i = mBuckets[bucket]; i >= 0; last = i,i = mEntries[i].mNext) + { + if ((mEntries[i].mHashCode == hashCode) && (mEntries[i].mKey == key)) + { + if (last < 0) + { + mBuckets[bucket] = mEntries[i].mNext; + } + else + { + mEntries[last].mNext = mEntries[i].mNext; + } + TKey entryKey = mEntries[i].mKey; + TValue result = mEntries[i].mValue; + + mEntries[i].mHashCode = -1; + mEntries[i].mNext = mFreeList; +#if BF_ENABLE_REALTIME_LEAK_CHECK + mEntries[i].mKey = default(TKey); + mEntries[i].mValue = default(TValue); +#endif + mFreeList = i; + mFreeCount++; +#if VERSION_DICTIONARY + mVersion++; +#endif + return .Ok((entryKey, result)); + } + } + } + return .Err; + } + public bool TryGetValue(TKey key, out TValue value) { int_cosize i = (int_cosize)FindEntry(key); @@ -614,7 +750,7 @@ namespace System.Collections return false; } - public bool TryGetValue(TKey key, out TKey matchKey, out TValue value) + public bool TryGet(TKey key, out TKey matchKey, out TValue value) { int_cosize i = (int_cosize)FindEntry(key); if (i >= 0) @@ -628,9 +764,9 @@ namespace System.Collections return false; } - public bool TryGetWith(TAltKey key, out TKey matchKey, out TValue value) where TAltKey : IOpEquals, IHashable + public bool TryGetAlt(TAltKey key, out TKey matchKey, out TValue value) where TAltKey : IOpEquals, IHashable { - int_cosize i = (int_cosize)FindEntryWith(key); + int_cosize i = (int_cosize)FindEntryAlt(key); if (i >= 0) { matchKey = mEntries[i].mKey; @@ -652,16 +788,6 @@ namespace System.Collections return default(TValue); } - private static bool IsCompatibleKey(Object key) - { - if (key == null) - { - ThrowUnimplemented(); - //ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); - } - return (key is TKey); - } - public struct Enumerator : IEnumerator, IRefEnumerator { private Dictionary mDictionary; diff --git a/BeefLibs/corlib/src/Collections/List.bf b/BeefLibs/corlib/src/Collections/List.bf index a2ee132f..67749415 100644 --- a/BeefLibs/corlib/src/Collections/List.bf +++ b/BeefLibs/corlib/src/Collections/List.bf @@ -353,6 +353,11 @@ namespace System.Collections } } + public bool ContainsAlt(TAlt item) where TAlt : IOpEquals, IHashable + { + return IndexOfAlt(item) != -1; + } + public void CopyTo(T[] array) { CopyTo(array, 0); @@ -460,6 +465,14 @@ namespace System.Collections return -1; } + public int IndexOfAlt(TAlt item) where TAlt : IOpEquals, IHashable + { + for (int i = 0; i < mSize; i++) + if (mItems[i] == item) + return i; + return -1; + } + public int LastIndexOf(T item) { for (int i = mSize - 1; i >= 0; i--) @@ -621,6 +634,18 @@ namespace System.Collections return false; } + public bool RemoveAlt(TAlt item) where TAlt : IOpEquals, IHashable + { + int index = IndexOfAlt(item); + if (index >= 0) + { + RemoveAt(index); + return true; + } + + return false; + } + public Result GetAndRemove(T item) { int index = IndexOf(item); @@ -634,6 +659,19 @@ namespace System.Collections return .Err; } + public Result GetAndRemoveAlt(TAlt item) where TAlt : IOpEquals, IHashable + { + int index = IndexOfAlt(item); + if (index >= 0) + { + T val = mItems[index]; + RemoveAt(index); + return val; + } + + return .Err; + } + /// The method returns the index of the given value in the list. If the /// list does not contain the given value, the method returns a negative /// integer. The bitwise complement operator (~) can be applied to a diff --git a/IDE/src/FileWatcher.bf b/IDE/src/FileWatcher.bf index ae68031b..201c5d9b 100644 --- a/IDE/src/FileWatcher.bf +++ b/IDE/src/FileWatcher.bf @@ -533,7 +533,7 @@ namespace IDE { DepInfo depInfo; String outKey; - if (!mWatchedFiles.TryGetValue(fixedFilePath, out outKey, out depInfo)) + if (!mWatchedFiles.TryGet(fixedFilePath, out outKey, out depInfo)) return; depInfo.mDependentObjects.Remove(dependentObject); @@ -545,7 +545,7 @@ namespace IDE Path.GetDirectoryPath(fixedFilePath, directoryName); WatcherEntry watcherEntry = null; String key; - mWatchers.TryGetValue(directoryName, out key, out watcherEntry); + mWatchers.TryGet(directoryName, out key, out watcherEntry); DerefWatcherEntry(watcherEntry); diff --git a/IDE/src/Workspace.bf b/IDE/src/Workspace.bf index f370ccd9..1d4fd821 100644 --- a/IDE/src/Workspace.bf +++ b/IDE/src/Workspace.bf @@ -766,7 +766,7 @@ namespace IDE } } - if (mProjectNameMap.TryGetWith(projectName, var matchKey, var value)) + if (mProjectNameMap.TryGetAlt(projectName, var matchKey, var value)) { return value; } diff --git a/IDE/src/ui/OpenFileInSolutionDialog.bf b/IDE/src/ui/OpenFileInSolutionDialog.bf index e5019a70..3f8ee85e 100644 --- a/IDE/src/ui/OpenFileInSolutionDialog.bf +++ b/IDE/src/ui/OpenFileInSolutionDialog.bf @@ -213,7 +213,7 @@ namespace IDE.ui { var fixedPath = scope String(path); IDEUtils.MakeComparableFilePath(fixedPath); - if (sTimeCache.TryGetValue(fixedPath, var key, var value)) + if (sTimeCache.TryGet(fixedPath, var key, var value)) { value.mCheckedTime = default; }