more default value related fixes for FishSet and FishTable
This commit is contained in:
@@ -636,24 +636,31 @@ public static class CollectionExtensions
|
||||
return destination;
|
||||
}
|
||||
|
||||
public static unsafe void Fill<T>(this T[] array, T value)
|
||||
public static void Fill<T>(this T[] array, T value)
|
||||
{
|
||||
Guard.IsNotNull(array);
|
||||
|
||||
var i = array.Length - 1;
|
||||
|
||||
if (array.Length == 0)
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
fixed (T* startAddress = &array[0])
|
||||
|
||||
do
|
||||
{
|
||||
var i = array.Length - 1;
|
||||
do
|
||||
{
|
||||
startAddress[i] = value;
|
||||
}
|
||||
while (--i >= 0);
|
||||
array.UnsafeStore(i, value);
|
||||
}
|
||||
while (--i >= 0);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T UnsafeLoad<T>(this T[] array, int index) => Array.UnsafeLoad(array, index);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void UnsafeStore<T>(this T[] array, int index, T value) => Array.UnsafeStore(array, index, value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TTo UnsafeCast<TFrom, TTo>(this TFrom obj) => Array.UnsafeMov<TFrom, TTo>(obj);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void AddRangeFast<T>(this List<T> list, T[] range)
|
||||
{
|
||||
|
||||
@@ -205,7 +205,11 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
|
||||
|
||||
private void SetBucketEmpty(int index)
|
||||
{
|
||||
_buckets[index] = _defaultValue;
|
||||
var buckets = _buckets;
|
||||
if (buckets.Length <= index)
|
||||
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
|
||||
|
||||
buckets.UnsafeStore(index, _defaultValue);
|
||||
_tails.SetEmpty(index);
|
||||
}
|
||||
|
||||
@@ -303,10 +307,10 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
|
||||
return tailCount;
|
||||
}
|
||||
|
||||
private bool IsBucketEmpty(int bucketIndex) => IsBucketEmpty(bucketIndex, _tails, _buckets);
|
||||
private bool IsBucketEmpty(int bucketIndex) => IsBucketEmpty(bucketIndex, _tails);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool IsBucketEmpty(int bucketIndex, Tails tails, T?[] buckets) => tails.IsEmpty(bucketIndex);
|
||||
private static bool IsBucketEmpty(int bucketIndex, Tails tails) => tails.IsEmpty(bucketIndex);
|
||||
|
||||
private bool TryFindTailIndexAndReplace(T entry, ref int bucketIndex, ReplaceBehaviour replaceBehaviour)
|
||||
{
|
||||
@@ -389,12 +393,15 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
|
||||
var tailingEntries = new PooledIList<List<T>>();
|
||||
var tailingEntriesList = tailingEntries.List;
|
||||
var tailIndex = GetTailIndex(bucketIndex);
|
||||
var buckets = _buckets;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ref var tailingBucket = ref _buckets[tailIndex];
|
||||
tailingEntriesList.Add(tailingBucket!);
|
||||
tailingBucket = _defaultValue;
|
||||
if (tailIndex >= buckets.Length)
|
||||
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
|
||||
|
||||
tailingEntriesList.Add(buckets.UnsafeLoad(tailIndex)!);
|
||||
buckets.UnsafeStore(tailIndex, _defaultValue);
|
||||
|
||||
if (HasTail(tailIndex))
|
||||
{
|
||||
@@ -454,7 +461,7 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
|
||||
|
||||
for (var i = 0; i < oldBuckets.Length; i++)
|
||||
{
|
||||
if (!IsBucketEmpty(i, oldTails, oldBuckets))
|
||||
if (!IsBucketEmpty(i, oldTails))
|
||||
InsertEntry(oldBuckets[i]!, ReplaceBehaviour.Throw, true);
|
||||
}
|
||||
}
|
||||
@@ -802,6 +809,13 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
|
||||
internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
|
||||
=> throw new InvalidOperationException("Enumeration has either not started or has already finished.");
|
||||
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
|
||||
=> throw new InvalidOperationException(
|
||||
"Operations that change non-concurrent collections must have exclusive access. A concurrent "
|
||||
+ "update was performed on this collection and corrupted its state. The collection's state is no "
|
||||
+ "longer correct.");
|
||||
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowWrongKeyTypeArgumentException(object? key)
|
||||
{
|
||||
|
||||
@@ -312,7 +312,11 @@ public class FishTable<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, I
|
||||
|
||||
private void SetBucketEmpty(int index)
|
||||
{
|
||||
_buckets[index] = _defaultEntry;
|
||||
var buckets = _buckets;
|
||||
if (buckets.Length <= index)
|
||||
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
|
||||
|
||||
buckets.UnsafeStore(index, _defaultEntry);
|
||||
_tails.SetEmpty(index);
|
||||
}
|
||||
|
||||
@@ -565,12 +569,15 @@ public class FishTable<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, I
|
||||
var tailingEntries = new PooledIList<List<Entry>>();
|
||||
var tailingEntriesList = tailingEntries.List;
|
||||
var tailIndex = GetTailIndex(bucketIndex);
|
||||
var buckets = _buckets;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ref var tailingBucket = ref _buckets[tailIndex];
|
||||
tailingEntriesList.Add(tailingBucket);
|
||||
tailingBucket = _defaultEntry;
|
||||
if (tailIndex >= buckets.Length)
|
||||
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
|
||||
|
||||
tailingEntriesList.Add(buckets.UnsafeLoad(tailIndex));
|
||||
buckets.UnsafeStore(tailIndex, _defaultEntry);
|
||||
|
||||
if (HasTail(tailIndex))
|
||||
{
|
||||
@@ -1759,6 +1766,13 @@ public class FishTable<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, I
|
||||
internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
|
||||
=> throw new InvalidOperationException("Enumeration has either not started or has already finished.");
|
||||
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
|
||||
=> throw new InvalidOperationException(
|
||||
"Operations that change non-concurrent collections must have exclusive access. A concurrent "
|
||||
+ "update was performed on this collection and corrupted its state. The collection's state is no "
|
||||
+ "longer correct.");
|
||||
|
||||
[DoesNotReturn]
|
||||
internal static void ThrowKeyNotFoundException<T>(T key)
|
||||
{
|
||||
|
||||
@@ -29,11 +29,11 @@ namespace FisheryLib;
|
||||
[PublicAPI]
|
||||
public static class FisheryLib
|
||||
{
|
||||
public const decimal VERSION = 0.511M;
|
||||
public const decimal VERSION = 0.512M;
|
||||
|
||||
public static decimal CurrentlyLoadedVersion { get; } = VERSION;
|
||||
|
||||
public const string VERSION_STRING = "0.5.1.1";
|
||||
public const string VERSION_STRING = "0.5.1.2";
|
||||
|
||||
// public static string GetVersion()
|
||||
// {
|
||||
|
||||
Reference in New Issue
Block a user