Implement versioned enumerator retrieval

This commit is contained in:
Marek Lemańczyk committed 2025-07-14 22:43:43 +02:00
1 parent ed23fd7f69
commit c2affa4ad7
10 files changed
+207 -93

No files matched your search

@@ -6,9 +6,10 @@ namespace Recyclable.Collections
{ {
public partial class RecyclableList<T> public partial class RecyclableList<T>
{ {
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Enumerator : IEnumerator<T> [VersionedCollectionsGenerator.CloneForVersioned]
{ public struct Enumerator : IEnumerator<T>
{
private static readonly bool _isReferenceType = !typeof(T).IsValueType; private static readonly bool _isReferenceType = !typeof(T).IsValueType;
private int _currentItemIndex; private int _currentItemIndex;
@@ -3,8 +3,9 @@ using System.Runtime.CompilerServices;
namespace Recyclable.Collections namespace Recyclable.Collections
{ {
public static class RecyclableListExtensions [VersionedCollectionsGenerator.GenerateVersioned]
{ public static class RecyclableListExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RecyclableList<T> ToRecyclableList<T>(this Array values) => new(values); public static RecyclableList<T> ToRecyclableList<T>(this Array values) => new(values);
@@ -6,11 +6,13 @@ namespace Recyclable.Collections
{ {
public partial class RecyclableList<T> : IRecyclableVersionedList<T> public partial class RecyclableList<T> : IRecyclableVersionedList<T>
{ {
VersionedEnumerator IRecyclableVersionedList<T>.GetEnumerator() => new(this); [VersionedCollectionsGenerator.CloneForVersioned]
VersionedEnumerator IRecyclableVersionedList<T>.GetEnumerator() => new(this);
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VersionedEnumerator : IEnumerator<T> [VersionedCollectionsGenerator.CloneForVersioned]
{ public struct VersionedEnumerator : IEnumerator<T>
{
private int _currentItemIndex; private int _currentItemIndex;
private readonly ulong _enumeratorVersion; private readonly ulong _enumeratorVersion;
private readonly RecyclableList<T> _list; private readonly RecyclableList<T> _list;
+21 -6
View File
@@ -363,14 +363,29 @@ namespace Recyclable.Collections
#endif #endif
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() => new(this); [VersionedCollectionsGenerator.CloneForVersioned]
#if WITH_VERSIONING
public VersionedEnumerator GetEnumerator() => new(this);
#else
public Enumerator GetEnumerator() => new(this);
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this); [VersionedCollectionsGenerator.CloneForVersioned]
#if WITH_VERSIONING
IEnumerator IEnumerable.GetEnumerator() => new VersionedEnumerator(this);
#else
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this); [VersionedCollectionsGenerator.CloneForVersioned]
#if WITH_VERSIONING
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new VersionedEnumerator(this);
#else
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this);
#endif
public void Dispose() public void Dispose()
{ {
@@ -126,7 +126,9 @@ namespace Recyclable.Collections
} }
targetList._capacity = capacity; targetList._capacity = capacity;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
return; return;
} }
@@ -186,10 +188,13 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = targetBlockIdx; targetList._nextItemBlockIndex = targetBlockIdx;
targetList._nextItemIndex = targetItemIdx; targetList._nextItemIndex = targetItemIdx;
targetList._lastBlockWithData = targetBlockIdx - (targetItemIdx > 0 ? 0 : 1); targetList._lastBlockWithData = targetBlockIdx - (targetItemIdx > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, in Array items) [VersionedCollectionsGenerator.RewriteForVersioned]
public static void AddRange<T>(this RecyclableLongList<T> targetList, in Array items)
{ {
if (items.LongLength == 0) if (items.LongLength == 0)
{ {
@@ -240,7 +245,9 @@ namespace Recyclable.Collections
} }
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, ICollection items) public static void AddRange<T>(this RecyclableLongList<T> targetList, ICollection items)
@@ -305,7 +312,9 @@ namespace Recyclable.Collections
RecyclableArrayPool<T>.ReturnShared(itemsBuffer, RecyclableLongList<T>._needsClearing); RecyclableArrayPool<T>.ReturnShared(itemsBuffer, RecyclableLongList<T>._needsClearing);
} }
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, ICollection<T> items) public static void AddRange<T>(this RecyclableLongList<T> targetList, ICollection<T> items)
@@ -373,7 +382,9 @@ namespace Recyclable.Collections
RecyclableArrayPool<T>.ReturnShared(itemsBuffer, RecyclableLongList<T>._needsClearing); RecyclableArrayPool<T>.ReturnShared(itemsBuffer, RecyclableLongList<T>._needsClearing);
} }
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, IEnumerable source) public static void AddRange<T>(this RecyclableLongList<T> targetList, IEnumerable source)
@@ -616,7 +627,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = targetBlockIndex; targetList._nextItemBlockIndex = targetBlockIndex;
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._lastBlockWithData = targetBlockIndex - (targetList._nextItemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = targetBlockIndex - (targetList._nextItemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, ReadOnlySpan<T> items) public static void AddRange<T>(this RecyclableLongList<T> targetList, ReadOnlySpan<T> items)
@@ -671,7 +684,9 @@ namespace Recyclable.Collections
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._lastBlockWithData = targetBlockIndex; targetList._lastBlockWithData = targetBlockIndex;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, RecyclableList<T> items) public static void AddRange<T>(this RecyclableLongList<T> targetList, RecyclableList<T> items)
@@ -728,7 +743,9 @@ namespace Recyclable.Collections
} }
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, RecyclableLongList<T> items) public static void AddRange<T>(this RecyclableLongList<T> targetList, RecyclableLongList<T> items)
@@ -801,7 +818,9 @@ namespace Recyclable.Collections
} }
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, Span<T> items) public static void AddRange<T>(this RecyclableLongList<T> targetList, Span<T> items)
@@ -856,7 +875,9 @@ namespace Recyclable.Collections
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._lastBlockWithData = targetBlockIndex; targetList._lastBlockWithData = targetBlockIndex;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
public static void AddRange<T>(this RecyclableLongList<T> targetList, in T[] items) public static void AddRange<T>(this RecyclableLongList<T> targetList, in T[] items)
@@ -912,7 +933,9 @@ namespace Recyclable.Collections
targetList._longCount = targetCapacity; targetList._longCount = targetCapacity;
targetList._lastBlockWithData = targetBlockIndex; targetList._lastBlockWithData = targetBlockIndex;
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -954,7 +977,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -999,7 +1024,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1038,7 +1065,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1082,7 +1111,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1121,7 +1152,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1165,7 +1198,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1208,7 +1243,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
@@ -1248,7 +1285,9 @@ namespace Recyclable.Collections
targetList._nextItemBlockIndex = blockIndex; targetList._nextItemBlockIndex = blockIndex;
targetList._nextItemIndex = itemIndex; targetList._nextItemIndex = itemIndex;
targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1);
targetList._version++; #if WITH_VERSIONING
targetList._version++;
#endif
} }
} }
} }
@@ -10,19 +10,25 @@ namespace Recyclable.Collections
public static void Sort<T>(this RecyclableLongList<T> list) public static void Sort<T>(this RecyclableLongList<T> list)
{ {
QuickSortExtensions<T>.QuickSort(list); QuickSortExtensions<T>.QuickSort(list);
#if WITH_VERSIONING
list._version++; list._version++;
#endif
} }
public static void Sort<T>(this RecyclableLongList<T> list, Comparison<T> comparison) public static void Sort<T>(this RecyclableLongList<T> list, Comparison<T> comparison)
{ {
QuickSortExtensions<T>.QuickSort(list, new ComparisonToComparerAdapter<T>(comparison), new SystemRandomNumberGenerator()); QuickSortExtensions<T>.QuickSort(list, new ComparisonToComparerAdapter<T>(comparison), new SystemRandomNumberGenerator());
#if WITH_VERSIONING
list._version++; list._version++;
#endif
} }
public static void Sort<T>(this RecyclableLongList<T> list, IComparer<T>? comparer) public static void Sort<T>(this RecyclableLongList<T> list, IComparer<T>? comparer)
{ {
QuickSortExtensions<T>.QuickSort(list, comparer ?? Comparer<T>.Default, new SystemRandomNumberGenerator()); QuickSortExtensions<T>.QuickSort(list, comparer ?? Comparer<T>.Default, new SystemRandomNumberGenerator());
#if WITH_VERSIONING
list._version++; list._version++;
#endif
} }
public static void Sort<T>(this RecyclableLongList<T> list, long index, long count, IComparer<T>? comparer) public static void Sort<T>(this RecyclableLongList<T> list, long index, long count, IComparer<T>? comparer)
@@ -33,7 +39,9 @@ namespace Recyclable.Collections
} }
QuickSortExtensions<T>.QuickSort(list, (int)index, (int)(index + count - 1), comparer ?? Comparer<T>.Default, new SystemRandomNumberGenerator()); QuickSortExtensions<T>.QuickSort(list, (int)index, (int)(index + count - 1), comparer ?? Comparer<T>.Default, new SystemRandomNumberGenerator());
#if WITH_VERSIONING
list._version++; list._version++;
#endif
} }
} }
} }
@@ -5,8 +5,9 @@ namespace Recyclable.Collections
{ {
public partial class RecyclableLongList<T> public partial class RecyclableLongList<T>
{ {
public struct Enumerator : IEnumerator<T> [VersionedCollectionsGenerator.CloneForVersioned]
{ public struct Enumerator : IEnumerator<T>
{
#nullable disable #nullable disable
private static readonly T _default = default; private static readonly T _default = default;
#nullable restore #nullable restore
@@ -3,8 +3,9 @@ using System.Runtime.CompilerServices;
namespace Recyclable.Collections namespace Recyclable.Collections
{ {
public static class RecyclableLongListExtensions [VersionedCollectionsGenerator.GenerateVersioned]
{ public static class RecyclableLongListExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static RecyclableLongList<T> ToRecyclableLongList<T>(this Array values, int minBlockSize = RecyclableDefaults.BlockSize) => new(values, minBlockSize); public static RecyclableLongList<T> ToRecyclableLongList<T>(this Array values, int minBlockSize = RecyclableDefaults.BlockSize) => new(values, minBlockSize);
@@ -5,11 +5,14 @@ namespace Recyclable.Collections
{ {
public partial class RecyclableLongList<T> : IRecyclableVersionedLongList<T> public partial class RecyclableLongList<T> : IRecyclableVersionedLongList<T>
{ {
public VersionedEnumerator GetVersionedEnumerator() => new(this); [VersionedCollectionsGenerator.CloneForVersioned]
VersionedEnumerator IRecyclableVersionedLongList<T>.GetEnumerator() => new(this); public VersionedEnumerator GetVersionedEnumerator() => new(this);
[VersionedCollectionsGenerator.CloneForVersioned]
VersionedEnumerator IRecyclableVersionedLongList<T>.GetEnumerator() => new(this);
public struct VersionedEnumerator : IEnumerator<T> [VersionedCollectionsGenerator.CloneForVersioned]
{ public struct VersionedEnumerator : IEnumerator<T>
{
#nullable disable #nullable disable
private static readonly T _default = default; private static readonly T _default = default;
#nullable restore #nullable restore
+93 -50
View File
@@ -9,7 +9,8 @@ using Recyclable.Collections.Pools;
namespace Recyclable.Collections namespace Recyclable.Collections
{ {
public partial class RecyclableLongList<T> : IList<T>, IReadOnlyList<T>, IDisposable [VersionedCollectionsGenerator.GenerateVersioned]
public partial class RecyclableLongList<T> : IList<T>, IReadOnlyList<T>, IDisposable
{ {
private static readonly bool _defaultIsNull = default(T) == null; private static readonly bool _defaultIsNull = default(T) == null;
internal static readonly bool _needsClearing = !typeof(T).IsValueType; internal static readonly bool _needsClearing = !typeof(T).IsValueType;
@@ -25,7 +26,7 @@ namespace Recyclable.Collections
#nullable restore #nullable restore
internal int _nextItemBlockIndex; internal int _nextItemBlockIndex;
internal int _nextItemIndex; internal int _nextItemIndex;
internal ulong _version; internal ulong _version;
public int BlockSize => _blockSize; public int BlockSize => _blockSize;
public int BlockSizeMinus1 => _blockSizeMinus1; public int BlockSizeMinus1 => _blockSizeMinus1;
@@ -35,15 +36,19 @@ namespace Recyclable.Collections
get => _capacity; get => _capacity;
private set private set
{ {
_capacity = value; _capacity = value;
_version++; #if WITH_VERSIONING
if (_capacity != value) _version++;
{ #endif
_capacity = Helpers.Resize(this, _blockSize, _blockSizePow2BitShift, checked((long)BitOperations.RoundUpToPowerOf2((ulong)value))); if (_capacity != value)
_version++; {
} _capacity = Helpers.Resize(this, _blockSize, _blockSizePow2BitShift, checked((long)BitOperations.RoundUpToPowerOf2((ulong)value)));
} #if WITH_VERSIONING
} _version++;
#endif
}
}
}
public int Count => checked((int)_longCount); public int Count => checked((int)_longCount);
public bool IsReadOnly => false; public bool IsReadOnly => false;
@@ -51,7 +56,8 @@ namespace Recyclable.Collections
public long LongCount => _longCount; public long LongCount => _longCount;
public int NextItemBlockIndex => _nextItemBlockIndex; public int NextItemBlockIndex => _nextItemBlockIndex;
public int NextItemIndex => _nextItemIndex; public int NextItemIndex => _nextItemIndex;
public ulong Version => _version; [VersionedCollectionsGenerator.CloneForVersioned]
public ulong Version => _version;
public RecyclableLongList(int minBlockSize = RecyclableDefaults.BlockSize, long initialCapacity = RecyclableDefaults.InitialCapacity) public RecyclableLongList(int minBlockSize = RecyclableDefaults.BlockSize, long initialCapacity = RecyclableDefaults.InitialCapacity)
{ {
@@ -251,20 +257,24 @@ namespace Recyclable.Collections
get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1]; get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1];
set set
{ {
new Span<T>(_memoryBlocks[(int)(index >> _blockSizePow2BitShift)])[(int)(index & _blockSizeMinus1)] = value; new Span<T>(_memoryBlocks[(int)(index >> _blockSizePow2BitShift)])[(int)(index & _blockSizeMinus1)] = value;
_version++; #if WITH_VERSIONING
} _version++;
} #endif
}
}
public T this[int index] public T this[int index]
{ {
get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1]; get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1];
set set
{ {
new Span<T>(_memoryBlocks[index >> _blockSizePow2BitShift])[index & _blockSizeMinus1] = value; new Span<T>(_memoryBlocks[index >> _blockSizePow2BitShift])[index & _blockSizeMinus1] = value;
_version++; #if WITH_VERSIONING
} _version++;
} #endif
}
}
public T[][] AsArray => _memoryBlocks; public T[][] AsArray => _memoryBlocks;
@@ -292,9 +302,11 @@ namespace Recyclable.Collections
_lastBlockWithData++; _lastBlockWithData++;
} }
_longCount++; _longCount++;
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
public void Clear() public void Clear()
{ {
@@ -326,9 +338,11 @@ namespace Recyclable.Collections
_nextItemBlockIndex = 0; _nextItemBlockIndex = 0;
_nextItemIndex = 0; _nextItemIndex = 0;
_lastBlockWithData = RecyclableDefaults.ItemNotFoundIndex; _lastBlockWithData = RecyclableDefaults.ItemNotFoundIndex;
_longCount = 0; _longCount = 0;
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(T item) public bool Contains(T item)
@@ -358,9 +372,24 @@ namespace Recyclable.Collections
public void CopyTo(T[] array, int arrayIndex) => Helpers.CopyTo(_memoryBlocks, 0, _blockSize, _longCount, array, arrayIndex); public void CopyTo(T[] array, int arrayIndex) => Helpers.CopyTo(_memoryBlocks, 0, _blockSize, _longCount, array, arrayIndex);
public Enumerator GetEnumerator() => new(this); [VersionedCollectionsGenerator.CloneForVersioned]
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this); #if WITH_VERSIONING
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this); public VersionedEnumerator GetEnumerator() => new(this);
#else
public Enumerator GetEnumerator() => new(this);
#endif
[VersionedCollectionsGenerator.CloneForVersioned]
#if WITH_VERSIONING
IEnumerator IEnumerable.GetEnumerator() => new VersionedEnumerator(this);
#else
IEnumerator IEnumerable.GetEnumerator() => new Enumerator(this);
#endif
[VersionedCollectionsGenerator.CloneForVersioned]
#if WITH_VERSIONING
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new VersionedEnumerator(this);
#else
IEnumerator<T> IEnumerable<T>.GetEnumerator() => new Enumerator(this);
#endif
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public int IndexOf(T item) public int IndexOf(T item)
@@ -433,8 +462,10 @@ namespace Recyclable.Collections
_lastBlockWithData++; _lastBlockWithData++;
} }
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
public void Insert(long index, T item) public void Insert(long index, T item)
{ {
@@ -472,8 +503,10 @@ namespace Recyclable.Collections
_lastBlockWithData++; _lastBlockWithData++;
} }
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public long LongIndexOf(T item) public long LongIndexOf(T item)
@@ -543,9 +576,11 @@ namespace Recyclable.Collections
#nullable restore #nullable restore
} }
_version++; #if WITH_VERSIONING
return true; _version++;
} #endif
return true;
}
return false; return false;
} }
@@ -585,8 +620,10 @@ namespace Recyclable.Collections
#nullable restore #nullable restore
} }
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public void RemoveAt(long index) public void RemoveAt(long index)
@@ -623,8 +660,10 @@ namespace Recyclable.Collections
#nullable restore #nullable restore
} }
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
public void RemoveBlock(int index) public void RemoveBlock(int index)
{ {
@@ -644,17 +683,21 @@ namespace Recyclable.Collections
_nextItemBlockIndex--; _nextItemBlockIndex--;
} }
_lastBlockWithData--; _lastBlockWithData--;
_version++; #if WITH_VERSIONING
} _version++;
#endif
}
public void Dispose() public void Dispose()
{ {
_version++; #if WITH_VERSIONING
if (_capacity > 0) _version++;
{ #endif
Clear(); if (_capacity > 0)
if (_memoryBlocks.Length >= RecyclableDefaults.MinPooledArrayLength) {
Clear();
if (_memoryBlocks.Length >= RecyclableDefaults.MinPooledArrayLength)
{ {
// If anything, it has been already cleared by .Clear(), Remove() or RemoveAt() methods, as the list was modified / disposed. // If anything, it has been already cleared by .Clear(), Remove() or RemoveAt() methods, as the list was modified / disposed.
RecyclableArrayPool<T[]>.ReturnShared(_memoryBlocks, false); RecyclableArrayPool<T[]>.ReturnShared(_memoryBlocks, false);