aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiguel Costa <miguel.costa@qt.io>2021-05-27 09:37:29 +0200
committerMiguel Costa <miguel.costa@qt.io>2021-06-02 09:04:23 +0000
commit32579db3ccb3f4fa28e010bf58ac2cd8e9f1aad2 (patch)
tree53fb9e2c445111d27e122ea29186c2f27eab2418 /src
parentdb326690ec282f06757cacce40710281122e31d8 (diff)
Add Count, IsEmpty, Remove to PriorityQueue
Made the following changes to the PriorityQueue class: * Added Count property (≈ O(1)) with the number of items in the queue. * Added IsEmpty property, based on Count. * Added Remove method (≈ O(log n)) to remove an item from the queue. Change-Id: Ic94f8f02fdfcf99d47ee033689681ebcc7fa9cde Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qtvstools/Common/PriorityQueue.cs55
-rw-r--r--src/tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs11
2 files changed, 49 insertions, 17 deletions
diff --git a/src/qtvstools/Common/PriorityQueue.cs b/src/qtvstools/Common/PriorityQueue.cs
index 2a630273..dce56bec 100644
--- a/src/qtvstools/Common/PriorityQueue.cs
+++ b/src/qtvstools/Common/PriorityQueue.cs
@@ -54,6 +54,8 @@ namespace QtVsTools
SortedDictionary<TPriority, T> ItemsByPriority { get; set; }
Dictionary<object, TPriority> ItemPriority { get; set; }
T Head { get; set; }
+ public int Count { get; private set; }
+ public bool IsEmpty => (Count == 0);
IEnumerable<T> Items => ThreadSafe(() => ItemsByPriority.Values.ToList());
IEnumerator<T> IEnumerable<T>.GetEnumerator() => Items.GetEnumerator();
@@ -61,24 +63,27 @@ namespace QtVsTools
Func<T, object> GetItemKey { get; set; }
- public BasePriorityQueue()
- {
- Clear();
- GetItemKey = (x => x);
- }
+ public BasePriorityQueue() : this(x => x)
+ { }
public BasePriorityQueue(Func<T, object> getItemKey)
{
- Clear();
+ ItemsByPriority = new SortedDictionary<TPriority, T>();
+ ItemPriority = new Dictionary<object, TPriority>();
+ Head = default(T);
+ Count = 0;
GetItemKey = getItemKey;
}
public void Clear()
{
lock (CriticalSection) {
- ItemsByPriority = new SortedDictionary<TPriority, T>();
- ItemPriority = new Dictionary<object, TPriority>();
+ if (Count == 0)
+ return;
+ ItemsByPriority.Clear();
+ ItemPriority.Clear();
Head = default(T);
+ Count = 0;
}
}
@@ -101,11 +106,14 @@ namespace QtVsTools
if (ItemsByPriority.TryGetValue(priority, out oldItem) && !item.Equals(oldItem))
throw new InvalidOperationException("An item with the same priority exists.");
TPriority oldPriority;
- if (ItemPriority.TryGetValue(GetItemKey(item), out oldPriority))
+ if (ItemPriority.TryGetValue(GetItemKey(item), out oldPriority)) {
ItemsByPriority.Remove(oldPriority);
+ --Count;
+ }
ItemPriority[GetItemKey(item)] = priority;
ItemsByPriority[priority] = item;
Head = ItemsByPriority.First().Value;
+ ++Count;
}
}
@@ -113,7 +121,7 @@ namespace QtVsTools
{
lock (CriticalSection) {
result = Head;
- return ItemsByPriority.Any();
+ return Count > 0;
}
}
@@ -127,18 +135,31 @@ namespace QtVsTools
}
}
+ public void Remove(T item)
+ {
+ lock (CriticalSection) {
+ object key = GetItemKey(item);
+ if (key == null)
+ return;
+ ItemsByPriority.Remove(ItemPriority[key]);
+ ItemPriority.Remove(key);
+ --Count;
+ if (key == GetItemKey(Head)) {
+ if (IsEmpty)
+ Head = default(T);
+ else
+ Head = ItemsByPriority.First().Value;
+ }
+ }
+ }
+
public bool TryDequeue(out T result)
{
lock (CriticalSection) {
result = Head;
- if (!ItemsByPriority.Any())
+ if (IsEmpty)
return false;
- ItemsByPriority.Remove(ItemPriority[GetItemKey(result)]);
- ItemPriority.Remove(GetItemKey(result));
- if (ItemsByPriority.Any())
- Head = ItemsByPriority.First().Value;
- else
- Head = default(T);
+ Remove(Head);
return true;
}
}
diff --git a/src/tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs b/src/tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
index ef46a1e1..8dbd0236 100644
--- a/src/tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
+++ b/src/tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
@@ -215,5 +215,16 @@ namespace QtVsTools.Test.PriorityQueue
q.Enqueue("w");
Assert.IsTrue(string.Join("", q) == "bxzw");
}
+
+ [TestMethod]
+ public void TestRemove()
+ {
+ var q = new PunisherQueue<string>();
+ q.Enqueue("a");
+ q.Enqueue("b");
+ q.Enqueue("c");
+ q.Remove("b");
+ Assert.IsTrue(string.Join("", q) == "ac");
+ }
}
}