Collections.Benchmarks.Core package updated. Bug fixes. Logo added.
This commit is contained in:
1 parent
fd38907eaa
commit
4f0102438e
17 files changed
+346
-67
No files matched your search
+9
-7
@@ -1,10 +1,12 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public class BinarySearchBenchmarks<T> : CollectionsBenchmarksBase<T>
|
public class BinarySearchBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
public void Array_BinarySearch_BestAndWorstCases()
|
public override string MethodNameSuffix => "_BinarySearch";
|
||||||
|
|
||||||
|
public void Array_BinarySearch()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
var list = TestObjects;
|
var list = TestObjects;
|
||||||
@@ -16,7 +18,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void List_BinarySearch_BestAndWorstCases()
|
public void List_BinarySearch()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
var list = TestObjectsAsList;
|
var list = TestObjectsAsList;
|
||||||
@@ -28,7 +30,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PooledList_BinarySearch_BestAndWorstCases()
|
public void PooledList_BinarySearch()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
var list = TestObjectsAsPooledList;
|
var list = TestObjectsAsPooledList;
|
||||||
@@ -40,7 +42,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecyclableList_BinarySearch_BestAndWorstCases()
|
public void RecyclableList_BinarySearch()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
var list = TestObjectsAsRecyclableList;
|
var list = TestObjectsAsRecyclableList;
|
||||||
@@ -52,7 +54,7 @@ namespace Recyclable.Collections.Benchmarks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void RecyclableLongList_BinarySearch_BestAndWorstCases()
|
// public void RecyclableLongList_BinarySearch()
|
||||||
// {
|
// {
|
||||||
// var data = TestObjects;
|
// var data = TestObjects;
|
||||||
// var list = TestObjectsAsRecyclableLongList;
|
// var list = TestObjectsAsRecyclableLongList;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public class ConvertAllBenchmarks<T> : CollectionsBenchmarksBase<T>
|
public class ConvertAllBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_ConvertAll";
|
||||||
|
|
||||||
public void Array_ConvertAll()
|
public void Array_ConvertAll()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
public class ExistsBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_Exists_BestAndWorstCases";
|
||||||
|
|
||||||
public void Array_Exists_BestAndWorstCases()
|
public void Array_Exists_BestAndWorstCases()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
public class FindAllBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_FindAll_BestAndWorstCases";
|
||||||
|
|
||||||
public void Array_FindAll_BestAndWorstCases()
|
public void Array_FindAll_BestAndWorstCases()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
+4
-2
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks : CollectionsBenchmarksBase<CollectionsBenchmarksSource>
|
public class FindLastIndexBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_FindLastIndex_BestAndWorstCases";
|
||||||
|
|
||||||
public void Array_FindLastIndex_BestAndWorstCases()
|
public void Array_FindLastIndex_BestAndWorstCases()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
public class FindLastBenchmarks : RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_FindLast_BestAndWorstCases";
|
||||||
|
|
||||||
public void Array_FindLast_BestAndWorstCases()
|
public void Array_FindLast_BestAndWorstCases()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Collections.Benchmarks.Core;
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
namespace Recyclable.Collections.Benchmarks
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
{
|
{
|
||||||
public partial class RecyclableCollectionsCompatibilityListBenchmarks
|
public class FindBenchmarks: RecyclableCollectionsCompatibilityListBenchmarks
|
||||||
{
|
{
|
||||||
|
public override string MethodNameSuffix => "_Find_BestAndWorstCases";
|
||||||
|
|
||||||
public void Array_Find_BestAndWorstCases()
|
public void Array_Find_BestAndWorstCases()
|
||||||
{
|
{
|
||||||
var data = TestObjects;
|
var data = TestObjects;
|
||||||
|
|||||||
@@ -1,2 +1,25 @@
|
|||||||
// See https://aka.ms/new-console-template for more information
|
using BenchmarkDotNet.Configs;
|
||||||
Console.WriteLine("Hello, World!");
|
using BenchmarkDotNet.Running;
|
||||||
|
|
||||||
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
static IConfig BenchmarkConfig { get; } = ManualConfig.Create(DefaultConfig.Instance)
|
||||||
|
.WithOptions(ConfigOptions.DisableOptimizationsValidator | ConfigOptions.JoinSummary);
|
||||||
|
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
BenchmarkRunner.Run(new[]
|
||||||
|
{
|
||||||
|
typeof(BinarySearchBenchmarks),
|
||||||
|
typeof(ConvertAllBenchmarks),
|
||||||
|
typeof(ExistsBenchmarks),
|
||||||
|
typeof(FindBenchmarks),
|
||||||
|
typeof(FindAllBenchmarks),
|
||||||
|
typeof(FindLastBenchmarks),
|
||||||
|
typeof(FindLastIndexBenchmarks)
|
||||||
|
}, BenchmarkConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-4
@@ -1,15 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Collections.Benchmarks.Core" Version="0.0.2" />
|
<PackageReference Include="Collections.Benchmarks.Core" Version="0.0.4" />
|
||||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Recyclable.Collections.Compatibility.List\Recyclable.Collections.Compatibility.List.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using Collections.Benchmarks.Core;
|
||||||
|
|
||||||
|
namespace Recyclable.Collections.Compatibility.List.Benchmarks
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class RecyclableCollectionsCompatibilityListBenchmarks : DataDrivenBenchmarksBase<CollectionsBenchmarksSource>
|
||||||
|
{
|
||||||
|
[Params(CollectionsBenchmarksSource.Array)]
|
||||||
|
public override CollectionsBenchmarksSource BaseDataType { get => base.BaseDataType; set => base.BaseDataType = value; }
|
||||||
|
|
||||||
|
[Params(
|
||||||
|
CollectionsBenchmarksSource.List,
|
||||||
|
CollectionsBenchmarksSource.PooledList,
|
||||||
|
CollectionsBenchmarksSource.RecyclableList
|
||||||
|
)]
|
||||||
|
public override CollectionsBenchmarksSource DataType { get => base.DataType; set => base.DataType = value; }
|
||||||
|
|
||||||
|
//[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 32, 40, RecyclableDefaults.MinPooledArrayLength - 1, RecyclableDefaults.MinPooledArrayLength, 40, 50, 60, 70, 80, 90, 100, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, RecyclableDefaults.MinItemsCountForParallelization)]
|
||||||
|
[Params(RecyclableDefaults.MinPooledArrayLength, RecyclableDefaults.MinItemsCountForParallelization)]
|
||||||
|
public override int TestObjectCount { get => base.TestObjectCount; set => base.TestObjectCount = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-2
@@ -12,8 +12,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||||
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.2" />
|
<PackageReference Include="Recyclable.Collections.TestData" Version="0.0.3.1" />
|
||||||
<PackageReference Include="xunit" Version="2.5.3" />
|
<PackageReference Include="xunit" Version="2.5.3" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
@@ -25,4 +25,8 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Recyclable.Collections.Compatibility.List\Recyclable.Collections.Compatibility.List.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
+154
-1
@@ -3,6 +3,7 @@ using Recyclable.Collections;
|
|||||||
using Recyclable.Collections.TestData;
|
using Recyclable.Collections.TestData;
|
||||||
using Recyclable.Collections.Pools;
|
using Recyclable.Collections.Pools;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
#pragma warning disable xUnit1026, RCS1163, IDE0039, IDE0060, RCS1235
|
#pragma warning disable xUnit1026, RCS1163, IDE0039, IDE0060, RCS1235
|
||||||
|
|
||||||
@@ -201,6 +202,27 @@ namespace Recyclable.CollectionsTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||||
|
public void FindIndexShouldNotAnythingWhenRangeExcludesItem(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||||
|
{
|
||||||
|
// Prepare
|
||||||
|
using var list = new RecyclableList<long>(testData, itemsCount);
|
||||||
|
var expectedData = testData.ToList();
|
||||||
|
|
||||||
|
foreach (var itemIndex in itemIndexes)
|
||||||
|
{
|
||||||
|
var expectedItem = expectedData[(int)itemIndex];
|
||||||
|
var expected = expectedData.FindIndex((int)itemIndex + 1, (int)(itemsCount - itemIndex - 1), item => item == expectedItem);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var actual = list.FindIndex((int)itemIndex + 1, (int)(itemsCount - itemIndex - 1), item => item == expectedItem);
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
_ = actual.Should().Be(-1).And.Be(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||||
public void FindIndexShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
public void FindIndexShouldReturnCorrectIndexesWhenConstrainedIndex(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||||
@@ -475,6 +497,82 @@ namespace Recyclable.CollectionsTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||||
|
public void InsertRangeShouldAddItemsInTheRightPosition(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||||
|
{
|
||||||
|
// Prepare
|
||||||
|
var expectedData = testData.Reverse().ToArray();
|
||||||
|
|
||||||
|
foreach (var itemIndex in itemIndexes)
|
||||||
|
{
|
||||||
|
using var list = new RecyclableList<long>(testData.Reverse(), itemsCount);
|
||||||
|
var expected = expectedData.ToList();
|
||||||
|
expected.InsertRange((int)itemIndex, testData);
|
||||||
|
|
||||||
|
if (testCase.Contains("Array[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (Array)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ICollection[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (ICollection)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ICollection<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (ICollection<long>)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("IEnumerable[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (IEnumerable)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("IReadOnlyList<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (IReadOnlyList<long>)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ReadOnlySpan<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, new ReadOnlySpan<long>((long[])testData));
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("Span<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, new Span<long>((long[])testData));
|
||||||
|
}
|
||||||
|
else if (testData is long[] testDataArray)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataArray);
|
||||||
|
}
|
||||||
|
else if (testData is List<long> testDataList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableList<long> testDataRecyclableList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataRecyclableList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableLongList<long> testDataRecyclableLongList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataRecyclableLongList);
|
||||||
|
}
|
||||||
|
else if (testData is IList<long> testDataIList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataIList);
|
||||||
|
}
|
||||||
|
else if (testData is IEnumerable<long> testDataIEnumerable)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataIEnumerable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidCastException("Unknown type of test data");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate
|
||||||
|
list.Count.Should().Be(itemsCount << 1);
|
||||||
|
_ = list.Should().Equal(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||||
public void LastIndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
public void LastIndexOfShouldReturnCorrectIndexes(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||||
@@ -564,7 +662,62 @@ namespace Recyclable.CollectionsTests
|
|||||||
expectedItems.InsertRange((int)itemIndex, testData);
|
expectedItems.InsertRange((int)itemIndex, testData);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
list.InsertRange((int)itemIndex, testData);
|
if (testCase.Contains("Array[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (Array)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ICollection[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (ICollection)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ICollection<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (ICollection<long>)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("IEnumerable[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (IEnumerable)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("IReadOnlyList<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, (IReadOnlyList<long>)testData);
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("ReadOnlySpan<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, new ReadOnlySpan<long>((long[])testData));
|
||||||
|
}
|
||||||
|
else if (testCase.Contains("Span<T>[", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, new Span<long>((long[])testData));
|
||||||
|
}
|
||||||
|
else if (testData is long[] testDataArray)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataArray);
|
||||||
|
}
|
||||||
|
else if (testData is List<long> testDataList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableList<long> testDataRecyclableList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataRecyclableList);
|
||||||
|
}
|
||||||
|
else if (testData is RecyclableLongList<long> testDataRecyclableLongList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataRecyclableLongList);
|
||||||
|
}
|
||||||
|
else if (testData is IList<long> testDataIList)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataIList);
|
||||||
|
}
|
||||||
|
else if (testData is IEnumerable<long> testDataIEnumerable)
|
||||||
|
{
|
||||||
|
list.InsertRange((int)itemIndex, testDataIEnumerable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidCastException("Unknown type of test data");
|
||||||
|
}
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
_ = list[(int)itemIndex].Should().Be(item);
|
_ = list[(int)itemIndex].Should().Be(item);
|
||||||
|
|||||||
@@ -7,26 +7,40 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Comp
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Compatibility.List.Tests", "Recyclable.Collections.Compatibility.List.Tests\Recyclable.Collections.Compatibility.List.Tests.csproj", "{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Compatibility.List.Tests", "Recyclable.Collections.Compatibility.List.Tests\Recyclable.Collections.Compatibility.List.Tests.csproj", "{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Recyclable.Collections.Compatibility.List.Benchmarks", "Recyclable.Collections.Compatibility.List.Benchmarks\Recyclable.Collections.Compatibility.List.Benchmarks.csproj", "{A1414948-E61B-4AE1-ACAF-33A8BB85041E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Recyclable.Collections.Compatibility.List.Benchmarks", "Recyclable.Collections.Compatibility.List.Benchmarks\Recyclable.Collections.Compatibility.List.Benchmarks.csproj", "{A1414948-E61B-4AE1-ACAF-33A8BB85041E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Debug|x64.Build.0 = Debug|x64
|
||||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{779028EF-0584-4566-A80D-B5F3D6E25DD0}.Release|x64.Build.0 = Release|x64
|
||||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{1501C2BD-BDAF-4C89-B131-16C7D9C1B41B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A1414948-E61B-4AE1-ACAF-33A8BB85041E}.Release|x64.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
+4
-3
@@ -6,7 +6,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<PackageId>Recyclable.Collections.Compatibility.List</PackageId>
|
<PackageId>Recyclable.Collections.Compatibility.List</PackageId>
|
||||||
<PackageVersion>0.0.1</PackageVersion>
|
<PackageVersion>0.0.2</PackageVersion>
|
||||||
<Authors>Marek Lemańczyk</Authors>
|
<Authors>Marek Lemańczyk</Authors>
|
||||||
<Company>N/A</Company>
|
<Company>N/A</Company>
|
||||||
<Product>Recyclable.Collections.Compatibility.List</Product>
|
<Product>Recyclable.Collections.Compatibility.List</Product>
|
||||||
@@ -18,8 +18,9 @@
|
|||||||
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<PackageReleaseNotes>Support for RecyclableList<T> & RecyclableLongList<T> added.</PackageReleaseNotes>
|
<PackageReleaseNotes>Collections.Benchmarks.Core package updated. Bug fixes.</PackageReleaseNotes>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
<PackageIcon>logo.png</PackageIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -36,6 +37,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Recyclable.Collections" Version="0.0.6" />
|
<PackageReference Include="Recyclable.Collections" Version="0.0.6.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -117,13 +117,12 @@ namespace Recyclable.Collections
|
|||||||
|
|
||||||
public static int FindIndex<T>(this RecyclableList<T> list, int startIndex, int count, Predicate<T> match)
|
public static int FindIndex<T>(this RecyclableList<T> list, int startIndex, int count, Predicate<T> match)
|
||||||
{
|
{
|
||||||
int sourceItemsCount = list._count;
|
int sourceItemsCount = Math.Min(startIndex + count, list._count);
|
||||||
if (sourceItemsCount == 0 || startIndex >= sourceItemsCount)
|
if (sourceItemsCount == 0 || startIndex >= sourceItemsCount)
|
||||||
{
|
{
|
||||||
return RecyclableDefaults.ItemNotFoundIndex;
|
return RecyclableDefaults.ItemNotFoundIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceItemsCount = Math.Min(sourceItemsCount, startIndex + sourceItemsCount);
|
|
||||||
ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
ReadOnlySpan<T> sourceSpan = list._memoryBlock;
|
||||||
for (var itemIndex = startIndex; itemIndex < sourceItemsCount; itemIndex++)
|
for (var itemIndex = startIndex; itemIndex < sourceItemsCount; itemIndex++)
|
||||||
{
|
{
|
||||||
|
|||||||
+64
-33
@@ -74,6 +74,7 @@ namespace Recyclable.Collections
|
|||||||
{
|
{
|
||||||
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, currentItemsCount, checked((int)BitOperations.RoundUpToPowerOf2((uint)(currentItemsCount + requiredAdditionalCapacity))));
|
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, currentItemsCount, checked((int)BitOperations.RoundUpToPowerOf2((uint)(currentItemsCount + requiredAdditionalCapacity))));
|
||||||
|
|
||||||
|
// TODO: Count should be requiredAdditionalCapacity, we need to move as many items as many we're inserting
|
||||||
Array.Copy(list._memoryBlock, index, list._memoryBlock, index + requiredAdditionalCapacity, list._count - index);
|
Array.Copy(list._memoryBlock, index, list._memoryBlock, index + requiredAdditionalCapacity, list._count - index);
|
||||||
Span<T> memorySpan = list._memoryBlock;
|
Span<T> memorySpan = list._memoryBlock;
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
@@ -94,6 +95,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||||
Array.Copy(items, items.GetLowerBound(0), memoryBlock, index, items.Length);
|
Array.Copy(items, items.GetLowerBound(0), memoryBlock, index, items.Length);
|
||||||
list._count += items.Length;
|
list._count += items.Length;
|
||||||
@@ -109,6 +111,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||||
new ReadOnlySpan<T>(items).CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
new ReadOnlySpan<T>(items).CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||||
list._count += items.Length;
|
list._count += items.Length;
|
||||||
@@ -124,6 +127,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||||
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||||
list._count += items.Length;
|
list._count += items.Length;
|
||||||
@@ -139,6 +143,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Length, list._count - index);
|
||||||
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
items.CopyTo(new Span<T>(memoryBlock, index, items.Length));
|
||||||
list._count += items.Length;
|
list._count += items.Length;
|
||||||
@@ -154,6 +159,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||||
items.CopyTo(memoryBlock, index);
|
items.CopyTo(memoryBlock, index);
|
||||||
list._count += items.Count;
|
list._count += items.Count;
|
||||||
@@ -169,6 +175,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||||
items.CopyTo(list._memoryBlock, index);
|
items.CopyTo(list._memoryBlock, index);
|
||||||
list._count += items.Count;
|
list._count += items.Count;
|
||||||
@@ -184,6 +191,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||||
items.CopyTo(memoryBlock, index);
|
items.CopyTo(memoryBlock, index);
|
||||||
list._count += items.Count;
|
list._count += items.Count;
|
||||||
@@ -199,6 +207,7 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
T[] memoryBlock = list._memoryBlock;
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
// TODO: Count should be items.Count, we need to move as many items as many we're inserting
|
||||||
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
Array.Copy(memoryBlock, index, memoryBlock, index + items.Count, list._count - index);
|
||||||
new ReadOnlySpan<T>(items._memoryBlock, 0, items._count).CopyTo(new(list._memoryBlock, index, items._count));
|
new ReadOnlySpan<T>(items._memoryBlock, 0, items._count).CopyTo(new(list._memoryBlock, index, items._count));
|
||||||
list._count += items._count;
|
list._count += items._count;
|
||||||
@@ -257,43 +266,64 @@ namespace Recyclable.Collections
|
|||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerator InsertRange<T>(this RecyclableList<T> list, int index, IEnumerable source, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
public static void InsertRange<T>(this RecyclableList<T> list, int index, IEnumerable items, int growByCount = RecyclableDefaults.MinPooledArrayLength)
|
||||||
{
|
{
|
||||||
int targetItemIndex = list._count;
|
var enumerator = items.GetEnumerator();
|
||||||
Span<T> memorySpan;
|
if (!enumerator.MoveNext())
|
||||||
|
|
||||||
int i;
|
|
||||||
var enumerator = source.GetEnumerator();
|
|
||||||
|
|
||||||
int capacity = list._capacity;
|
|
||||||
memorySpan = list._memoryBlock;
|
|
||||||
if (enumerator.MoveNext())
|
|
||||||
{
|
{
|
||||||
int available = capacity - targetItemIndex;
|
return;
|
||||||
do
|
|
||||||
{
|
|
||||||
if (targetItemIndex + growByCount > capacity)
|
|
||||||
{
|
|
||||||
capacity = RecyclableListHelpers<T>.EnsureCapacity(list, targetItemIndex, checked((int)BitOperations.RoundUpToPowerOf2((uint)(targetItemIndex + growByCount))));
|
|
||||||
memorySpan = list._memoryBlock;
|
|
||||||
available = capacity - targetItemIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < available; i++)
|
|
||||||
{
|
|
||||||
memorySpan[targetItemIndex++] = (T)enumerator.Current;
|
|
||||||
if (!enumerator.MoveNext())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (i >= available);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int capacity = list._capacity,
|
||||||
|
added = 0,
|
||||||
|
available = capacity - list._count,
|
||||||
|
i,
|
||||||
|
movingBlockLength = list._count - index;
|
||||||
|
|
||||||
|
T[] memoryBlock = list._memoryBlock;
|
||||||
|
if (available > 0)
|
||||||
|
{
|
||||||
|
Array.Copy(memoryBlock, index, memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<T> memorySpan = memoryBlock;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (index + available + movingBlockLength > capacity)
|
||||||
|
{
|
||||||
|
var capacityBeforeIncrease = capacity;
|
||||||
|
capacity = checked((int)BitOperations.RoundUpToPowerOf2((uint)(capacity + growByCount)));
|
||||||
|
_ = RecyclableListHelpers<T>.EnsureCapacity(list, memoryBlock.Length, capacity);
|
||||||
|
memorySpan = memoryBlock = list._memoryBlock;
|
||||||
|
available = capacity - index - movingBlockLength;
|
||||||
|
Array.Copy(memoryBlock, capacityBeforeIncrease - movingBlockLength, memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < available; i++)
|
||||||
|
{
|
||||||
|
memorySpan[index++] = (T)enumerator.Current;
|
||||||
|
if (!enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
added++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
added += i;
|
||||||
|
}
|
||||||
|
while (i == available);
|
||||||
|
|
||||||
|
if (i != available)
|
||||||
|
{
|
||||||
|
Array.Copy(memoryBlock, capacity - movingBlockLength, memoryBlock, index, movingBlockLength);
|
||||||
|
if (RecyclableList<T>._needsClearing)
|
||||||
|
{
|
||||||
|
Array.Clear(memoryBlock, capacity - movingBlockLength, movingBlockLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list._count += added;
|
||||||
list._capacity = capacity;
|
list._capacity = capacity;
|
||||||
list._count = targetItemIndex;
|
|
||||||
return enumerator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InsertRange<T>(this RecyclableList<T> list, int index, IReadOnlyList<T> items)
|
public static void InsertRange<T>(this RecyclableList<T> list, int index, IReadOnlyList<T> items)
|
||||||
@@ -304,7 +334,8 @@ namespace Recyclable.Collections
|
|||||||
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, list._count, checked((int)BitOperations.RoundUpToPowerOf2((uint)(list._count + sourceItemsCount))));
|
list._capacity = RecyclableListHelpers<T>.EnsureCapacity(list, list._count, checked((int)BitOperations.RoundUpToPowerOf2((uint)(list._count + sourceItemsCount))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Span<T> memorySpan = new(list._memoryBlock, list._count, sourceItemsCount);
|
Array.Copy(list._memoryBlock, index, list._memoryBlock, index + sourceItemsCount, Math.Min(list.Count - index, sourceItemsCount));
|
||||||
|
Span<T> memorySpan = new(list._memoryBlock, index, sourceItemsCount);
|
||||||
for (var sourceItemIndex = 0; sourceItemIndex < sourceItemsCount; sourceItemIndex++)
|
for (var sourceItemIndex = 0; sourceItemIndex < sourceItemsCount; sourceItemIndex++)
|
||||||
{
|
{
|
||||||
memorySpan[sourceItemIndex] = items[sourceItemIndex];
|
memorySpan[sourceItemIndex] = items[sourceItemIndex];
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using Recyclable.Collections.Pools;
|
using Recyclable.Collections.Pools;
|
||||||
|
|
||||||
namespace Recyclable.Collections
|
namespace Recyclable.Collections
|
||||||
@@ -13,12 +14,15 @@ namespace Recyclable.Collections
|
|||||||
{
|
{
|
||||||
public static ReadOnlyCollection<T> AsReadOnly<T>(this RecyclableList<T> list) => new(list);
|
public static ReadOnlyCollection<T> AsReadOnly<T>(this RecyclableList<T> list) => new(list);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static int BinarySearch<T>(this RecyclableList<T> list, T item)
|
public static int BinarySearch<T>(this RecyclableList<T> list, T item)
|
||||||
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item);
|
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static int BinarySearch<T>(this RecyclableList<T> list, T item, IComparer<T>? comparer)
|
public static int BinarySearch<T>(this RecyclableList<T> list, T item, IComparer<T>? comparer)
|
||||||
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item, comparer);
|
=> Array.BinarySearch(list._memoryBlock, 0, list._count, item, comparer);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static int BinarySearch<T>(this RecyclableList<T> list, int index, int count, T item, IComparer<T>? comparer)
|
public static int BinarySearch<T>(this RecyclableList<T> list, int index, int count, T item, IComparer<T>? comparer)
|
||||||
=> Array.BinarySearch(list._memoryBlock, index, count, item, comparer);
|
=> Array.BinarySearch(list._memoryBlock, index, count, item, comparer);
|
||||||
|
|
||||||
@@ -42,8 +46,10 @@ namespace Recyclable.Collections
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void CopyTo<T>(this RecyclableList<T> list, T[] array) => Array.Copy(list._memoryBlock, array, list._count);
|
public static void CopyTo<T>(this RecyclableList<T> list, T[] array) => Array.Copy(list._memoryBlock, array, list._count);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void CopyTo<T>(this RecyclableList<T> list, int index, T[] array, int arrayIndex, int count) => Array.Copy(list._memoryBlock, index, array, arrayIndex, count);
|
public static void CopyTo<T>(this RecyclableList<T> list, int index, T[] array, int arrayIndex, int count) => Array.Copy(list._memoryBlock, index, array, arrayIndex, count);
|
||||||
|
|
||||||
public static void ForEach<T>(this RecyclableList<T> list, Action<T> action)
|
public static void ForEach<T>(this RecyclableList<T> list, Action<T> action)
|
||||||
@@ -131,42 +137,49 @@ namespace Recyclable.Collections
|
|||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Reverse<T>(this RecyclableList<T> list)
|
public static void Reverse<T>(this RecyclableList<T> list)
|
||||||
{
|
{
|
||||||
Array.Reverse(list._memoryBlock, 0, list._count);
|
Array.Reverse(list._memoryBlock, 0, list._count);
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Reverse<T>(this RecyclableList<T> list, int index, int count)
|
public static void Reverse<T>(this RecyclableList<T> list, int index, int count)
|
||||||
{
|
{
|
||||||
Array.Reverse(list._memoryBlock, index, count);
|
Array.Reverse(list._memoryBlock, index, count);
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Sort<T>(this RecyclableList<T> list)
|
public static void Sort<T>(this RecyclableList<T> list)
|
||||||
{
|
{
|
||||||
Array.Sort(list._memoryBlock, 0, list._count);
|
Array.Sort(list._memoryBlock, 0, list._count);
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Sort<T>(this RecyclableList<T> list, Comparison<T> comparison)
|
public static void Sort<T>(this RecyclableList<T> list, Comparison<T> comparison)
|
||||||
{
|
{
|
||||||
Array.Sort(list._memoryBlock, 0, list._count, new ComparisonToComparerAdapter<T>(comparison));
|
Array.Sort(list._memoryBlock, 0, list._count, new ComparisonToComparerAdapter<T>(comparison));
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Sort<T>(this RecyclableList<T> list, IComparer<T>? comparer)
|
public static void Sort<T>(this RecyclableList<T> list, IComparer<T>? comparer)
|
||||||
{
|
{
|
||||||
Array.Sort(list._memoryBlock, 0, list._count, comparer);
|
Array.Sort(list._memoryBlock, 0, list._count, comparer);
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static void Sort<T>(this RecyclableList<T> list, int index, int count, IComparer<T>? comparer)
|
public static void Sort<T>(this RecyclableList<T> list, int index, int count, IComparer<T>? comparer)
|
||||||
{
|
{
|
||||||
Array.Sort(list._memoryBlock, index, count, comparer);
|
Array.Sort(list._memoryBlock, index, count, comparer);
|
||||||
list._version++;
|
list._version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public static T[] ToArray<T>(this RecyclableList<T> list)
|
public static T[] ToArray<T>(this RecyclableList<T> list)
|
||||||
{
|
{
|
||||||
T[] result = new T[list._count];
|
T[] result = new T[list._count];
|
||||||
|
|||||||
Reference in new issue
Block a user