fix: Fixed PriorityQueue IndexOutOfRange exception when an inner queue becomes depleted

This commit is contained in:
Chris Cameron
2019-05-02 10:23:53 -04:00
parent 736c2aee33
commit d7bfb07c2c
3 changed files with 52 additions and 20 deletions

View File

@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased] ## [Unreleased]
### Changed
- Fixed PriorityQueue IndexOutOfRange exception when an inner queue becomes depleted
## [8.3.1] - 2019-04-05 ## [8.3.1] - 2019-04-05
### Changed ### Changed
- Fixed FormatException when parsing some JSON DateTimes - Fixed FormatException when parsing some JSON DateTimes

View File

@@ -168,6 +168,29 @@ namespace ICD.Common.Utils.Tests.Collections
Assert.AreEqual(0, queue.Count); Assert.AreEqual(0, queue.Count);
} }
[Test]
public void TryDequeueTest()
{
PriorityQueue<int> queue = new PriorityQueue<int>();
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] [Test]
public void GetEnumeratorTest() public void GetEnumeratorTest()
{ {

View File

@@ -77,7 +77,7 @@ namespace ICD.Common.Utils.Collections
if (!m_PriorityToQueue.TryGetValue(priority, out queue)) if (!m_PriorityToQueue.TryGetValue(priority, out queue))
{ {
queue = new List<T>(); queue = new List<T>();
m_PriorityToQueue[priority] = queue; m_PriorityToQueue.Add(priority, queue);
} }
queue.Add(item); queue.Add(item);
@@ -97,7 +97,7 @@ namespace ICD.Common.Utils.Collections
if (!m_PriorityToQueue.TryGetValue(priority, out queue)) if (!m_PriorityToQueue.TryGetValue(priority, out queue))
{ {
queue = new List<T>(); queue = new List<T>();
m_PriorityToQueue[priority] = queue; m_PriorityToQueue.Add(priority, queue);
} }
queue.Insert(0, item); queue.Insert(0, item);
@@ -136,7 +136,7 @@ namespace ICD.Common.Utils.Collections
bool inserted = false; bool inserted = false;
foreach (KeyValuePair<int, List<T>> kvp in m_PriorityToQueue) foreach (KeyValuePair<int, List<T>> kvp in m_PriorityToQueue.ToArray())
{ {
int[] removeIndices = int[] removeIndices =
kvp.Value kvp.Value
@@ -166,6 +166,9 @@ namespace ICD.Common.Utils.Collections
inserted = true; inserted = true;
} }
if (kvp.Value.Count == 0)
m_PriorityToQueue.Remove(kvp.Key);
} }
if (!inserted) if (!inserted)
@@ -193,6 +196,8 @@ namespace ICD.Common.Utils.Collections
/// <returns></returns> /// <returns></returns>
[PublicAPI] [PublicAPI]
public bool TryDequeue(out T output) public bool TryDequeue(out T output)
{
while (true)
{ {
output = default(T); output = default(T);
@@ -203,16 +208,20 @@ namespace ICD.Common.Utils.Collections
int priority = kvp.Key; int priority = kvp.Key;
List<T> queue = kvp.Value; List<T> queue = kvp.Value;
output = queue[0]; bool found = queue.TryFirst(out output);
if (found)
{
queue.RemoveAt(0); queue.RemoveAt(0);
m_Count--;
}
if (queue.Count == 0) if (queue.Count == 0)
m_PriorityToQueue.Remove(priority); m_PriorityToQueue.Remove(priority);
m_Count--; if (found)
return true; return true;
} }
}
/// <summary> /// <summary>
/// Gets an enumerator for the items. /// Gets an enumerator for the items.
@@ -233,10 +242,7 @@ namespace ICD.Common.Utils.Collections
public void CopyTo(Array array, int index) public void CopyTo(Array array, int index)
{ {
foreach (T item in this) foreach (T item in this)
{ array.SetValue(item, index++);
array.SetValue(item, index);
index++;
}
} }
#endregion #endregion