Small cleanup

This commit is contained in:
mlemanczyk committed 2023-09-03 14:42:18 +02:00
1 parent f928e1e35e
commit 4c7a50969b
9 files changed
+58 -59

No files matched your search

@@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
@@ -4,7 +4,6 @@
{
public const int BlockIndexLimit = int.MaxValue;
public const int BlockSize = 16_384;
public const int Capacity = 1;
public const int InitialCapacity = 4;
public const long MinItemsCountForParallelization = 850_000;
public const int MinPooledArrayLength = 37;
@@ -17,13 +17,14 @@ namespace Recyclable.Collections
{
Span<T> arrayMemory = destinationArray.AsSpan();
arrayMemory = arrayMemory[destinationArrayIndex..];
// TODO: Convert "/" & "%" to bit-shifting
int startingArrayIndex = (int)(startingIndex / blockSize);
startingIndex %= blockSize;
if (arrays.Count > 0)
if (arrays._count > 0)
{
ReadOnlySpan<T> sourceMemory = arrays[0].AsSpan();
var maxToCopy = (int)Math.Min(blockSize - startingIndex, arrayMemory.Length);
if (arrays.Count == 1)
if (arrays._count == 1)
{
maxToCopy = Math.Min(maxToCopy, lastBlockSize);
}
@@ -33,7 +34,7 @@ namespace Recyclable.Collections
arrayMemory = arrayMemory[maxToCopy..];
}
for (var arrayIdx = startingArrayIndex + 1; arrayIdx < arrays.Count - 1 && arrayMemory.Length > 0; arrayIdx++)
for (var arrayIdx = startingArrayIndex + 1; arrayIdx < arrays._count - 1 && arrayMemory.Length > 0; arrayIdx++)
{
ReadOnlySpan<T> sourceMemory = arrays[arrayIdx].AsSpan();
var maxToCopy = Math.Min(blockSize, arrayMemory.Length);
@@ -42,7 +43,7 @@ namespace Recyclable.Collections
arrayMemory = arrayMemory[maxToCopy..];
}
if (arrays.Count > 1 && arrayMemory.Length > 0)
if (arrays._count > 1 && arrayMemory.Length > 0)
{
ReadOnlySpan<T> sourceMemory = arrays[^1].AsSpan();
var maxToCopy = Math.Min(lastBlockSize, arrayMemory.Length);
@@ -56,7 +57,7 @@ namespace Recyclable.Collections
public static IEnumerable<T> Enumerate(RecyclableList<T[]> arrays, int chunkSize, long totalCount)
{
long currentCount = 0;
for (var arrayIdx = 0; (arrayIdx < arrays.Count) && (currentCount < totalCount); arrayIdx++)
for (var arrayIdx = 0; (arrayIdx < arrays._count) && (currentCount < totalCount); arrayIdx++)
{
var array = arrays[arrayIdx];
currentCount += Math.Min(chunkSize, totalCount);
@@ -86,7 +87,7 @@ namespace Recyclable.Collections
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long LongIndexOf(RecyclableList<T[]> arrays, int blockSize, T item, IEqualityComparer<T> comparer)
{
for (var arrayIdx = 0; arrayIdx < arrays.Count; arrayIdx++)
for (var arrayIdx = 0; arrayIdx < arrays._count; arrayIdx++)
{
var array = arrays[arrayIdx];
Span<T> arrayMemory = array.AsSpan();
+15 -15
View File
@@ -8,9 +8,9 @@ namespace Recyclable.Collections
[Serializable]
public sealed partial class RecyclableList<T> : IList<T>, IReadOnlyList<T>, IDisposable
{
private static readonly bool NeedsClearing = !typeof(T).IsValueType;
private static readonly bool _needsClearing = !typeof(T).IsValueType;
public static explicit operator ReadOnlySpan<T>(RecyclableList<T> source) => new(source._memoryBlock, 0, source.Count);
public static explicit operator ReadOnlySpan<T>(RecyclableList<T> source) => new(source._memoryBlock, 0, source._count);
#nullable disable
internal T[] _memoryBlock;
@@ -59,17 +59,17 @@ namespace Recyclable.Collections
return enumerator;
}
private void AddRangeWithKnownCount(IEnumerable<T> source, int targetItemIdx, int requiredAdditionalCapacity)
private void AddRangeWithKnownCount(IEnumerable<T> source, int currentItemsCount, int requiredAdditionalCapacity)
{
_capacity = RecyclableListHelpers<T>.ResizeAndCopy(this, checked((int)BitOperations.RoundUpToPowerOf2((uint)(targetItemIdx + requiredAdditionalCapacity))));
_capacity = RecyclableListHelpers<T>.ResizeAndCopy(this, checked((int)BitOperations.RoundUpToPowerOf2((uint)(currentItemsCount + requiredAdditionalCapacity))));
Span<T> memorySpan = new(_memoryBlock);
foreach (var item in source)
{
memorySpan[targetItemIdx++] = item;
memorySpan[currentItemsCount++] = item;
}
_count = targetItemIdx;
_count = currentItemsCount;
}
public RecyclableList()
@@ -136,7 +136,7 @@ namespace Recyclable.Collections
AddRange(source);
}
public RecyclableList(IEnumerable<T> source, int initialCapacity = RecyclableDefaults.Capacity)
public RecyclableList(IEnumerable<T> source, int initialCapacity = RecyclableDefaults.InitialCapacity)
{
if (initialCapacity >= RecyclableDefaults.InitialCapacity)
{
@@ -271,7 +271,7 @@ namespace Recyclable.Collections
return;
}
var sourceItemsCount = items.LongCount;
var sourceItemsCount = items._longCount;
if (sourceItemsCount > int.MaxValue)
{
ThrowHelper.ThrowArgumentOutOfRangeException(nameof(items), $"The number of items exceeds the maximum capacity of {nameof(RecyclableList<T>)}, equal {int.MaxValue}, equal {int.MaxValue}. Please consider using {nameof(RecyclableLongList<T>)}, instead");
@@ -292,7 +292,7 @@ namespace Recyclable.Collections
itemsSpan;
int blockIndex,
sourceBlockSize = items.BlockSize,
sourceBlockSize = items._blockSize,
lastBlockIndex = (int)(sourceItemsCount >> items._blockSizePow2BitShift) - 1;
for (blockIndex = 0; blockIndex <= lastBlockIndex; blockIndex++)
@@ -307,9 +307,9 @@ namespace Recyclable.Collections
itemsSpan = new(items._memoryBlocks[blockIndex], 0, (int)sourceItemsCount);
itemsSpan.CopyTo(targetSpan);
}
else if (blockIndex <= items.LastBlockWithData)
else if (blockIndex <= items._lastBlockWithData)
{
itemsSpan = new(items._memoryBlocks[blockIndex], 0, items.NextItemIndex);
itemsSpan = new(items._memoryBlocks[blockIndex], 0, items._nextItemIndex);
itemsSpan.CopyTo(targetSpan);
}
@@ -358,7 +358,7 @@ namespace Recyclable.Collections
return;
}
if (NeedsClearing)
if (_needsClearing)
{
Array.Clear(_memoryBlock, 0, _count);
}
@@ -408,7 +408,7 @@ namespace Recyclable.Collections
Array.Copy(_memoryBlock, index + 1, _memoryBlock, index, _count - index);
}
if (NeedsClearing)
if (_needsClearing)
{
_memoryBlock[_count] = default;
}
@@ -435,7 +435,7 @@ namespace Recyclable.Collections
Array.Copy(_memoryBlock, index + 1, _memoryBlock, index, _count - index);
}
if (NeedsClearing)
if (_needsClearing)
{
_memoryBlock[_count] = default;
}
@@ -457,7 +457,7 @@ namespace Recyclable.Collections
_version++;
if (_count != 0)
{
if (NeedsClearing)
if (_needsClearing)
{
Array.Clear(_memoryBlock, 0, _count);
}
@@ -67,7 +67,7 @@ namespace Recyclable.Collections
public void Reset()
{
if (NeedsClearing)
if (_needsClearing)
{
_current = _default;
}
@@ -78,7 +78,7 @@ namespace Recyclable.Collections
public void Dispose()
{
if (NeedsClearing)
if (_needsClearing)
{
_current = _default;
}
@@ -196,7 +196,7 @@ namespace Recyclable.Collections
// We can now return the old memory block for all arrays itself
if (sourceBlockCount >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T[]>.ReturnShared(list._memoryBlocks!, NeedsClearing);
RecyclableArrayPool<T[]>.ReturnShared(list._memoryBlocks!, _needsClearing);
}
}
@@ -86,7 +86,7 @@ namespace Recyclable.Collections
throw new InvalidOperationException();
}
if (NeedsClearing)
if (_needsClearing)
{
_current = _default;
}
@@ -97,7 +97,7 @@ namespace Recyclable.Collections
public void Dispose()
{
if (NeedsClearing)
if (_needsClearing)
{
_current = _default;
}
+29 -29
View File
@@ -10,23 +10,32 @@ namespace Recyclable.Collections
{
public partial class RecyclableLongList<T> : IList<T>, IReadOnlyList<T>, IDisposable
{
#pragma warning disable CA1825
private static readonly T[][] _emptyMemoryBlocksArray = new T[0][];
private static readonly T[] _emptyBlockArray = new T[0];
#pragma warning restore CA1825
private static readonly bool _defaultIsNull = default(T) == null;
private static readonly bool NeedsClearing = !typeof(T).IsValueType;
private static readonly bool _needsClearing = !typeof(T).IsValueType;
internal int _blockSize;
internal byte _blockSizePow2BitShift;
internal int _blockSizeMinus1;
internal int _nextItemBlockIndex;
internal int _nextItemIndex;
private int _reservedBlockCount;
internal long _capacity;
internal int _lastBlockWithData = RecyclableDefaults.ItemNotFoundIndex;
internal long _longCount;
#nullable disable
internal T[][] _memoryBlocks;
#nullable restore
internal int _nextItemBlockIndex;
internal int _nextItemIndex;
#pragma warning disable IDE0032
internal int _reservedBlockCount;
#pragma warning restore IDE0032
internal ulong _version;
private long _capacity;
public int BlockSize => _blockSize;
public int BlockSizeMinus1 => _blockSizeMinus1;
public byte BlockSizePow2BitShift => _blockSizePow2BitShift;
public long Capacity
{
get => _capacity;
@@ -44,20 +53,11 @@ namespace Recyclable.Collections
public int Count => checked((int)_longCount);
public bool IsReadOnly => false;
internal int _lastBlockWithData = RecyclableDefaults.ItemNotFoundIndex;
public int LastBlockWithData => _lastBlockWithData;
internal long _longCount;
public long LongCount => _longCount;
public int ReservedBlockCount => _reservedBlockCount;
public int BlockSize => _blockSize;
public int BlockSizeMinus1 => _blockSizeMinus1;
public byte BlockSizePow2BitShift => _blockSizePow2BitShift;
public int NextItemBlockIndex => _nextItemBlockIndex;
public int NextItemIndex => _nextItemIndex;
internal ulong _version;
public int ReservedBlockCount => _reservedBlockCount;
public ulong Version => _version;
private void AddRangeEnumerated(IEnumerable<T> source, int growByCount)
@@ -74,7 +74,7 @@ namespace Recyclable.Collections
long capacity = _capacity;
long available = capacity - copied;
Span<T[]> memoryBlocksSpan = new(_memoryBlocks, 0, ReservedBlockCount);
Span<T[]> memoryBlocksSpan = new(_memoryBlocks, 0, _reservedBlockCount);
Span<T> blockArraySpan;
var memoryBlocksCount = memoryBlocksSpan.Length;
while (true)
@@ -155,7 +155,7 @@ namespace Recyclable.Collections
blockSize = _blockSize;
}
var memoryBlocksCount = ReservedBlockCount;
var memoryBlocksCount = _reservedBlockCount;
memoryBlocksSpan = new(_memoryBlocks, 0, memoryBlocksCount);
blockArraySpan = new(memoryBlocksSpan[targetBlockIdx], 0, blockSize);
foreach (var item in source)
@@ -440,12 +440,12 @@ namespace Recyclable.Collections
public void AddRange(RecyclableList<T> items)
{
if (items.Count == 0)
if (items._count == 0)
{
return;
}
long targetCapacity = _longCount + items.Count;
long targetCapacity = _longCount + items._count;
if (_capacity < targetCapacity)
{
_capacity = Helpers.Resize(this, _blockSize, _blockSizePow2BitShift, checked((long)BitOperations.RoundUpToPowerOf2((ulong)targetCapacity)));
@@ -455,7 +455,7 @@ namespace Recyclable.Collections
targetBlockIndex = _nextItemBlockIndex,
memoryBlockCount = _reservedBlockCount;
Span<T> itemsSpan = new(items.AsArray, 0, items.Count);
Span<T> itemsSpan = new(items._memoryBlock, 0, items._count);
Span<T[]> memoryBlocksSpan = new(_memoryBlocks, 0, memoryBlockCount);
Span<T> targetBlockArraySpan = new(memoryBlocksSpan[targetBlockIndex], _nextItemIndex, blockSize - _nextItemIndex);
while (targetBlockArraySpan.Length <= itemsSpan.Length)
@@ -529,12 +529,12 @@ namespace Recyclable.Collections
public void AddRange(RecyclableLongList<T> items)
{
if (items.LongCount == 0)
if (items._longCount == 0)
{
return;
}
long itemsCount = items.LongCount,
long itemsCount = items._longCount,
targetCapacity = _longCount + itemsCount;
if (_capacity < targetCapacity)
@@ -698,7 +698,7 @@ namespace Recyclable.Collections
{
if (items.Count >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T>.ReturnShared(itemsBuffer, NeedsClearing);
RecyclableArrayPool<T>.ReturnShared(itemsBuffer, _needsClearing);
}
_version++;
@@ -753,7 +753,7 @@ namespace Recyclable.Collections
int toRemoveIdx = 0;
while (toRemoveIdx < memoryBlocksCount)
{
RecyclableArrayPool<T>.ReturnShared(memoryBlocks[toRemoveIdx++], NeedsClearing);
RecyclableArrayPool<T>.ReturnShared(memoryBlocks[toRemoveIdx++], _needsClearing);
}
}
@@ -970,7 +970,7 @@ namespace Recyclable.Collections
_lastBlockWithData--;
}
if (NeedsClearing)
if (_needsClearing)
{
#nullable disable
new Span<T>(_memoryBlocks[_nextItemBlockIndex])[_nextItemIndex] = default;
@@ -988,7 +988,7 @@ namespace Recyclable.Collections
{
if (_blockSize >= RecyclableDefaults.MinPooledArrayLength)
{
RecyclableArrayPool<T>.ReturnShared(_memoryBlocks[index], NeedsClearing);
RecyclableArrayPool<T>.ReturnShared(_memoryBlocks[index], _needsClearing);
_memoryBlocks[index] = _emptyBlockArray;
}
else
@@ -1038,7 +1038,7 @@ namespace Recyclable.Collections
_lastBlockWithData--;
}
if (NeedsClearing)
if (_needsClearing)
{
#nullable disable
new Span<T>(_memoryBlocks[_nextItemBlockIndex])[_nextItemIndex] = default;
@@ -1076,7 +1076,7 @@ namespace Recyclable.Collections
_lastBlockWithData--;
}
if (NeedsClearing)
if (_needsClearing)
{
#nullable disable
new Span<T>(_memoryBlocks[_nextItemBlockIndex])[_nextItemIndex] = default;
@@ -89,7 +89,7 @@ namespace Recyclable.CollectionsTests
}
// Validate
_ = list.Capacity.Should().Be(4);
_ = list.Capacity.Should().Be(RecyclableDefaults.InitialCapacity);
_ = list.Count.Should().Be(0);
_ = list.Should().BeEmpty();
}
@@ -138,7 +138,7 @@ namespace Recyclable.CollectionsTests
}
// Validate
var expectedData = testData.Concat(testData).ToRecyclableLongList();
using var expectedData = testData.Concat(testData).ToRecyclableLongList();
if (itemsCount > 0)
{