RecyclableLongList.Compatibility.List.Find(), .FindLast(), .ForEach() & .GetRange() implemented. Bug fixes.
This commit is contained in:
1 parent
c8c1b5dea2
commit
4ddd57eaf4
2 files changed
+198
-60
No files matched your search
+79
-31
@@ -63,24 +63,58 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public static T? Find<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
public static T? Find<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
||||||
{
|
{
|
||||||
//int sourceItemsCount = list._count;
|
if (list._longCount == 0)
|
||||||
//if (sourceItemsCount == 0)
|
{
|
||||||
//{
|
return default;
|
||||||
// return default;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
int blockIndex = 0,
|
||||||
//for (var itemIndex = 0; itemIndex < sourceItemsCount; itemIndex++)
|
blockSize = list._blockSize,
|
||||||
//{
|
itemIndex = 0,
|
||||||
// if (match(sourceSpan[itemIndex]))
|
lastBlockWithData = list._lastBlockWithData;
|
||||||
// {
|
|
||||||
// return sourceSpan[itemIndex];
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return default;
|
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
||||||
|
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
|
||||||
|
while (blockIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
if (match(sourceMemoryBlockSpan[itemIndex]))
|
||||||
|
{
|
||||||
|
return sourceMemoryBlockSpan[itemIndex];
|
||||||
|
}
|
||||||
|
|
||||||
throw new NotImplementedException();
|
if (itemIndex + 1 == blockSize)
|
||||||
|
{
|
||||||
|
itemIndex = 0;
|
||||||
|
blockIndex++;
|
||||||
|
sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
// We're re-using another variable for better performance
|
||||||
|
lastBlockWithData = list._nextItemIndex > 0 ? list._nextItemIndex : blockSize;
|
||||||
|
while (itemIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
if (match(sourceMemoryBlockSpan[itemIndex]))
|
||||||
|
{
|
||||||
|
return sourceMemoryBlockSpan[itemIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
itemIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecyclableLongList<T> FindAll<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
public static RecyclableLongList<T> FindAll<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
||||||
@@ -317,7 +351,7 @@ namespace Recyclable.Collections
|
|||||||
lastBlockWithData = (startIndex + count) >> list._blockSizePow2BitShift;
|
lastBlockWithData = (startIndex + count) >> list._blockSizePow2BitShift;
|
||||||
|
|
||||||
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
||||||
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
|
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
|
||||||
while (blockIndex < lastBlockWithData)
|
while (blockIndex < lastBlockWithData)
|
||||||
{
|
{
|
||||||
if (match(sourceMemoryBlockSpan[itemIndex]))
|
if (match(sourceMemoryBlockSpan[itemIndex]))
|
||||||
@@ -374,7 +408,7 @@ namespace Recyclable.Collections
|
|||||||
lastBlockWithData = list._lastBlockWithData;
|
lastBlockWithData = list._lastBlockWithData;
|
||||||
|
|
||||||
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
||||||
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
|
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
|
||||||
while (blockIndex < lastBlockWithData)
|
while (blockIndex < lastBlockWithData)
|
||||||
{
|
{
|
||||||
if (match(sourceMemoryBlockSpan[itemIndex]))
|
if (match(sourceMemoryBlockSpan[itemIndex]))
|
||||||
@@ -474,23 +508,37 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public static T? FindLast<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
public static T? FindLast<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
||||||
{
|
{
|
||||||
//if (list._count == 0)
|
if (list._longCount == 0)
|
||||||
//{
|
{
|
||||||
// return default;
|
return default;
|
||||||
//}
|
}
|
||||||
|
|
||||||
//ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
int blockSizeMinus1 = list._blockSizeMinus1,
|
||||||
//for (var itemIndex = list._count - 1; itemIndex >= 0; itemIndex--)
|
itemIndex;
|
||||||
//{
|
|
||||||
// if (match(sourceSpan[itemIndex]))
|
|
||||||
// {
|
|
||||||
// return sourceSpan[itemIndex];
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return default;
|
ReadOnlySpan<T[]> memoryBlocksSpan = new(list._memoryBlocks);
|
||||||
|
ReadOnlySpan<T> sourceSpan = memoryBlocksSpan[list._lastBlockWithData];
|
||||||
|
for (itemIndex = list._nextItemIndex == 0 ? blockSizeMinus1 : list._nextItemIndex - 1; itemIndex >= 0; itemIndex--)
|
||||||
|
{
|
||||||
|
if (match(sourceSpan[itemIndex]))
|
||||||
|
{
|
||||||
|
return sourceSpan[itemIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new NotImplementedException();
|
for (var blockIndex = list._lastBlockWithData - 1; blockIndex >= 0; blockIndex--)
|
||||||
|
{
|
||||||
|
sourceSpan = memoryBlocksSpan[blockIndex];
|
||||||
|
for (itemIndex = blockSizeMinus1; itemIndex >= 0; itemIndex--)
|
||||||
|
{
|
||||||
|
if (match(sourceSpan[itemIndex]))
|
||||||
|
{
|
||||||
|
return sourceSpan[itemIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int FindLastIndex<T>(this RecyclableLongList<T> list, int startIndex, int count, Predicate<T> match)
|
public static int FindLastIndex<T>(this RecyclableLongList<T> list, int startIndex, int count, Predicate<T> match)
|
||||||
|
|||||||
+119
-29
@@ -334,43 +334,133 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public static void ForEach<T>(this RecyclableLongList<T> list, Action<T> action)
|
public static void ForEach<T>(this RecyclableLongList<T> list, Action<T> action)
|
||||||
{
|
{
|
||||||
//int sourceItemsCount = list._count;
|
if (list._longCount == 0)
|
||||||
//if (sourceItemsCount == 0)
|
{
|
||||||
//{
|
return;
|
||||||
// return;
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
int blockIndex = 0,
|
||||||
//for (var itemIndex = 0; itemIndex < sourceItemsCount; itemIndex++)
|
blockSize = list._blockSize,
|
||||||
//{
|
itemIndex = 0,
|
||||||
// action(sourceSpan[itemIndex]);
|
lastBlockWithData = list._lastBlockWithData;
|
||||||
//}
|
|
||||||
|
|
||||||
throw new NotImplementedException();
|
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
|
||||||
|
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
|
||||||
|
while (blockIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
action(sourceMemoryBlockSpan[itemIndex]);
|
||||||
|
if (itemIndex + 1 == blockSize)
|
||||||
|
{
|
||||||
|
itemIndex = 0;
|
||||||
|
blockIndex++;
|
||||||
|
sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
// We're re-using another variable for better performance
|
||||||
|
lastBlockWithData = list._nextItemIndex > 0 ? list._nextItemIndex : blockSize;
|
||||||
|
while (itemIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
action(sourceMemoryBlockSpan[itemIndex++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecyclableList<T> GetRange<T>(this RecyclableLongList<T> list, int index, int count)
|
public static RecyclableLongList<T> GetRange<T>(this RecyclableLongList<T> list, int startIndex, int count)
|
||||||
{
|
{
|
||||||
//int sourceItemsCount = index + count <= list._count ? count : list._count - index;
|
if (list._longCount == 0 || count == 0)
|
||||||
//if (sourceItemsCount <= 0)
|
{
|
||||||
//{
|
return new();
|
||||||
// return new();
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
//ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
int itemIndex = startIndex & list._blockSizeMinus1,
|
||||||
//RecyclableList<T> result = new(sourceItemsCount);
|
blockIndex = startIndex >> list._blockSizePow2BitShift,
|
||||||
//Span<T> targetSpan = result._memoryBlock;
|
blockSize = list._blockSize,
|
||||||
//int resultItemsCount = 0;
|
lastItemIndex = (startIndex + count) & list._blockSizeMinus1,
|
||||||
//sourceItemsCount += index;
|
lastBlockWithData = (startIndex + count) >> list._blockSizePow2BitShift,
|
||||||
//for (var itemIndex = index; itemIndex < sourceItemsCount; itemIndex++)
|
targetBlockIndex = 0,
|
||||||
//{
|
targetItemIndex = 0;
|
||||||
// targetSpan[resultItemsCount++] = sourceSpan[itemIndex];
|
|
||||||
//}
|
|
||||||
|
|
||||||
//result._count = resultItemsCount;
|
RecyclableLongList<T> result = new(minBlockSize: blockSize, initialCapacity: count);
|
||||||
//return result;
|
ReadOnlySpan<T[]> sourceMemoryBlocksSpan = new (list._memoryBlocks),
|
||||||
|
targetMemoryBlocksSpan = new (result._memoryBlocks);
|
||||||
|
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
|
||||||
|
Span<T> targetMemoryBlockSpan = new(targetMemoryBlocksSpan[0]);
|
||||||
|
while (blockIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
targetMemoryBlockSpan[targetItemIndex] = sourceMemoryBlockSpan[itemIndex];
|
||||||
|
|
||||||
throw new NotImplementedException();
|
if (targetItemIndex + 1 == blockSize)
|
||||||
|
{
|
||||||
|
targetItemIndex = 0;
|
||||||
|
targetBlockIndex++;
|
||||||
|
if (targetBlockIndex <= lastBlockWithData)
|
||||||
|
{
|
||||||
|
targetMemoryBlockSpan = new(targetMemoryBlocksSpan[targetBlockIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItemIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemIndex + 1 == blockSize)
|
||||||
|
{
|
||||||
|
itemIndex = 0;
|
||||||
|
blockIndex++;
|
||||||
|
sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockIndex == lastBlockWithData)
|
||||||
|
{
|
||||||
|
// We're re-using another variable for better performance
|
||||||
|
lastBlockWithData = lastItemIndex > 0 ? lastItemIndex : blockSize;
|
||||||
|
while (itemIndex < lastBlockWithData)
|
||||||
|
{
|
||||||
|
targetMemoryBlockSpan[targetItemIndex] = sourceMemoryBlockSpan[itemIndex];
|
||||||
|
itemIndex++;
|
||||||
|
if (targetItemIndex + 1 == blockSize)
|
||||||
|
{
|
||||||
|
targetItemIndex = 0;
|
||||||
|
targetBlockIndex++;
|
||||||
|
if (targetBlockIndex <= lastBlockWithData)
|
||||||
|
{
|
||||||
|
targetMemoryBlockSpan = new(targetMemoryBlocksSpan[targetBlockIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetItemIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result._lastBlockWithData = lastBlockWithData;
|
||||||
|
result._longCount = count;
|
||||||
|
result._nextItemIndex = count & list._blockSizeMinus1;
|
||||||
|
result._nextItemBlockIndex = targetBlockIndex;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int RemoveAll<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
public static int RemoveAll<T>(this RecyclableLongList<T> list, Predicate<T> match)
|
||||||
|
|||||||
Reference in new issue
Block a user