diff --git a/Recyclable.Collections/RecyclableLongList.AddRange.cs b/Recyclable.Collections/RecyclableLongList.AddRange.cs index cec751b..9e1bd79 100644 --- a/Recyclable.Collections/RecyclableLongList.AddRange.cs +++ b/Recyclable.Collections/RecyclableLongList.AddRange.cs @@ -126,7 +126,9 @@ namespace Recyclable.Collections } targetList._capacity = capacity; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif return; } @@ -186,10 +188,13 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = targetBlockIdx; targetList._nextItemIndex = targetItemIdx; targetList._lastBlockWithData = targetBlockIdx - (targetItemIdx > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } - public static void AddRange(this RecyclableLongList targetList, in Array items) + [VersionedCollectionsGenerator.RewriteForVersioned] + public static void AddRange(this RecyclableLongList targetList, in Array items) { if (items.LongLength == 0) { @@ -240,7 +245,9 @@ namespace Recyclable.Collections } targetList._longCount = targetCapacity; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, ICollection items) @@ -305,7 +312,9 @@ namespace Recyclable.Collections RecyclableArrayPool.ReturnShared(itemsBuffer, RecyclableLongList._needsClearing); } - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, ICollection items) @@ -373,7 +382,9 @@ namespace Recyclable.Collections RecyclableArrayPool.ReturnShared(itemsBuffer, RecyclableLongList._needsClearing); } - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, IEnumerable source) @@ -616,7 +627,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = targetBlockIndex; targetList._longCount = targetCapacity; targetList._lastBlockWithData = targetBlockIndex - (targetList._nextItemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, ReadOnlySpan items) @@ -671,7 +684,9 @@ namespace Recyclable.Collections targetList._longCount = targetCapacity; targetList._lastBlockWithData = targetBlockIndex; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, RecyclableList items) @@ -728,7 +743,9 @@ namespace Recyclable.Collections } targetList._longCount = targetCapacity; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, RecyclableLongList items) @@ -801,7 +818,9 @@ namespace Recyclable.Collections } targetList._longCount = targetCapacity; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, Span items) @@ -856,7 +875,9 @@ namespace Recyclable.Collections targetList._longCount = targetCapacity; targetList._lastBlockWithData = targetBlockIndex; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } public static void AddRange(this RecyclableLongList targetList, in T[] items) @@ -912,7 +933,9 @@ namespace Recyclable.Collections targetList._longCount = targetCapacity; targetList._lastBlockWithData = targetBlockIndex; - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -954,7 +977,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -999,7 +1024,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1038,7 +1065,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1082,7 +1111,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1121,7 +1152,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1165,7 +1198,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1208,7 +1243,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] @@ -1248,7 +1285,9 @@ namespace Recyclable.Collections targetList._nextItemBlockIndex = blockIndex; targetList._nextItemIndex = itemIndex; targetList._lastBlockWithData = blockIndex - (itemIndex > 0 ? 0 : 1); - targetList._version++; + #if WITH_VERSIONING +targetList._version++; +#endif } } } diff --git a/Recyclable.Collections/RecyclableLongList.Compatibility.List.Sorted.cs b/Recyclable.Collections/RecyclableLongList.Compatibility.List.Sorted.cs index 7e28d19..885f574 100644 --- a/Recyclable.Collections/RecyclableLongList.Compatibility.List.Sorted.cs +++ b/Recyclable.Collections/RecyclableLongList.Compatibility.List.Sorted.cs @@ -10,19 +10,25 @@ namespace Recyclable.Collections public static void Sort(this RecyclableLongList list) { QuickSortExtensions.QuickSort(list); +#if WITH_VERSIONING list._version++; +#endif } public static void Sort(this RecyclableLongList list, Comparison comparison) { QuickSortExtensions.QuickSort(list, new ComparisonToComparerAdapter(comparison), new SystemRandomNumberGenerator()); +#if WITH_VERSIONING list._version++; +#endif } public static void Sort(this RecyclableLongList list, IComparer? comparer) { QuickSortExtensions.QuickSort(list, comparer ?? Comparer.Default, new SystemRandomNumberGenerator()); +#if WITH_VERSIONING list._version++; +#endif } public static void Sort(this RecyclableLongList list, long index, long count, IComparer? comparer) @@ -33,7 +39,9 @@ namespace Recyclable.Collections } QuickSortExtensions.QuickSort(list, (int)index, (int)(index + count - 1), comparer ?? Comparer.Default, new SystemRandomNumberGenerator()); +#if WITH_VERSIONING list._version++; +#endif } } } diff --git a/Recyclable.Collections/RecyclableLongList.cs b/Recyclable.Collections/RecyclableLongList.cs index a2daf6d..c9b574b 100644 --- a/Recyclable.Collections/RecyclableLongList.cs +++ b/Recyclable.Collections/RecyclableLongList.cs @@ -9,7 +9,8 @@ using Recyclable.Collections.Pools; namespace Recyclable.Collections { - public partial class RecyclableLongList : IList, IReadOnlyList, IDisposable + [VersionedCollectionsGenerator.GenerateVersioned] + public partial class RecyclableLongList : IList, IReadOnlyList, IDisposable { private static readonly bool _defaultIsNull = default(T) == null; internal static readonly bool _needsClearing = !typeof(T).IsValueType; @@ -25,7 +26,7 @@ namespace Recyclable.Collections #nullable restore internal int _nextItemBlockIndex; internal int _nextItemIndex; - internal ulong _version; + internal ulong _version; public int BlockSize => _blockSize; public int BlockSizeMinus1 => _blockSizeMinus1; @@ -35,15 +36,19 @@ namespace Recyclable.Collections get => _capacity; private set { - _capacity = value; - _version++; - if (_capacity != value) - { - _capacity = Helpers.Resize(this, _blockSize, _blockSizePow2BitShift, checked((long)BitOperations.RoundUpToPowerOf2((ulong)value))); - _version++; - } - } - } + _capacity = value; +#if WITH_VERSIONING + _version++; +#endif + if (_capacity != value) + { + _capacity = Helpers.Resize(this, _blockSize, _blockSizePow2BitShift, checked((long)BitOperations.RoundUpToPowerOf2((ulong)value))); +#if WITH_VERSIONING + _version++; +#endif + } + } + } public int Count => checked((int)_longCount); public bool IsReadOnly => false; @@ -51,7 +56,8 @@ namespace Recyclable.Collections public long LongCount => _longCount; public int NextItemBlockIndex => _nextItemBlockIndex; public int NextItemIndex => _nextItemIndex; - public ulong Version => _version; + [VersionedCollectionsGenerator.CloneForVersioned] + public ulong Version => _version; public RecyclableLongList(int minBlockSize = RecyclableDefaults.BlockSize, long initialCapacity = RecyclableDefaults.InitialCapacity) { @@ -251,20 +257,24 @@ namespace Recyclable.Collections get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1]; set { - new Span(_memoryBlocks[(int)(index >> _blockSizePow2BitShift)])[(int)(index & _blockSizeMinus1)] = value; - _version++; - } - } + new Span(_memoryBlocks[(int)(index >> _blockSizePow2BitShift)])[(int)(index & _blockSizeMinus1)] = value; +#if WITH_VERSIONING + _version++; +#endif + } + } public T this[int index] { get => _memoryBlocks[index >> _blockSizePow2BitShift][index & _blockSizeMinus1]; set { - new Span(_memoryBlocks[index >> _blockSizePow2BitShift])[index & _blockSizeMinus1] = value; - _version++; - } - } + new Span(_memoryBlocks[index >> _blockSizePow2BitShift])[index & _blockSizeMinus1] = value; +#if WITH_VERSIONING + _version++; +#endif + } + } public T[][] AsArray => _memoryBlocks; @@ -292,9 +302,11 @@ namespace Recyclable.Collections _lastBlockWithData++; } - _longCount++; - _version++; - } + _longCount++; +#if WITH_VERSIONING + _version++; +#endif + } public void Clear() { @@ -326,9 +338,11 @@ namespace Recyclable.Collections _nextItemBlockIndex = 0; _nextItemIndex = 0; _lastBlockWithData = RecyclableDefaults.ItemNotFoundIndex; - _longCount = 0; - _version++; - } + _longCount = 0; +#if WITH_VERSIONING + _version++; +#endif + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(T item) @@ -433,8 +447,10 @@ namespace Recyclable.Collections _lastBlockWithData++; } - _version++; - } +#if WITH_VERSIONING + _version++; +#endif + } public void Insert(long index, T item) { @@ -472,8 +488,10 @@ namespace Recyclable.Collections _lastBlockWithData++; } - _version++; - } +#if WITH_VERSIONING + _version++; +#endif + } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public long LongIndexOf(T item) @@ -543,9 +561,11 @@ namespace Recyclable.Collections #nullable restore } - _version++; - return true; - } +#if WITH_VERSIONING + _version++; +#endif + return true; + } return false; } @@ -585,8 +605,10 @@ namespace Recyclable.Collections #nullable restore } - _version++; - } +#if WITH_VERSIONING + _version++; +#endif + } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public void RemoveAt(long index) @@ -623,8 +645,10 @@ namespace Recyclable.Collections #nullable restore } - _version++; - } +#if WITH_VERSIONING + _version++; +#endif + } public void RemoveBlock(int index) { @@ -644,17 +668,21 @@ namespace Recyclable.Collections _nextItemBlockIndex--; } - _lastBlockWithData--; - _version++; - } + _lastBlockWithData--; +#if WITH_VERSIONING + _version++; +#endif + } - public void Dispose() - { - _version++; - if (_capacity > 0) - { - Clear(); - if (_memoryBlocks.Length >= RecyclableDefaults.MinPooledArrayLength) + public void Dispose() + { +#if WITH_VERSIONING + _version++; +#endif + if (_capacity > 0) + { + 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. RecyclableArrayPool.ReturnShared(_memoryBlocks, false);