From 91fae49bdb812f568bbe03fd846b684a71c1db90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Sat, 11 Mar 2023 23:15:04 +0100 Subject: [PATCH] RecyclableList.AddRange(IEnumerable source) fixed to properly add items when we can get non-enumerated count. --- Recyclable.Collections/RecyclableList.cs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Recyclable.Collections/RecyclableList.cs b/Recyclable.Collections/RecyclableList.cs index 754b83e..1451540 100644 --- a/Recyclable.Collections/RecyclableList.cs +++ b/Recyclable.Collections/RecyclableList.cs @@ -525,42 +525,40 @@ namespace Recyclable.Collections long capacity = _capacity; long oldLongCount = _longCount; int blockSize = _blockSize; - int targetItemIdx = (int)(oldLongCount % blockSize); - int targetBlockIdx = (targetItemIdx / blockSize) + (targetItemIdx > 0 ? 1 : 0); + int targetItemIdx = _nextItemIndex; + int targetBlockIdx = _lastBlockIndex; Span memoryBlocksSpan; Span blockArraySpan; if (source.TryGetNonEnumeratedCount(out var requiredAdditionalCapacity)) { - int requiredCapacity = targetItemIdx + requiredAdditionalCapacity; + long requiredCapacity = oldLongCount + requiredAdditionalCapacity; if (capacity < requiredCapacity) { _ = EnsureCapacity(requiredCapacity); blockSize = _blockSize; - targetBlockIdx = (targetItemIdx / blockSize) + (targetItemIdx > 0 ? 1 : 0); - targetItemIdx = (int)(oldLongCount % blockSize); } - memoryBlocksSpan = new(_memoryBlocks); - var memoryBlocksCount = memoryBlocksSpan.Length; - blockArraySpan = new Span(memoryBlocksSpan[targetBlockIdx]); + var memoryBlocksCount = _memoryBlocks.Length; + memoryBlocksSpan = new(_memoryBlocks, 0, memoryBlocksCount); + blockArraySpan = new Span(memoryBlocksSpan[targetBlockIdx], 0, blockSize); foreach (var item in source) { blockArraySpan[targetItemIdx++] = item; if (targetItemIdx == blockSize) - { + { targetBlockIdx++; + targetItemIdx = 0; if (targetBlockIdx == memoryBlocksCount) { break; } - targetItemIdx = 0; - blockArraySpan = new Span(memoryBlocksSpan[targetBlockIdx]); + blockArraySpan = new Span(memoryBlocksSpan[targetBlockIdx], 0, blockSize); } } - _longCount = (targetBlockIdx * blockSize) + targetItemIdx; + _longCount = requiredCapacity; _lastBlockIndex = targetBlockIdx; _nextItemIndex = targetItemIdx; return;