Add versioning support for RecyclableLongList
This commit is contained in:
1 parent
ed23fd7f69
commit
1e64c71af3
3 files changed
+142
-67
No files matched your search
@@ -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<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)
|
||||
{
|
||||
@@ -240,7 +245,9 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
targetList._longCount = targetCapacity;
|
||||
targetList._version++;
|
||||
#if WITH_VERSIONING
|
||||
targetList._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
targetList._version++;
|
||||
#if WITH_VERSIONING
|
||||
targetList._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
targetList._version++;
|
||||
#if WITH_VERSIONING
|
||||
targetList._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void AddRange<T>(this RecyclableLongList<T> 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<T>(this RecyclableLongList<T> targetList, ReadOnlySpan<T> 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<T>(this RecyclableLongList<T> targetList, RecyclableList<T> items)
|
||||
@@ -728,7 +743,9 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
targetList._longCount = targetCapacity;
|
||||
targetList._version++;
|
||||
#if WITH_VERSIONING
|
||||
targetList._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void AddRange<T>(this RecyclableLongList<T> targetList, RecyclableLongList<T> items)
|
||||
@@ -801,7 +818,9 @@ namespace Recyclable.Collections
|
||||
}
|
||||
|
||||
targetList._longCount = targetCapacity;
|
||||
targetList._version++;
|
||||
#if WITH_VERSIONING
|
||||
targetList._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void AddRange<T>(this RecyclableLongList<T> targetList, Span<T> 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<T>(this RecyclableLongList<T> 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,19 +10,25 @@ namespace Recyclable.Collections
|
||||
public static void Sort<T>(this RecyclableLongList<T> list)
|
||||
{
|
||||
QuickSortExtensions<T>.QuickSort(list);
|
||||
#if WITH_VERSIONING
|
||||
list._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Sort<T>(this RecyclableLongList<T> list, Comparison<T> comparison)
|
||||
{
|
||||
QuickSortExtensions<T>.QuickSort(list, new ComparisonToComparerAdapter<T>(comparison), new SystemRandomNumberGenerator());
|
||||
#if WITH_VERSIONING
|
||||
list._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Sort<T>(this RecyclableLongList<T> list, IComparer<T>? comparer)
|
||||
{
|
||||
QuickSortExtensions<T>.QuickSort(list, comparer ?? Comparer<T>.Default, new SystemRandomNumberGenerator());
|
||||
#if WITH_VERSIONING
|
||||
list._version++;
|
||||
#endif
|
||||
}
|
||||
|
||||
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());
|
||||
#if WITH_VERSIONING
|
||||
list._version++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,8 @@ using Recyclable.Collections.Pools;
|
||||
|
||||
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;
|
||||
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<T>(_memoryBlocks[(int)(index >> _blockSizePow2BitShift)])[(int)(index & _blockSizeMinus1)] = value;
|
||||
_version++;
|
||||
}
|
||||
}
|
||||
new Span<T>(_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<T>(_memoryBlocks[index >> _blockSizePow2BitShift])[index & _blockSizeMinus1] = value;
|
||||
_version++;
|
||||
}
|
||||
}
|
||||
new Span<T>(_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<T[]>.ReturnShared(_memoryBlocks, false);
|
||||
|
||||
Reference in new issue
Block a user