RecyclableLongList.Compatibility.List.FindIndex() implemented.

This commit is contained in:
mlemanczyk committed 2023-12-16 02:29:27 +01:00
1 parent 95d497c903
commit 1884e1c5b4
1 file changed
+148 -46
@@ -305,69 +305,171 @@ namespace Recyclable.Collections
public static int FindIndex<T>(this RecyclableLongList<T> list, int startIndex, int count, Predicate<T> match) public static int FindIndex<T>(this RecyclableLongList<T> list, int startIndex, int count, Predicate<T> match)
{ {
//int sourceItemsCount = Math.Min(startIndex + count, list._count); if (list._longCount == 0)
//if (sourceItemsCount == 0 || startIndex >= sourceItemsCount) {
//{ return RecyclableDefaults.ItemNotFoundIndex;
// return RecyclableDefaults.ItemNotFoundIndex; }
//}
//ReadOnlySpan<T> sourceSpan = list._memoryBlock; int itemIndex = startIndex & list._blockSizeMinus1,
//for (var itemIndex = startIndex; itemIndex < sourceItemsCount; itemIndex++) blockIndex = startIndex >> list._blockSizePow2BitShift,
//{ blockSize = list._blockSize,
// if (match(sourceSpan[itemIndex])) lastItemIndex = (startIndex + count) & list._blockSizeMinus1,
// { lastBlockWithData = (startIndex + count) >> list._blockSizePow2BitShift;
// return itemIndex;
// }
//}
//return RecyclableDefaults.ItemNotFoundIndex; ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
while (blockIndex < lastBlockWithData)
{
if (match(sourceMemoryBlockSpan[itemIndex]))
{
return (blockIndex << list._blockSizePow2BitShift) + 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 = lastItemIndex > 0 ? lastItemIndex : blockSize;
while (itemIndex < lastBlockWithData)
{
if (match(sourceMemoryBlockSpan[itemIndex]))
{
return (blockIndex << list._blockSizePow2BitShift) + itemIndex;
}
itemIndex++;
}
}
return RecyclableDefaults.ItemNotFoundIndex;
} }
public static int FindIndex<T>(this RecyclableLongList<T> list, int startIndex, Predicate<T> match) public static int FindIndex<T>(this RecyclableLongList<T> list, int startIndex, Predicate<T> match)
{ {
//int sourceItemsCount = list._count; if (list._longCount == 0)
//if (sourceItemsCount == 0 || startIndex >= sourceItemsCount) {
//{ return RecyclableDefaults.ItemNotFoundIndex;
// return RecyclableDefaults.ItemNotFoundIndex; }
//}
//sourceItemsCount = Math.Min(sourceItemsCount, startIndex + sourceItemsCount); int itemIndex = startIndex & list._blockSizeMinus1,
//ReadOnlySpan<T> sourceSpan = list._memoryBlock; blockIndex = startIndex >> list._blockSizePow2BitShift,
//for (var itemIndex = startIndex; itemIndex < sourceItemsCount; itemIndex++) blockSize = list._blockSize,
//{ lastItemIndex = (int)(list._longCount & list._blockSizeMinus1),
// if (match(sourceSpan[itemIndex])) lastBlockWithData = list._lastBlockWithData;
// {
// return itemIndex;
// }
//}
//return RecyclableDefaults.ItemNotFoundIndex; ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
while (blockIndex < lastBlockWithData)
{
if (match(sourceMemoryBlockSpan[itemIndex]))
{
return (blockIndex << list._blockSizePow2BitShift) + 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 = lastItemIndex > 0 ? lastItemIndex : blockSize;
while (itemIndex < lastBlockWithData)
{
if (match(sourceMemoryBlockSpan[itemIndex]))
{
return (blockIndex << list._blockSizePow2BitShift) + itemIndex;
}
itemIndex++;
}
}
return RecyclableDefaults.ItemNotFoundIndex;
} }
public static int FindIndex<T>(this RecyclableLongList<T> list, Predicate<T> match) public static int FindIndex<T>(this RecyclableLongList<T> list, Predicate<T> match)
{ {
//int sourceItemsCount = list._count; if (list._longCount == 0)
//if (sourceItemsCount == 0) {
//{ return RecyclableDefaults.ItemNotFoundIndex;
// return RecyclableDefaults.ItemNotFoundIndex; }
//}
//ReadOnlySpan<T> sourceSpan = list._memoryBlock; int blockIndex = 0,
//for (var itemIndex = 0; itemIndex < sourceItemsCount; itemIndex++) blockSize = list._blockSize;
//{ ReadOnlySpan<T[]> sourceMemoryBlocksSpan = list._memoryBlocks;
// if (match(sourceSpan[itemIndex])) ReadOnlySpan<T> sourceMemoryBlockSpan = sourceMemoryBlocksSpan[0];
// { var itemIndex = 0;
// return itemIndex; int lastBlockWithData = list._lastBlockWithData;
// } while (blockIndex < lastBlockWithData)
//} {
if (match(sourceMemoryBlockSpan[itemIndex]))
{
return (blockIndex << list._blockSizePow2BitShift) + itemIndex;
}
//return RecyclableDefaults.ItemNotFoundIndex; if (itemIndex + 1 == blockSize)
{
itemIndex = 0;
blockIndex++;
sourceMemoryBlockSpan = sourceMemoryBlocksSpan[blockIndex];
throw new NotImplementedException(); 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 (blockIndex << list._blockSizePow2BitShift) + itemIndex;
}
itemIndex++;
}
}
return RecyclableDefaults.ItemNotFoundIndex;
} }
public static T? FindLast<T>(this RecyclableLongList<T> list, Predicate<T> match) public static T? FindLast<T>(this RecyclableLongList<T> list, Predicate<T> match)