diff --git a/ICD.Common.Utils/Collections/PriorityQueue.cs b/ICD.Common.Utils/Collections/PriorityQueue.cs
index 6d18399..7adc438 100644
--- a/ICD.Common.Utils/Collections/PriorityQueue.cs
+++ b/ICD.Common.Utils/Collections/PriorityQueue.cs
@@ -84,6 +84,20 @@ namespace ICD.Common.Utils.Collections
m_Count++;
}
+ ///
+ /// Adds the item to the queue with the given priority at the given index.
+ ///
+ ///
+ ///
+ ///
+ [PublicAPI]
+ public void Enqueue([CanBeNull] T item, int priority, int position)
+ {
+ m_PriorityToQueue.GetOrAddNew(priority, ()=> new List())
+ .Insert(position, item);
+ m_Count++;
+ }
+
///
/// Enqueues the item at the beginning of the queue.
///
@@ -117,7 +131,7 @@ namespace ICD.Common.Utils.Collections
if (remove == null)
throw new ArgumentNullException("remove");
- EnqueueRemove(item, remove, int.MaxValue);
+ EnqueueRemove(item, remove, int.MaxValue, false);
}
///
@@ -128,12 +142,16 @@ namespace ICD.Common.Utils.Collections
///
///
///
+ ///
[PublicAPI]
- public void EnqueueRemove(T item, Func remove, int priority)
+ public void EnqueueRemove([CanBeNull] T item, [NotNull] Func remove, int priority, bool deDuplicateToEndOfQueue)
{
if (remove == null)
throw new ArgumentNullException("remove");
+ int lowestMatchingPriority = int.MaxValue;
+ int? firstMatchingIndex = null;
+
foreach (KeyValuePair> kvp in m_PriorityToQueue.ToArray())
{
int[] removeIndices =
@@ -142,6 +160,12 @@ namespace ICD.Common.Utils.Collections
.Reverse()
.ToArray();
+ if (removeIndices.Any() && kvp.Key < lowestMatchingPriority )
+ {
+ lowestMatchingPriority = kvp.Key;
+ firstMatchingIndex = removeIndices.Last();
+ }
+
foreach (int removeIndex in removeIndices)
{
kvp.Value.RemoveAt(removeIndex);
@@ -152,7 +176,16 @@ namespace ICD.Common.Utils.Collections
m_PriorityToQueue.Remove(kvp.Key);
}
- Enqueue(item, priority);
+
+ if(deDuplicateToEndOfQueue)
+ Enqueue(item, priority);
+ else
+ {
+ if(firstMatchingIndex == null)
+ Enqueue(item, lowestMatchingPriority);
+ else
+ Enqueue(item, lowestMatchingPriority, firstMatchingIndex.Value);
+ }
}
///
diff --git a/ICD.Common.Utils/Extensions/DictionaryExtensions.cs b/ICD.Common.Utils/Extensions/DictionaryExtensions.cs
index cc3f582..a484a46 100644
--- a/ICD.Common.Utils/Extensions/DictionaryExtensions.cs
+++ b/ICD.Common.Utils/Extensions/DictionaryExtensions.cs
@@ -130,6 +130,41 @@ namespace ICD.Common.Utils.Extensions
return value;
}
+ ///
+ /// If the key is present in the dictionary return the value, otherwise add a new value to the dictionary and return it.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ [PublicAPI]
+ public static TValue GetOrAddNew([NotNull] this IDictionary extends,
+ [NotNull] TKey key,
+ [NotNull] Func valueFunc)
+ {
+ if (extends == null)
+ throw new ArgumentNullException("extends");
+
+ // ReSharper disable CompareNonConstrainedGenericWithNull
+ if (key == null)
+ // ReSharper restore CompareNonConstrainedGenericWithNull
+ throw new ArgumentNullException("key");
+
+ if (valueFunc == null)
+ throw new ArgumentNullException("valueFunc");
+
+ TValue value;
+ if (!extends.TryGetValue(key, out value))
+ {
+ value = valueFunc();
+ extends.Add(key, value);
+ }
+
+ return value;
+ }
+
///
/// Gets a key for the given value.
///