more default value related fixes for FishSet and FishTable
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -636,23 +636,30 @@ 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);
|
||||
|
||||
if (array.Length == 0)
|
||||
var i = array.Length - 1;
|
||||
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
fixed (T* startAddress = &array[0])
|
||||
{
|
||||
var i = array.Length - 1;
|
||||
do
|
||||
{
|
||||
startAddress[i] = value;
|
||||
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