Skip to content

Commit

Permalink
Add PriorityQueue to System.Collections.Generic (#43957) (#46009)
Browse files Browse the repository at this point in the history
* Add PriorityQueue to System.Collections.Generic (#43957)

This commit adds a new data structure, priority queue.

Fixes #43957

* (draft step, to squash) Modify API reference

In this commit, I modified the API reference using [these guidelines](https://github.com/dotnet/runtime/blob/4d784693ebc5f91c7eede32170046355ef3969b2/docs/coding-guidelines/updating-ref-source.md), following the advice from @danmosemsft.

The automatically generated code (with `dotnet msbuild /t:GenerateReferenceAssemblySource`) didn't build out of the box and I tweaked it manually.

* (draft step, to squash) Add tests for PriorityQueue

Added generic tests for <int, int> and <string, string>. Removed non-generic tests.

* (draft step, to squash) Add initial implementation

This commit adds the core of the heap implementation for the priority queue.

It doesn't implement the method `EnqueueDequeue`, as I'm not convinced by it. It also doesn't implement the method `CopyTo(Array array, int index)`, leaving this one for later.

* (draft step, to squash) Rename parameters

* (draft step, to squash) Replace `this.nodes` with `_nodes`

* (draft step, to squash) Use an array and handle sizing ourselves

* (draft step, to squash) Create UnorderedItemsCollection lazily

* (draft step, to squash) Deduplicate constructors

* (draft step, to squash) Replace excessive `var` with explicit types

* (draft step, to squash) Remove `this.` in front of methods

* (draft step, to squash) Improve out-of-range-argument exceptions

* (draft step, to squash) Use error messages from .resx

* (draft step, to squash) Use positive case first in try methods

* (draft step, to squash) Implement UnorderedItemsCollection.CopyTo

* (draft step, to squash) Optimize expressions involving Arity

* (draft step, to squash) Adjust implementation to be consistent with reference

* (draft step, to squash) Implement method `EnqueueDequeue`

* (draft step, to squash) Make EnsureCapacity return int

* (draft step, to squash) Simplify lazy initialization of _unorderedItems

* (draft step, to squash) Use `out _` discard for unused properties

* (draft step, to squash) Relax null checks on elements and priorities

* (draft step, to squash) Simplify method SetCapacity

* (draft step, to squash) Remove MethodImplOptions.AggressiveInlining attributed

* (draft step, to squash) Use Array.Empty if the initial capacity is zero

* (draft step, to squash) Simplify UnorderedItemsCollection.Enumerator declaration

* (draft step, to squash) Simplify GetEnumerator methods

* (draft step, to squash) Optimize EnqueueRange methods

* (draft step, to squash) Capitalize members of (TElement, TPriority)[]

* (draft step, to squash) Improve resize constants

* (draft step, to squash) Remove redundant `.this`

* (draft step, to squash) Optimize EnqueueDequeue

* (draft step, to squash) Reduce indentation

* (draft step, to squash) Simplify math expressions

* (draft step, to squash) Remove the PutAt helper method

* (draft step, to squash) Make the UnorderedItemsCollection constructor internal

* (draft step, to squash) Clear last node slot on removal

* (draft step, to squash) Improve next growth capacity computation

* (draft step, to squash) Optimize Enqueue method

* (draft step, to squash) Make UnorderedItemsCollection.CopyTo implemented explicitly on ICollection

* (draft step, to squash) Improve priority queue tests

* (draft step, to squash) Drop redundant casting

* (draft step, to squash) Cosmetic improvements

* (draft step, to squash) Change signature of UnorderedItemsCollection

* (draft step, to squash) Add test PriorityQueue_Generic_EnqueueDequeue_EqualToMin

* (draft step, to squash) Add tests of enqueue null functionality

* (draft step, to squash) Add test PriorityQueue_Generic_EnsureCapacity_Negative

* (draft step, to squash) Check underlying buffer length in tests with reflection

* (draft step, to squash) Check enumeration invalidation

* (draft step, to squash) Simplify code and improve documentation
  • Loading branch information
pgolebiowski authored Feb 15, 2021
1 parent d687544 commit 826aa4f
Show file tree
Hide file tree
Showing 7 changed files with 1,255 additions and 0 deletions.
45 changes: 45 additions & 0 deletions src/libraries/System.Collections/ref/System.Collections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,51 @@ public void Dispose() { }
void System.Collections.IEnumerator.Reset() { }
}
}

public partial class PriorityQueue<TElement, TPriority>
{
public PriorityQueue() { }
public PriorityQueue(System.Collections.Generic.IComparer<TPriority>? comparer) { }
public PriorityQueue(System.Collections.Generic.IEnumerable<(TElement element, TPriority priority)> items) { }
public PriorityQueue(System.Collections.Generic.IEnumerable<(TElement element, TPriority priority)> items, System.Collections.Generic.IComparer<TPriority>? comparer) { }
public PriorityQueue(int initialCapacity) { }
public PriorityQueue(int initialCapacity, System.Collections.Generic.IComparer<TPriority>? comparer) { }
public System.Collections.Generic.IComparer<TPriority> Comparer { get { throw null; } }
public int Count { get { throw null; } }
public System.Collections.Generic.PriorityQueue<TElement, TPriority>.UnorderedItemsCollection UnorderedItems { get { throw null; } }
public void Clear() { }
public TElement Dequeue() { throw null; }
public void Enqueue(TElement element, TPriority priority) { }
public TElement EnqueueDequeue(TElement element, TPriority priority) { throw null; }
public void EnqueueRange(System.Collections.Generic.IEnumerable<(TElement element, TPriority priority)> items) { }
public void EnqueueRange(System.Collections.Generic.IEnumerable<TElement> elements, TPriority priority) { }
public int EnsureCapacity(int capacity) { throw null; }
public TElement Peek() { throw null; }
public void TrimExcess() { }
public bool TryDequeue([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TElement element, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TPriority priority) { throw null; }
public bool TryPeek([System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TElement element, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TPriority priority) { throw null; }
public sealed partial class UnorderedItemsCollection : System.Collections.Generic.IEnumerable<(TElement element, TPriority priority)>, System.Collections.Generic.IReadOnlyCollection<(TElement element, TPriority priority)>, System.Collections.ICollection, System.Collections.IEnumerable
{
internal UnorderedItemsCollection(PriorityQueue<TElement, TPriority> queue) { }
public int Count { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
void ICollection.CopyTo(System.Array array, int index) { }
public System.Collections.Generic.PriorityQueue<TElement, TPriority>.UnorderedItemsCollection.Enumerator GetEnumerator() { throw null; }
System.Collections.Generic.IEnumerator<(TElement element, TPriority priority)> System.Collections.Generic.IEnumerable<(TElement element, TPriority priority)>.GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public partial struct Enumerator : System.Collections.Generic.IEnumerator<(TElement element, TPriority priority)>, System.Collections.IEnumerator, System.IDisposable
{
(TElement element, TPriority priority) IEnumerator<(TElement element, TPriority priority)>.Current { get { throw null; } }
public void Dispose() { }
public bool MoveNext() { throw null; }
public (TElement element, TPriority priority) Current { get { throw null; } }
object System.Collections.IEnumerator.Current { get { throw null; } }
void System.Collections.IEnumerator.Reset() { }
}
}
}

public partial class Queue<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection, System.Collections.IEnumerable
{
public Queue() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Compile Include="$(CoreLibSharedDir)System\Collections\Generic\IDictionaryDebugView.cs"
Link="Common\System\Collections\Generic\IDictionaryDebugView.cs" />
<Compile Include="System\Collections\Generic\LinkedList.cs" />
<Compile Include="System\Collections\Generic\PriorityQueue.cs" />
<Compile Include="System\Collections\Generic\Queue.cs" />
<Compile Include="System\Collections\Generic\QueueDebugView.cs" />
<Compile Include="System\Collections\Generic\SortedDictionary.cs" />
Expand Down
Loading

0 comments on commit 826aa4f

Please sign in to comment.