Add IReadOnlyCollection AddRange overload
This commit is contained in:
1 parent
050d7fd386
commit
f6640deaf1
2 files changed
+103
No files matched your search
@@ -1108,6 +1108,53 @@ namespace Recyclable.Collections
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
|
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, IReadOnlyCollection<T> items)
|
||||||
|
{
|
||||||
|
int count = items.Count;
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int startIndex = queue._size;
|
||||||
|
int newCount = startIndex + count;
|
||||||
|
EnsureCapacity(queue, newCount);
|
||||||
|
|
||||||
|
int index = startIndex;
|
||||||
|
foreach (T item in items)
|
||||||
|
{
|
||||||
|
queue._heap[index++] = item;
|
||||||
|
}
|
||||||
|
queue._size = newCount;
|
||||||
|
|
||||||
|
int half = newCount >> 1;
|
||||||
|
for (int i = half - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
int idx = i;
|
||||||
|
T current = queue._heap[idx];
|
||||||
|
while (idx < half)
|
||||||
|
{
|
||||||
|
int child = (idx << 1) + 1;
|
||||||
|
int right = child + 1;
|
||||||
|
if (right < newCount && queue._comparer.Compare(queue._heap[right], queue._heap[child]) < 0)
|
||||||
|
{
|
||||||
|
child = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue._comparer.Compare(queue._heap[child], current) >= 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue._heap[idx] = queue._heap[child];
|
||||||
|
idx = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue._heap[idx] = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
internal static IEnumerator AddRange<T>(this RecyclablePriorityQueue<T> queue, IEnumerable source)
|
internal static IEnumerator AddRange<T>(this RecyclablePriorityQueue<T> queue, IEnumerable source)
|
||||||
{
|
{
|
||||||
@@ -1178,6 +1225,10 @@ namespace Recyclable.Collections
|
|||||||
{
|
{
|
||||||
AddRange(queue, readOnlyList);
|
AddRange(queue, readOnlyList);
|
||||||
}
|
}
|
||||||
|
else if (items is IReadOnlyCollection<T> readOnlyCollection)
|
||||||
|
{
|
||||||
|
AddRange(queue, readOnlyCollection);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (T item in items)
|
foreach (T item in items)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Recyclable.Collections;
|
using Recyclable.Collections;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Recyclable.CollectionsTests
|
namespace Recyclable.CollectionsTests
|
||||||
{
|
{
|
||||||
@@ -406,6 +407,57 @@ namespace Recyclable.CollectionsTests
|
|||||||
_ = result.Should().Equal(expected);
|
_ = result.Should().Equal(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AddRangeReadOnlyCollectionShouldAddItemsInSortedOrder()
|
||||||
|
{
|
||||||
|
var source = new TestReadOnlyCollection<int>(_testData);
|
||||||
|
using var queue = new RecyclablePriorityQueue<int>();
|
||||||
|
|
||||||
|
queue.AddRange(source);
|
||||||
|
|
||||||
|
var result = new List<int>();
|
||||||
|
while (queue.LongCount > 0)
|
||||||
|
{
|
||||||
|
result.Add(queue.Dequeue());
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = result.Should().Equal(_testData.Order());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void AddRangeReadOnlyCollectionShouldNotOverrideItems()
|
||||||
|
{
|
||||||
|
var source = new TestReadOnlyCollection<int>(_testData);
|
||||||
|
using var queue = new RecyclablePriorityQueue<int>();
|
||||||
|
|
||||||
|
queue.AddRange(source);
|
||||||
|
queue.AddRange(source);
|
||||||
|
|
||||||
|
var expected = _testData.Concat(_testData).Order().ToArray();
|
||||||
|
var result = new List<int>();
|
||||||
|
while (queue.LongCount > 0)
|
||||||
|
{
|
||||||
|
result.Add(queue.Dequeue());
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = result.Should().Equal(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class TestReadOnlyCollection<T> : IReadOnlyCollection<T>
|
||||||
|
{
|
||||||
|
private readonly T[] _items;
|
||||||
|
|
||||||
|
public TestReadOnlyCollection(T[] items)
|
||||||
|
{
|
||||||
|
_items = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => _items.Length;
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)_items).GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => _items.GetEnumerator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user