RecyclableListExtensions.CopyTo fixed to not raise exceptions in some configurations.

This commit is contained in:
Marek Lemańczyk committed 2023-03-17 01:40:56 +01:00
1 parent cf284865e9
commit 5235ea12bc
1 file changed
+10 -5
@@ -17,12 +17,17 @@ namespace Recyclable.Collections
public static void CopyTo<T>(this T[][] sourceMemoryBlocks, long startingIndex, int blockSize, long itemsCount, T[] destinationArray, int destinationArrayIndex) public static void CopyTo<T>(this T[][] sourceMemoryBlocks, long startingIndex, int blockSize, long itemsCount, T[] destinationArray, int destinationArrayIndex)
{ {
if (itemsCount <= 0)
{
return;
}
Span<T> sourceBlockMemory; Span<T> sourceBlockMemory;
Span<T> destinationArrayMemory; Span<T> destinationArrayMemory;
int startingBlockIndex = (int)(startingIndex / blockSize); int startingBlockIndex = (int)(startingIndex / blockSize);
int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount - (itemsCount / blockSize) > 0 ? 1 : 0)) - 1; int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount % blockSize > 0 ? 1 : 0)) - 1;
Span<T[]> sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex - startingBlockIndex + 1); Span<T[]> sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex + 1);
destinationArrayMemory = new Span<T>(destinationArray, destinationArrayIndex, destinationArray.Length - destinationArrayIndex); destinationArrayMemory = new Span<T>(destinationArray, destinationArrayIndex, (int)Math.Min(destinationArray.Length - destinationArrayIndex, itemsCount));
int memoryBlockIndex; int memoryBlockIndex;
for (memoryBlockIndex = 0; memoryBlockIndex < lastBlockIndex; memoryBlockIndex++) for (memoryBlockIndex = 0; memoryBlockIndex < lastBlockIndex; memoryBlockIndex++)
{ {
@@ -31,9 +36,9 @@ namespace Recyclable.Collections
destinationArrayMemory = destinationArrayMemory[blockSize..]; destinationArrayMemory = destinationArrayMemory[blockSize..];
} }
if (itemsCount % blockSize > 0) if (itemsCount - (lastBlockIndex * blockSize) > 0)
{ {
sourceBlockMemory = new(sourceMemoryBlocksSpan[lastBlockIndex], 0, (int)(itemsCount % blockSize)); sourceBlockMemory = new(sourceMemoryBlocksSpan[lastBlockIndex], 0, (int)(itemsCount - (lastBlockIndex * blockSize)));
sourceBlockMemory.CopyTo(destinationArrayMemory); sourceBlockMemory.CopyTo(destinationArrayMemory);
} }
} }