Add more PriorityQueue AddRange overloads
This commit is contained in:
1 parent
6d80b36d70
commit
ff38aa302a
2 files changed
+445
No files matched your search
@@ -448,6 +448,352 @@ namespace Recyclable.Collections
|
||||
}
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableQueue<T> items)
|
||||
{
|
||||
long longCount = items._count;
|
||||
if (longCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = checked((int)longCount);
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + count;
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
var sourceChunk = items._head;
|
||||
int destIndex = startIndex;
|
||||
while (sourceChunk != null)
|
||||
{
|
||||
int sourceIndex = sourceChunk.Bottom;
|
||||
int sourceTop = sourceChunk.Top;
|
||||
T[] source = sourceChunk.Value;
|
||||
|
||||
while (sourceIndex < sourceTop)
|
||||
{
|
||||
queue._heap[destIndex++] = source[sourceIndex++];
|
||||
}
|
||||
|
||||
sourceChunk = sourceChunk.Next;
|
||||
}
|
||||
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableStack<T> items)
|
||||
{
|
||||
long longCount = items._count;
|
||||
if (longCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = checked((int)longCount);
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + count;
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
var sourceChunk = items._current;
|
||||
while (sourceChunk.Previous != null)
|
||||
{
|
||||
sourceChunk = sourceChunk.Previous;
|
||||
}
|
||||
|
||||
int destIndex = startIndex;
|
||||
while (sourceChunk != null)
|
||||
{
|
||||
T[] source = sourceChunk.Value;
|
||||
int sourceCount = sourceChunk.Index;
|
||||
int sourceIndex = 0;
|
||||
|
||||
while (sourceIndex < sourceCount)
|
||||
{
|
||||
queue._heap[destIndex++] = source[sourceIndex++];
|
||||
}
|
||||
|
||||
sourceChunk = sourceChunk.Next;
|
||||
}
|
||||
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableLinkedList<T> items)
|
||||
{
|
||||
long longCount = items._count;
|
||||
if (longCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = checked((int)longCount);
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + count;
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
var sourceChunk = items._head;
|
||||
int destIndex = startIndex;
|
||||
while (sourceChunk != null)
|
||||
{
|
||||
int sourceIndex = sourceChunk.Bottom;
|
||||
int sourceTop = sourceChunk.Top;
|
||||
T[] source = sourceChunk.Value;
|
||||
|
||||
while (sourceIndex < sourceTop)
|
||||
{
|
||||
queue._heap[destIndex++] = source[sourceIndex++];
|
||||
}
|
||||
|
||||
sourceChunk = sourceChunk.Next;
|
||||
}
|
||||
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableSortedSet<T> items)
|
||||
{
|
||||
int count = items._count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + count;
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
T[] source = items._items;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
queue._heap[startIndex + i] = source[i];
|
||||
}
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableHashSet<T> items)
|
||||
{
|
||||
int count = items._count;
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + count;
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
var entries = items._entries;
|
||||
int shift = items._blockShift,
|
||||
mask = items._blockSizeMinus1;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
queue._heap[startIndex + i] = entries[i >> shift][i & mask].Value;
|
||||
}
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
int index = i;
|
||||
T item = queue._heap[index];
|
||||
while (index < half)
|
||||
{
|
||||
int child = (index << 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], item) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
queue._heap[index] = queue._heap[child];
|
||||
index = child;
|
||||
}
|
||||
|
||||
queue._heap[index] = item;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
internal static void AddRange<T>(this RecyclablePriorityQueue<T> queue, RecyclableLongList<T> items)
|
||||
{
|
||||
long longCount = items._longCount;
|
||||
if (longCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int blockSize = items._blockSize;
|
||||
int fullBlocks = (int)(longCount >> items._blockSizePow2BitShift);
|
||||
int lastBlockLength = (int)(longCount & items._blockSizeMinus1);
|
||||
|
||||
int startIndex = queue._size;
|
||||
int newCount = startIndex + checked((int)longCount);
|
||||
EnsureCapacity(queue, newCount);
|
||||
|
||||
int destIndex = startIndex;
|
||||
for (int blockIndex = 0; blockIndex < fullBlocks; blockIndex++)
|
||||
{
|
||||
T[] block = items._memoryBlocks[blockIndex];
|
||||
int sourceIndex = 0;
|
||||
while (sourceIndex < blockSize)
|
||||
{
|
||||
queue._heap[destIndex++] = block[sourceIndex++];
|
||||
}
|
||||
}
|
||||
|
||||
if (lastBlockLength > 0)
|
||||
{
|
||||
T[] block = items._memoryBlocks[fullBlocks];
|
||||
int sourceIndex = 0;
|
||||
while (sourceIndex < lastBlockLength)
|
||||
{
|
||||
queue._heap[destIndex++] = block[sourceIndex++];
|
||||
}
|
||||
}
|
||||
|
||||
queue._size = newCount;
|
||||
|
||||
int half = newCount >> 1;
|
||||
for (int i = half - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -532,6 +878,30 @@ namespace Recyclable.Collections
|
||||
{
|
||||
AddRange(queue, priorityQueue);
|
||||
}
|
||||
else if (items is RecyclableQueue<T> recyclableQueue)
|
||||
{
|
||||
AddRange(queue, recyclableQueue);
|
||||
}
|
||||
else if (items is RecyclableStack<T> recyclableStack)
|
||||
{
|
||||
AddRange(queue, recyclableStack);
|
||||
}
|
||||
else if (items is RecyclableLinkedList<T> linkedList)
|
||||
{
|
||||
AddRange(queue, linkedList);
|
||||
}
|
||||
else if (items is RecyclableSortedSet<T> sortedSet)
|
||||
{
|
||||
AddRange(queue, sortedSet);
|
||||
}
|
||||
else if (items is RecyclableHashSet<T> hashSet)
|
||||
{
|
||||
AddRange(queue, hashSet);
|
||||
}
|
||||
else if (items is RecyclableLongList<T> longList)
|
||||
{
|
||||
AddRange(queue, longList);
|
||||
}
|
||||
else if (items is T[] array)
|
||||
{
|
||||
AddRange(queue, array);
|
||||
|
||||
@@ -148,6 +148,81 @@ namespace Recyclable.CollectionsTests
|
||||
_ = queue.Should().HaveCount(2).And.Contain((long?)null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRangeQueueShouldAddItemsInSortedOrder()
|
||||
{
|
||||
using var source = new RecyclableQueue<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 AddRangeQueueShouldNotOverrideItems()
|
||||
{
|
||||
using var source = new RecyclableQueue<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);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddRangeStackShouldAddItemsInSortedOrder()
|
||||
{
|
||||
using var source = new RecyclableStack<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 AddRangeSortedSetShouldAddItemsInSortedOrder()
|
||||
{
|
||||
using var source = new RecyclableSortedSet<int>();
|
||||
foreach (int item in _testData)
|
||||
{
|
||||
source.Add(item);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user