RecyclableList<T> and RecyclableLongList<T> implemented. Merge from recyclable-block-list-added branch.
This commit is contained in:
1 parent
aba28028b1
commit
12083c4682
12 files changed
+414
-8
No files matched your search
@@ -0,0 +1,73 @@
|
||||
using System.Reflection;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
|
||||
namespace Recyclable.Collections.Benchmarks
|
||||
{
|
||||
public enum RecyclableCollectionsBenchmarkType
|
||||
{
|
||||
Add_WithCapacity, Add, AddRange_WithCapacity, AddRangeWhenSourceIsArray, AddRangeWhenSourceIsIEnumerable,
|
||||
AddRangeWhenSourceIsIList, AddRangeWhenSourceIsList, AddRangeWhenSourceIsSameType, Contains_FirstItems,
|
||||
Contains_LastItems, Count, Create_WithCapacity, Create, GetItem, IndexOf_BestAndWorstCases, IndexOf_FirstItems,
|
||||
IndexOf_LastItems, LongCount, Remove_FirstItems, Remove_LastItems, RemoveAt_FirstItems, RemoveAt_LastItems,
|
||||
SetItem,
|
||||
}
|
||||
|
||||
public partial class RecyclableCollectionsBenchmarks : RecyclableBenchmarkBase<RecyclableCollectionsBenchmarkSource>
|
||||
{
|
||||
public RecyclableCollectionsBenchmarks() : base()
|
||||
{
|
||||
TestObjectCount = 1;
|
||||
// BaselineBenchmarkType = RecyclableCollectionsBenchmarkSource.PooledList;
|
||||
BenchmarkType = RecyclableCollectionsBenchmarkSource.RecyclableLongList;
|
||||
}
|
||||
|
||||
[Params
|
||||
(
|
||||
//RecyclableCollectionsBenchmarkType.Add_WithCapacity,
|
||||
//RecyclableCollectionsBenchmarkType.Add,
|
||||
//RecyclableCollectionsBenchmarkType.AddRange_WithCapacity,
|
||||
//RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsArray,
|
||||
//RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsIEnumerable,
|
||||
//RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsIList,
|
||||
//RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsList,
|
||||
//RecyclableCollectionsBenchmarkType.AddRangeWhenSourceIsSameType,
|
||||
//RecyclableCollectionsBenchmarkType.Contains_FirstItems,
|
||||
//RecyclableCollectionsBenchmarkType.Contains_LastItems,
|
||||
//RecyclableCollectionsBenchmarkType.Count,
|
||||
//RecyclableCollectionsBenchmarkType.Create_WithCapacity,
|
||||
//RecyclableCollectionsBenchmarkType.Create,
|
||||
//RecyclableCollectionsBenchmarkType.GetItem,
|
||||
RecyclableCollectionsBenchmarkType.IndexOf_BestAndWorstCases
|
||||
//RecyclableCollectionsBenchmarkType.IndexOf_FirstItems,
|
||||
//RecyclableCollectionsBenchmarkType.IndexOf_LastItems
|
||||
//RecyclableCollectionsBenchmarkType.LongCount,
|
||||
//RecyclableCollectionsBenchmarkType.Remove_FirstItems,
|
||||
//RecyclableCollectionsBenchmarkType.Remove_LastItems,
|
||||
//RecyclableCollectionsBenchmarkType.RemoveAt_FirstItems,
|
||||
//RecyclableCollectionsBenchmarkType.RemoveAt_LastItems,
|
||||
//RecyclableCollectionsBenchmarkType.SetItem
|
||||
)]
|
||||
|
||||
public RecyclableCollectionsBenchmarkType TestCase { get; set; } = RecyclableCollectionsBenchmarkType.IndexOf_BestAndWorstCases;
|
||||
|
||||
[Params
|
||||
(
|
||||
RecyclableCollectionsBenchmarkSource.List
|
||||
)]
|
||||
public override RecyclableCollectionsBenchmarkSource BaselineBenchmarkType { get => base.BaselineBenchmarkType; set => base.BaselineBenchmarkType = value; }
|
||||
|
||||
[Params
|
||||
(
|
||||
//RecyclableCollectionsBenchmarkSource.Array,
|
||||
//RecyclableCollectionsBenchmarkSource.List,
|
||||
//RecyclableCollectionsBenchmarkSource.PooledList
|
||||
//RecyclableCollectionsBenchmarkSource.RecyclableList,
|
||||
RecyclableCollectionsBenchmarkSource.RecyclableLongList
|
||||
)]
|
||||
public override RecyclableCollectionsBenchmarkSource BenchmarkType { get => base.BenchmarkType; set => base.BenchmarkType = value; }
|
||||
|
||||
protected override Action? GetTestMethod(RecyclableCollectionsBenchmarkSource benchmarkType)
|
||||
=> (Action?) GetType().GetMethod($"{benchmarkType}_{TestCase}", BindingFlags.Instance | BindingFlags.Public)?.CreateDelegate(typeof(Action), this)
|
||||
?? throw CreateMethodNotFoundException($"{benchmarkType}_{TestCase}", GetType().FullName);
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,55 @@ using Recyclable.Collections.Benchmarks;
|
||||
BenchmarkRunner.Run<ListVsLinkedListBenchmark>();
|
||||
//BenchmarkRunner.Run<DelegateVsComparerBenchmark>();
|
||||
|
||||
//var tests = new ListVsLinkedListBenchmark();
|
||||
//tests.RecyclableList();
|
||||
static void RunAssemblyBenchmarks()
|
||||
{
|
||||
_ = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(new[] { "-f*" });
|
||||
}
|
||||
|
||||
private static void RunRecyclableCollectionsBenchmarks()
|
||||
{
|
||||
_ = BenchmarkRunner.Run<RecyclableCollectionsBenchmarks>(BenchmarkConfig);
|
||||
}
|
||||
|
||||
static void RunSelectedBenchmarks()
|
||||
{
|
||||
// ****************
|
||||
// *** Template ***
|
||||
// ****************
|
||||
var benchmark = new RecyclableCollectionsBenchmarks();
|
||||
benchmark.Setup();
|
||||
benchmark.RecyclableLongList_IndexOf_BestAndWorstCases();
|
||||
benchmark.Cleanup();
|
||||
|
||||
//foreach (var _ in Enumerable.Range(1, 1000))
|
||||
//{
|
||||
// benchmark.RecyclableLongList_Remove_FirstItems();
|
||||
// benchmark.RecyclableLongList_RemoveAt_LastItems();
|
||||
// benchmark.List_RemoveAt_LastItems();
|
||||
//}
|
||||
|
||||
//benchmark.Cleanup();
|
||||
}
|
||||
|
||||
static void RunPocBenchmarks()
|
||||
{
|
||||
//_ = BenchmarkRunner.Run<BoolOrComparePocBenchmarks>(BenchmarkConfig);
|
||||
//_ = BenchmarkRunner.Run<DelegateVsComparerPocBenchmarks>(BenchmarkConfig);
|
||||
//_ = BenchmarkRunner.Run<ModuloPocBenchmarks>(BenchmarkConfig);
|
||||
// _ = BenchmarkRunner.Run<RecyclableLongListPocBenchmarks>(BenchmarkConfig);
|
||||
_ = BenchmarkRunner.Run<TaskRunVsTaskFactoryStartNewBenchmarks>(BenchmarkConfig);
|
||||
//_ = BenchmarkRunner.Run<RefVsInstanceMemberPocBenchmarks>(BenchmarkConfig);
|
||||
//_ = BenchmarkRunner.Run<WhenParallelSearchBenchmarks>(BenchmarkConfig);
|
||||
//_ = BenchmarkRunner.Run<RoundBenchmarks>(BenchmarkConfig);
|
||||
// _ = BenchmarkRunner.Run<SpanVsArrayBenchmarks>(BenchmarkConfig);
|
||||
// ArraySizeLimitPocBenchmarks>(BenchmarkConfig);
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
RunRecyclableCollectionsBenchmarks();
|
||||
// RunPocBenchmarks();
|
||||
// RunSelectedBenchmarks();
|
||||
// RunAssemblyBenchmarks();
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,8 @@ Global
|
||||
{CDC0CF78-FC11-43E3-9059-3261DA3639D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CDC0CF78-FC11-43E3-9059-3261DA3639D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CDC0CF78-FC11-43E3-9059-3261DA3639D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CDC0CF78-FC11-43E3-9059-3261DA3639D1}.Release|x64.ActiveCfg = Release|x64
|
||||
{CDC0CF78-FC11-43E3-9059-3261DA3639D1}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
public interface IRandomNumberGenerator
|
||||
internal interface IRandomNumberGenerator
|
||||
{
|
||||
int NextInt32(int startIndex, int endIndex);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
public interface IRecyclableOwner<T> : IList<T>
|
||||
internal interface IRecyclableOwner<T> : IList<T>
|
||||
{
|
||||
T this[long index] { get; set; }
|
||||
int BlockSize { get; }
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Recyclable.Collections
|
||||
{
|
||||
// The source code was taken from https://codereview.stackexchange.com/questions/205407/quicksort-without-recursion.
|
||||
// It was only beautified for .Net 6.0+.
|
||||
public static class ListExtensions
|
||||
internal static class ListExtensions
|
||||
{
|
||||
public static void InsertionSort<T>(this IList<T> values, int startIndex, int endIndex, IComparer<T> comparer)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal static class MathUtils
|
||||
{
|
||||
// private static readonly long[] Pow2 = new long[]
|
||||
// {
|
||||
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
|
||||
// 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
|
||||
// 8388608, 16777216, 33554432, 67108864, 134217728, 268435456,
|
||||
// 536870912, 1073741824, 2147483648
|
||||
// };
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsPow2(long value) => (value != 0) && ((value & (value - 1)) == 0);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int GetPow2Shift(long value) => BitOperations.IsPow2(value) ? 63 - BitOperations.LeadingZeroCount((ulong)value) : -1;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long DivMod(long number, int divider, out long remainder)
|
||||
{
|
||||
if (number >= divider << 4)
|
||||
{
|
||||
return Math.DivRem(number, divider, out remainder);
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = 0;
|
||||
remainder = number;
|
||||
while (remainder >= divider)
|
||||
{
|
||||
remainder -= divider;
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal class MemoryBucket<T>
|
||||
{
|
||||
public MemoryBucket(T[] memory, MemoryBucket<T> nextBucket)
|
||||
{
|
||||
_memory = memory;
|
||||
_nextBucket = nextBucket;
|
||||
}
|
||||
|
||||
public MemoryBucket(T[] memory)
|
||||
{
|
||||
_memory = memory;
|
||||
}
|
||||
|
||||
private T[] _memory;
|
||||
public T[] Memory { get => _memory; set => _memory = value; }
|
||||
|
||||
private MemoryBucket<T>? _nextBucket;
|
||||
public MemoryBucket<T>? NextBucket { get => _nextBucket; set => _nextBucket = value; }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageId>Recyclable.Collections</PackageId>
|
||||
<PackageVersion>0.0.2</PackageVersion>
|
||||
<PackageVersion>0.0.3.2-alpha</PackageVersion>
|
||||
<Authors>Marek Lemańczyk</Authors>
|
||||
<Company>N/A</Company>
|
||||
<Product>Recyclable.Collections</Product>
|
||||
@@ -19,7 +19,8 @@
|
||||
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<PackageReleaseNotes>RecyclableSortedList added. Minor improvements & cleanups.</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>Several classes made internal to avoid conflicts with other packages. Not ready classes made internal for now.</PackageReleaseNotes>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal static class RecyclableLongListExtensions
|
||||
{
|
||||
private const int _minPooledArraySize = RecyclableDefaults.MinPooledArrayLength;
|
||||
private const long ItemNotFoundIndexLong = -1L;
|
||||
private const int ItemNotFoundIndex = -1;
|
||||
|
||||
public static void CopyItems<T>(this T[] memory, long startingIndex, long count, ref T[] destArray, long offset = 1)
|
||||
{
|
||||
for (long destItemIndex = startingIndex, sourceItemIndex = offset; destItemIndex < startingIndex + count; destItemIndex++, sourceItemIndex++)
|
||||
{
|
||||
destArray[destItemIndex] = memory[sourceItemIndex];
|
||||
}
|
||||
}
|
||||
|
||||
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> destinationArrayMemory;
|
||||
int startingBlockIndex = (int)(startingIndex / blockSize);
|
||||
int lastBlockIndex = (int)((itemsCount / blockSize) + (itemsCount % blockSize > 0 ? 1 : 0)) - 1;
|
||||
Span<T[]> sourceMemoryBlocksSpan = new(sourceMemoryBlocks, startingBlockIndex, lastBlockIndex + 1);
|
||||
destinationArrayMemory = new Span<T>(destinationArray, destinationArrayIndex, (int)Math.Min(destinationArray.Length - destinationArrayIndex, itemsCount));
|
||||
int memoryBlockIndex;
|
||||
for (memoryBlockIndex = 0; memoryBlockIndex < lastBlockIndex; memoryBlockIndex++)
|
||||
{
|
||||
sourceBlockMemory = new(sourceMemoryBlocksSpan[memoryBlockIndex], 0, blockSize);
|
||||
sourceBlockMemory.CopyTo(destinationArrayMemory);
|
||||
destinationArrayMemory = destinationArrayMemory[blockSize..];
|
||||
}
|
||||
|
||||
if (itemsCount - (lastBlockIndex * blockSize) > 0)
|
||||
{
|
||||
sourceBlockMemory = new(sourceMemoryBlocksSpan[lastBlockIndex], 0, (int)(itemsCount - (lastBlockIndex * blockSize)));
|
||||
sourceBlockMemory.CopyTo(destinationArrayMemory);
|
||||
}
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
//public static bool Contains<T>(this RecyclableLongList<T[]> arrays, T item) => arrays.Any(x => x.Contains(item));
|
||||
|
||||
public static IEnumerable<T> Enumerate<T>(this T[][] arrays, int chunkSize, long totalCount)
|
||||
{
|
||||
long currentCount = 0;
|
||||
for (var arrayIdx = 0; arrayIdx < arrays.Length && currentCount < totalCount; arrayIdx++)
|
||||
{
|
||||
var array = arrays[arrayIdx];
|
||||
currentCount += chunkSize;
|
||||
switch (currentCount < totalCount)
|
||||
{
|
||||
case true:
|
||||
for (var valueIdx = 0; valueIdx < chunkSize; valueIdx++)
|
||||
{
|
||||
yield return array[valueIdx];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case false:
|
||||
var partialCount = (int)(totalCount % chunkSize);
|
||||
int maxCount = partialCount > 0 ? partialCount : chunkSize;
|
||||
for (var valueIdx = 0; valueIdx < maxCount; valueIdx++)
|
||||
{
|
||||
yield return array[valueIdx];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
//public static T LimitTo<T>(this T value, T maxValue, IComparer<T> comparer)
|
||||
// => comparer.Compare(value, maxValue) > 0 ? maxValue : value;
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long LongIndexOf<T>(this RecyclableLongList<T> arrays, long itemsCount, T itemToFind, IEqualityComparer<T> comparer)
|
||||
{
|
||||
for (var itemIdx = 0L; itemIdx < itemsCount; itemIdx++)
|
||||
{
|
||||
var item = arrays[itemIdx];
|
||||
if (comparer.Equals(itemToFind, item))
|
||||
{
|
||||
return itemIdx;
|
||||
}
|
||||
|
||||
itemIdx++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static long LongIndexOf<T>(this T[][] arrays, long itemsCount, T itemToFind, IEqualityComparer<T> comparer)
|
||||
{
|
||||
var arraysSpan = new Span<T[]>(arrays);
|
||||
var arraysCount = arraysSpan.Length;
|
||||
for (int arrayIdx = 0, scannedCount = 0; arrayIdx < arraysCount; arrayIdx++)
|
||||
{
|
||||
var itemsSpan = new Span<T>(arraysSpan[arrayIdx]);
|
||||
var arrayItemsCount = itemsSpan.Length;
|
||||
for (var itemIdx = 0; itemIdx < arrayItemsCount; itemIdx++)
|
||||
{
|
||||
if (comparer.Equals(itemToFind, itemsSpan[itemIdx]))
|
||||
{
|
||||
return scannedCount;
|
||||
}
|
||||
|
||||
scannedCount++;
|
||||
if (scannedCount == itemsCount)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableLongList<T> ToRecyclableLongList<T>(this IList<T> values, int blockSize = RecyclableDefaults.BlockSize) => new(values, blockSize);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableLongList<T> ToRecyclableLongList<T>(this List<T> values, int blockSize = RecyclableDefaults.BlockSize) => new(values, blockSize);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableList<T> ToRecyclableList<T>(this IEnumerable<T> values) => new(values);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableList<T> ToRecyclableList<T>(this T[] values) => new(values);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableList<T> ToRecyclableList<T>(this List<T> values) => new(values);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableList<T> ToRecyclableList<T>(this RecyclableList<T> values) => new(values);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static RecyclableLongList<T> ToRecyclableLongList<T>(this IEnumerable<T> values, int minBlockSize = RecyclableDefaults.BlockSize) => new(values, minBlockSize: minBlockSize);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T[] RentArrayFromPool<T>(this int minSize, ArrayPool<T> arrayPool) => (minSize >= _minPooledArraySize)
|
||||
? arrayPool.Rent(minSize)
|
||||
: new T[minSize];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T[] RentArrayFromPool<T>(this long minSize, ArrayPool<T> arrayPool) => (minSize is >= _minPooledArraySize and <= int.MaxValue)
|
||||
? arrayPool.Rent((int)minSize)
|
||||
: new T[minSize];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ReturnToPool<T>(this T[] array, ArrayPool<T> arrayPool, bool needsClearing)
|
||||
{
|
||||
if (array.LongLength is > _minPooledArraySize and <= int.MaxValue)
|
||||
{
|
||||
arrayPool.Return(array, needsClearing);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long LimitTo(this long value, int limit)
|
||||
=> (value <= limit) ? value : limit;
|
||||
|
||||
public static int IndexOf<T>(this T[] memory, int itemCount, T? itemToFind, IEqualityComparer<T> equalityComparer)
|
||||
{
|
||||
for (var itemIdx = 0; itemIdx < itemCount; itemIdx++)
|
||||
{
|
||||
var item = memory[itemIdx];
|
||||
if (equalityComparer.Equals(item, itemToFind))
|
||||
{
|
||||
return itemIdx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal readonly struct SearchConfiguration<TList, TItem>
|
||||
{
|
||||
public TItem ItemToFind { get; init; }
|
||||
public TList List { get; init; }
|
||||
public int BlockSizeMinus1 { get; init; }
|
||||
public byte BlockSizePow2BitShift { get; init; }
|
||||
public long ItemsCount { get; init; }
|
||||
public int StartingBlockIndex { get; init; }
|
||||
public long BlockSize { get; init; }
|
||||
|
||||
// public SearchConfiguration(TList list, in TItem itemToFind)
|
||||
// {
|
||||
// ItemToFind = itemToFind;
|
||||
// List = list;
|
||||
// }
|
||||
|
||||
public static SearchConfiguration<RecyclableLongList<TItem>, TItem> CreateFrom(RecyclableLongList<TItem> list, in TItem itemToFind) => new()
|
||||
{
|
||||
List = list,
|
||||
ItemToFind = itemToFind,
|
||||
BlockSizeMinus1 = list._blockSizeMinus1,
|
||||
BlockSizePow2BitShift = list._blockSizePow2BitShift,
|
||||
ItemsCount = list._longCount,
|
||||
BlockSize = list._blockSize
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
public class SystemRandomNumberGenerator : IRandomNumberGenerator
|
||||
internal class SystemRandomNumberGenerator : IRandomNumberGenerator
|
||||
{
|
||||
private readonly Random _random = new();
|
||||
|
||||
|
||||
Reference in new issue
Block a user