diff --git a/CHANGELOG.md b/CHANGELOG.md index b5ae245..5ac4bad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - RangeAttribute improvements for better type safety - PathUtils breaking out ProgramConfigDirectory and CommonConfigDirectory from the full paths +## [8.3.2] - 2019-05-02 +### Changed + - Fixed PriorityQueue IndexOutOfRange exception when an inner queue becomes depleted + ## [8.3.1] - 2019-04-05 ### Changed - Fixed FormatException when parsing some JSON DateTimes diff --git a/ICD.Common.Utils.Tests/Collections/PriorityQueueTest.cs b/ICD.Common.Utils.Tests/Collections/PriorityQueueTest.cs index caa319f..b44608f 100644 --- a/ICD.Common.Utils.Tests/Collections/PriorityQueueTest.cs +++ b/ICD.Common.Utils.Tests/Collections/PriorityQueueTest.cs @@ -168,6 +168,29 @@ namespace ICD.Common.Utils.Tests.Collections Assert.AreEqual(0, queue.Count); } + [Test] + public void TryDequeueTest() + { + PriorityQueue queue = new PriorityQueue(); + queue.Enqueue(10, 1); + queue.Enqueue(20, 2); + queue.Enqueue(30, 3); + + int output; + + Assert.IsTrue(queue.TryDequeue(out output)); + Assert.AreEqual(10, output); + + Assert.IsTrue(queue.TryDequeue(out output)); + Assert.AreEqual(20, output); + + Assert.IsTrue(queue.TryDequeue(out output)); + Assert.AreEqual(30, output); + + Assert.IsFalse(queue.TryDequeue(out output)); + Assert.AreEqual(0, output); + } + [Test] public void GetEnumeratorTest() { diff --git a/ICD.Common.Utils/Collections/PriorityQueue.cs b/ICD.Common.Utils/Collections/PriorityQueue.cs index c62ecd0..8c07ef3 100644 --- a/ICD.Common.Utils/Collections/PriorityQueue.cs +++ b/ICD.Common.Utils/Collections/PriorityQueue.cs @@ -77,7 +77,7 @@ namespace ICD.Common.Utils.Collections if (!m_PriorityToQueue.TryGetValue(priority, out queue)) { queue = new List(); - m_PriorityToQueue[priority] = queue; + m_PriorityToQueue.Add(priority, queue); } queue.Add(item); @@ -97,7 +97,7 @@ namespace ICD.Common.Utils.Collections if (!m_PriorityToQueue.TryGetValue(priority, out queue)) { queue = new List(); - m_PriorityToQueue[priority] = queue; + m_PriorityToQueue.Add(priority, queue); } queue.Insert(0, item); @@ -136,7 +136,7 @@ namespace ICD.Common.Utils.Collections bool inserted = false; - foreach (KeyValuePair> kvp in m_PriorityToQueue) + foreach (KeyValuePair> kvp in m_PriorityToQueue.ToArray()) { int[] removeIndices = kvp.Value @@ -166,6 +166,9 @@ namespace ICD.Common.Utils.Collections inserted = true; } + + if (kvp.Value.Count == 0) + m_PriorityToQueue.Remove(kvp.Key); } if (!inserted) @@ -194,24 +197,30 @@ namespace ICD.Common.Utils.Collections [PublicAPI] public bool TryDequeue(out T output) { - output = default(T); + while (true) + { + output = default(T); - KeyValuePair> kvp; - if (!m_PriorityToQueue.TryFirst(out kvp)) - return false; + KeyValuePair> kvp; + if (!m_PriorityToQueue.TryFirst(out kvp)) + return false; - int priority = kvp.Key; - List queue = kvp.Value; + int priority = kvp.Key; + List queue = kvp.Value; - output = queue[0]; - queue.RemoveAt(0); + bool found = queue.TryFirst(out output); + if (found) + { + queue.RemoveAt(0); + m_Count--; + } - if (queue.Count == 0) - m_PriorityToQueue.Remove(priority); + if (queue.Count == 0) + m_PriorityToQueue.Remove(priority); - m_Count--; - - return true; + if (found) + return true; + } } /// @@ -233,10 +242,7 @@ namespace ICD.Common.Utils.Collections public void CopyTo(Array array, int index) { foreach (T item in this) - { - array.SetValue(item, index); - index++; - } + array.SetValue(item, index++); } #endregion