RecyclableList.AddRange(IEnumerable<T> source) fixed to properly add items when we can get non-enumerated count.
This commit is contained in:
1 parent
1ea0af8d34
commit
91fae49bdb
1 file changed
+9
-11
@@ -525,42 +525,40 @@ namespace Recyclable.Collections
|
|||||||
long capacity = _capacity;
|
long capacity = _capacity;
|
||||||
long oldLongCount = _longCount;
|
long oldLongCount = _longCount;
|
||||||
int blockSize = _blockSize;
|
int blockSize = _blockSize;
|
||||||
int targetItemIdx = (int)(oldLongCount % blockSize);
|
int targetItemIdx = _nextItemIndex;
|
||||||
int targetBlockIdx = (targetItemIdx / blockSize) + (targetItemIdx > 0 ? 1 : 0);
|
int targetBlockIdx = _lastBlockIndex;
|
||||||
|
|
||||||
Span<T[]> memoryBlocksSpan;
|
Span<T[]> memoryBlocksSpan;
|
||||||
Span<T> blockArraySpan;
|
Span<T> blockArraySpan;
|
||||||
if (source.TryGetNonEnumeratedCount(out var requiredAdditionalCapacity))
|
if (source.TryGetNonEnumeratedCount(out var requiredAdditionalCapacity))
|
||||||
{
|
{
|
||||||
int requiredCapacity = targetItemIdx + requiredAdditionalCapacity;
|
long requiredCapacity = oldLongCount + requiredAdditionalCapacity;
|
||||||
if (capacity < requiredCapacity)
|
if (capacity < requiredCapacity)
|
||||||
{
|
{
|
||||||
_ = EnsureCapacity(requiredCapacity);
|
_ = EnsureCapacity(requiredCapacity);
|
||||||
blockSize = _blockSize;
|
blockSize = _blockSize;
|
||||||
targetBlockIdx = (targetItemIdx / blockSize) + (targetItemIdx > 0 ? 1 : 0);
|
|
||||||
targetItemIdx = (int)(oldLongCount % blockSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memoryBlocksSpan = new(_memoryBlocks);
|
var memoryBlocksCount = _memoryBlocks.Length;
|
||||||
var memoryBlocksCount = memoryBlocksSpan.Length;
|
memoryBlocksSpan = new(_memoryBlocks, 0, memoryBlocksCount);
|
||||||
blockArraySpan = new Span<T>(memoryBlocksSpan[targetBlockIdx]);
|
blockArraySpan = new Span<T>(memoryBlocksSpan[targetBlockIdx], 0, blockSize);
|
||||||
foreach (var item in source)
|
foreach (var item in source)
|
||||||
{
|
{
|
||||||
blockArraySpan[targetItemIdx++] = item;
|
blockArraySpan[targetItemIdx++] = item;
|
||||||
if (targetItemIdx == blockSize)
|
if (targetItemIdx == blockSize)
|
||||||
{
|
{
|
||||||
targetBlockIdx++;
|
targetBlockIdx++;
|
||||||
|
targetItemIdx = 0;
|
||||||
if (targetBlockIdx == memoryBlocksCount)
|
if (targetBlockIdx == memoryBlocksCount)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetItemIdx = 0;
|
blockArraySpan = new Span<T>(memoryBlocksSpan[targetBlockIdx], 0, blockSize);
|
||||||
blockArraySpan = new Span<T>(memoryBlocksSpan[targetBlockIdx]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_longCount = (targetBlockIdx * blockSize) + targetItemIdx;
|
_longCount = requiredCapacity;
|
||||||
_lastBlockIndex = targetBlockIdx;
|
_lastBlockIndex = targetBlockIdx;
|
||||||
_nextItemIndex = targetItemIdx;
|
_nextItemIndex = targetItemIdx;
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in new issue
Block a user