RecyclableLongList.BinarySearch implemented. Various performance improvements & fixes in RecyclableList.BinarySearch. Benchmarks & Tests extended.
This commit is contained in:
1 parent
393685f061
commit
1f7603fe08
15 files changed
+756
-172
No files matched your search
+159
-2
@@ -18,7 +18,7 @@ namespace Recyclable.CollectionsTests
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, itemsCount);
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
@@ -34,6 +34,32 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldFindAllItemsWhenConstrainedRange(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
var comparer = Comparer<long>.Default;
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var rangeSize = (int)Math.Min(itemsCount - itemIndex, 4);
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
var startItemIndex = (int)(rangeSize > 2 ? Math.Max(0, itemIndex - 2) : itemIndex);
|
||||
var expected = expectedData.BinarySearch(startItemIndex, rangeSize, expectedItem, comparer);
|
||||
|
||||
// Act
|
||||
var actual = list.BinarySearch(startItemIndex, rangeSize, expectedItem, comparer);
|
||||
|
||||
// Validate
|
||||
_ = actual.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldFindAllItemsWhenWithCustomComparer(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
@@ -41,7 +67,7 @@ namespace Recyclable.CollectionsTests
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, itemsCount);
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
var comparer = Comparer<long>.Default;
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
@@ -58,6 +84,137 @@ namespace Recyclable.CollectionsTests
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldNotFindNonExistingItems(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
list.RemoveAt((int)itemIndex);
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
var expectedRangedData = testData.ToList();
|
||||
expectedRangedData.RemoveAt((int)itemIndex);
|
||||
var expected = expectedRangedData.BinarySearch(expectedItem);
|
||||
|
||||
// Act
|
||||
var actual = list.BinarySearch(expectedItem);
|
||||
|
||||
// Validate
|
||||
_ = actual.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldNotFindNonExistingItemsWhenConstrainedRange(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
var comparer = Comparer<long>.Default;
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
list.RemoveAt((int)itemIndex);
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
var expectedRangedData = testData.ToList();
|
||||
expectedRangedData.RemoveAt((int)itemIndex);
|
||||
// Now we have 1 element less on the lists
|
||||
var rangeSize = (int)Math.Max(Math.Min(itemsCount - itemIndex - 2, 4), 0);
|
||||
int startItemIndex = (int)(rangeSize > 2 ? Math.Max(0, itemIndex - 2 - 1) : Math.Max(0, itemIndex - 1));
|
||||
var expected = expectedRangedData.BinarySearch(startItemIndex, rangeSize, expectedItem, comparer);
|
||||
|
||||
// Act
|
||||
var actual = list.BinarySearch(startItemIndex, rangeSize, expectedItem, comparer);
|
||||
|
||||
// Validate
|
||||
_ = actual.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldNotFindNonExistingItemsWhenOutsideRange(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
var comparer = Comparer<long>.Default;
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
|
||||
// Act && Validate
|
||||
var expected = expectedData.BinarySearch(0, (int)itemIndex, expectedItem, comparer);
|
||||
_ = list.BinarySearch(0, (int)itemIndex, expectedItem, comparer).Should().Be(expected);
|
||||
|
||||
expected = expectedData.BinarySearch((int)itemIndex + 1, itemsCount - (int)itemIndex - 1, expectedItem, comparer);
|
||||
_ = list.BinarySearch((int)itemIndex + 1, itemsCount - (int)itemIndex - 1, expectedItem, comparer).Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldNotFindNonExistingItemsWhenWithCustomComparer(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
var comparer = Comparer<long>.Default;
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
list.RemoveAt((int)itemIndex);
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
var expectedRangedData = testData.ToList();
|
||||
expectedRangedData.RemoveAt((int)itemIndex);
|
||||
var expected = expectedRangedData.BinarySearch(expectedItem, comparer);
|
||||
|
||||
// Act
|
||||
var actual = list.BinarySearch(expectedItem, comparer);
|
||||
|
||||
// Validate
|
||||
_ = actual.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataWithItemIndexVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void BinarySearchShouldThrowArgumentOutOfRangeWhenOutsideRange(string testCase, IEnumerable<long> testData, int itemsCount, in long[] itemIndexes)
|
||||
{
|
||||
_ = testData.Any().Should().BeTrue("we need items on the list that we can look for");
|
||||
|
||||
// Prepare
|
||||
using var list = new RecyclableList<long>(testData, initialCapacity: itemsCount);
|
||||
var comparer = Comparer<long>.Default;
|
||||
var expectedData = testData.ToList();
|
||||
|
||||
foreach (var itemIndex in itemIndexes)
|
||||
{
|
||||
var expectedItem = expectedData[(int)itemIndex];
|
||||
|
||||
// Act && Validate
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => _ = expectedData.BinarySearch(-1, (int)itemIndex, expectedItem, comparer));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => _ = list.BinarySearch(-1, (int)itemIndex, expectedItem, comparer));
|
||||
|
||||
Assert.Throws<ArgumentException>(() => _ = expectedData.BinarySearch((int)itemIndex + 1, itemsCount, expectedItem, comparer));
|
||||
Assert.Throws<ArgumentException>(() => _ = list.BinarySearch((int)itemIndex + 1, itemsCount, expectedItem, comparer));
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RecyclableLongListTestData.SourceDataVariants), MemberType = typeof(RecyclableLongListTestData))]
|
||||
public void ConvertAllShouldConvertAllItems(string testCase, IEnumerable<long> testData, int itemsCount)
|
||||
|
||||
Reference in new issue
Block a user