diff --git a/SimSharp/Collections/SimplePriorityQueue.cs b/SimSharp/Collections/SimplePriorityQueue.cs
index 6802422..9d17b0c 100644
--- a/SimSharp/Collections/SimplePriorityQueue.cs
+++ b/SimSharp/Collections/SimplePriorityQueue.cs
@@ -27,6 +27,7 @@ THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Linq;
namespace SimSharp {
///
@@ -132,9 +133,7 @@ private class SimpleNode : GenericPriorityQueueNode {
///
public int Count {
get {
- lock (_queue) {
- return _queue.Count;
- }
+ return _queue.Count;
}
}
@@ -146,13 +145,11 @@ private class SimpleNode : GenericPriorityQueueNode {
///
public TItem First {
get {
- lock (_queue) {
- if (_queue.Count <= 0) {
- throw new InvalidOperationException("Cannot call .First on an empty queue");
- }
-
- return _queue.First.Data;
+ if (_queue.Count <= 0) {
+ throw new InvalidOperationException("Cannot call .First on an empty queue");
}
+
+ return _queue.First.Data;
}
}
@@ -161,11 +158,9 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(n)
///
public void Clear() {
- lock (_queue) {
- _queue.Clear();
- _itemToNodesCache.Clear();
- _nullNodesCache.Clear();
- }
+ _queue.Clear();
+ _itemToNodesCache.Clear();
+ _nullNodesCache.Clear();
}
///
@@ -173,12 +168,10 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(1)
///
public bool Contains(TItem item) {
- lock (_queue) {
- if (item == null) {
- return _nullNodesCache.Count > 0;
- }
- return _itemToNodesCache.ContainsKey(item);
+ if (item == null) {
+ return _nullNodesCache.Count > 0;
}
+ return _itemToNodesCache.ContainsKey(item);
}
///
@@ -187,24 +180,22 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public TItem Dequeue() {
- lock (_queue) {
- if (_queue.Count <= 0) {
- throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
- }
-
- SimpleNode node = _queue.Dequeue();
- RemoveFromNodeCache(node);
- return node.Data;
+ if (_queue.Count <= 0) {
+ throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
}
+
+ SimpleNode node = _queue.Dequeue();
+ RemoveFromNodeCache(node);
+ return node.Data;
}
///
- /// Enqueue the item with the given priority, without calling lock(_queue) or AddToNodeCache(node)
+ /// Enqueue the item with the given priority, without calling AddToNodeCache(node)
///
///
///
///
- private SimpleNode EnqueueNoLockOrCache(TItem item, TPriority priority) {
+ private SimpleNode EnqueueNoCache(TItem item, TPriority priority) {
SimpleNode node = new SimpleNode(item);
if (_queue.Count == _queue.MaxSize) {
_queue.Resize(_queue.MaxSize * 2 + 1);
@@ -220,17 +211,15 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public void Enqueue(TItem item, TPriority priority) {
- lock (_queue) {
- IList nodes;
- if (item == null) {
- nodes = _nullNodesCache;
- } else if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- nodes = new List();
- _itemToNodesCache[item] = nodes;
- }
- SimpleNode node = EnqueueNoLockOrCache(item, priority);
- nodes.Add(node);
+ IList nodes;
+ if (item == null) {
+ nodes = _nullNodesCache;
+ } else if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ nodes = new List();
+ _itemToNodesCache[item] = nodes;
}
+ SimpleNode node = EnqueueNoCache(item, priority);
+ nodes.Add(node);
}
///
@@ -240,23 +229,21 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public bool EnqueueWithoutDuplicates(TItem item, TPriority priority) {
- lock (_queue) {
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count > 0) {
- return false;
- }
- nodes = _nullNodesCache;
- } else if (_itemToNodesCache.ContainsKey(item)) {
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count > 0) {
return false;
- } else {
- nodes = new List();
- _itemToNodesCache[item] = nodes;
}
- SimpleNode node = EnqueueNoLockOrCache(item, priority);
- nodes.Add(node);
- return true;
+ nodes = _nullNodesCache;
+ } else if (_itemToNodesCache.ContainsKey(item)) {
+ return false;
+ } else {
+ nodes = new List();
+ _itemToNodesCache[item] = nodes;
}
+ SimpleNode node = EnqueueNoCache(item, priority);
+ nodes.Add(node);
+ return true;
}
///
@@ -266,27 +253,25 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public void Remove(TItem item) {
- lock (_queue) {
- SimpleNode removeMe;
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count == 0) {
- throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
- }
- removeMe = _nullNodesCache[0];
- nodes = _nullNodesCache;
- } else {
- if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
- }
- removeMe = nodes[0];
- if (nodes.Count == 1) {
- _itemToNodesCache.Remove(item);
- }
+ SimpleNode removeMe;
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count == 0) {
+ throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
+ }
+ removeMe = _nullNodesCache[0];
+ nodes = _nullNodesCache;
+ } else {
+ if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
+ }
+ removeMe = nodes[0];
+ if (nodes.Count == 1) {
+ _itemToNodesCache.Remove(item);
}
- _queue.Remove(removeMe);
- nodes.Remove(removeMe);
}
+ _queue.Remove(removeMe);
+ nodes.Remove(removeMe);
}
///
@@ -298,13 +283,11 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public void UpdatePriority(TItem item, TPriority priority) {
- lock (_queue) {
- SimpleNode updateMe = GetExistingNode(item);
- if (updateMe == null) {
- throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + item);
- }
- _queue.UpdatePriority(updateMe, priority);
+ SimpleNode updateMe = GetExistingNode(item);
+ if (updateMe == null) {
+ throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + item);
}
+ _queue.UpdatePriority(updateMe, priority);
}
///
@@ -316,13 +299,11 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(1)
///
public TPriority GetPriority(TItem item) {
- lock (_queue) {
- SimpleNode findMe = GetExistingNode(item);
- if (findMe == null) {
- throw new InvalidOperationException("Cannot call GetPriority() on a node which is not enqueued: " + item);
- }
- return findMe.Priority;
+ SimpleNode findMe = GetExistingNode(item);
+ if (findMe == null) {
+ throw new InvalidOperationException("Cannot call GetPriority() on a node which is not enqueued: " + item);
}
+ return findMe.Priority;
}
#region Try* methods for multithreading
@@ -331,15 +312,13 @@ private class SimpleNode : GenericPriorityQueueNode {
/// Returns true if successful, false otherwise
/// O(1)
public bool TryFirst(out TItem first) {
- lock (_queue) {
- if (_queue.Count <= 0) {
- first = default(TItem);
- return false;
- }
-
- first = _queue.First.Data;
- return true;
+ if (_queue.Count <= 0) {
+ first = default(TItem);
+ return false;
}
+
+ first = _queue.First.Data;
+ return true;
}
///
@@ -349,17 +328,15 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public bool TryDequeue(out TItem first) {
- lock (_queue) {
- if (_queue.Count <= 0) {
- first = default(TItem);
- return false;
- }
-
- SimpleNode node = _queue.Dequeue();
- first = node.Data;
- RemoveFromNodeCache(node);
- return true;
+ if (_queue.Count <= 0) {
+ first = default(TItem);
+ return false;
}
+
+ SimpleNode node = _queue.Dequeue();
+ first = node.Data;
+ RemoveFromNodeCache(node);
+ return true;
}
///
@@ -370,28 +347,26 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public bool TryRemove(TItem item) {
- lock (_queue) {
- SimpleNode removeMe;
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count == 0) {
- return false;
- }
- removeMe = _nullNodesCache[0];
- nodes = _nullNodesCache;
- } else {
- if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- return false;
- }
- removeMe = nodes[0];
- if (nodes.Count == 1) {
- _itemToNodesCache.Remove(item);
- }
+ SimpleNode removeMe;
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count == 0) {
+ return false;
+ }
+ removeMe = _nullNodesCache[0];
+ nodes = _nullNodesCache;
+ } else {
+ if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ return false;
+ }
+ removeMe = nodes[0];
+ if (nodes.Count == 1) {
+ _itemToNodesCache.Remove(item);
}
- _queue.Remove(removeMe);
- nodes.Remove(removeMe);
- return true;
}
+ _queue.Remove(removeMe);
+ nodes.Remove(removeMe);
+ return true;
}
///
@@ -404,14 +379,12 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(log n)
///
public bool TryUpdatePriority(TItem item, TPriority priority) {
- lock (_queue) {
- SimpleNode updateMe = GetExistingNode(item);
- if (updateMe == null) {
- return false;
- }
- _queue.UpdatePriority(updateMe, priority);
- return true;
+ SimpleNode updateMe = GetExistingNode(item);
+ if (updateMe == null) {
+ return false;
}
+ _queue.UpdatePriority(updateMe, priority);
+ return true;
}
///
@@ -424,28 +397,18 @@ private class SimpleNode : GenericPriorityQueueNode {
/// O(1)
///
public bool TryGetPriority(TItem item, out TPriority priority) {
- lock (_queue) {
- SimpleNode findMe = GetExistingNode(item);
- if (findMe == null) {
- priority = default(TPriority);
- return false;
- }
- priority = findMe.Priority;
- return true;
+ SimpleNode findMe = GetExistingNode(item);
+ if (findMe == null) {
+ priority = default(TPriority);
+ return false;
}
+ priority = findMe.Priority;
+ return true;
}
#endregion
public IEnumerator GetEnumerator() {
- List queueData = new List();
- lock (_queue) {
- //Copy to a separate list because we don't want to 'yield return' inside a lock
- foreach (var node in _queue) {
- queueData.Add(node.Data);
- }
- }
-
- return queueData.GetEnumerator();
+ return _queue.Select(x => x.Data).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
@@ -453,26 +416,24 @@ private class SimpleNode : GenericPriorityQueueNode {
}
public bool IsValidQueue() {
- lock (_queue) {
- // Check all items in cache are in the queue
- foreach (IList nodes in _itemToNodesCache.Values) {
- foreach (SimpleNode node in nodes) {
- if (!_queue.Contains(node)) {
- return false;
- }
- }
- }
-
- // Check all items in queue are in cache
- foreach (SimpleNode node in _queue) {
- if (GetExistingNode(node.Data) == null) {
+ // Check all items in cache are in the queue
+ foreach (IList nodes in _itemToNodesCache.Values) {
+ foreach (SimpleNode node in nodes) {
+ if (!_queue.Contains(node)) {
return false;
}
}
+ }
- // Check queue structure itself
- return _queue.IsValidQueue();
+ // Check all items in queue are in cache
+ foreach (SimpleNode node in _queue) {
+ if (GetExistingNode(node.Data) == null) {
+ return false;
+ }
}
+
+ // Check queue structure itself
+ return _queue.IsValidQueue();
}
}
@@ -590,9 +551,7 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
///
public int Count {
get {
- lock (_queue) {
- return _queue.Count;
- }
+ return _queue.Count;
}
}
@@ -604,13 +563,11 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
///
public TItem First {
get {
- lock (_queue) {
- if (_queue.Count <= 0) {
- throw new InvalidOperationException("Cannot call .First on an empty queue");
- }
-
- return _queue.First.Data;
+ if (_queue.Count <= 0) {
+ throw new InvalidOperationException("Cannot call .First on an empty queue");
}
+
+ return _queue.First.Data;
}
}
@@ -619,11 +576,9 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(n)
///
public void Clear() {
- lock (_queue) {
- _queue.Clear();
- _itemToNodesCache.Clear();
- _nullNodesCache.Clear();
- }
+ _queue.Clear();
+ _itemToNodesCache.Clear();
+ _nullNodesCache.Clear();
}
///
@@ -631,12 +586,10 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(1)
///
public bool Contains(TItem item) {
- lock (_queue) {
- if (item == null) {
- return _nullNodesCache.Count > 0;
- }
- return _itemToNodesCache.ContainsKey(item);
+ if (item == null) {
+ return _nullNodesCache.Count > 0;
}
+ return _itemToNodesCache.ContainsKey(item);
}
///
@@ -645,23 +598,21 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public TItem Dequeue() {
- lock (_queue) {
- if (_queue.Count <= 0) {
- throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
- }
-
- SimpleNode node = _queue.Dequeue();
- RemoveFromNodeCache(node);
- return node.Data;
+ if (_queue.Count <= 0) {
+ throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
}
+
+ SimpleNode node = _queue.Dequeue();
+ RemoveFromNodeCache(node);
+ return node.Data;
}
///
- /// Enqueue the item with the given priority, without calling lock(_queue) or AddToNodeCache(node)
+ /// Enqueue the item with the given priority, without calling AddToNodeCache(node)
///
///
///
- private SimpleNode EnqueueNoLockOrCache(TItem item) {
+ private SimpleNode EnqueueNoCache(TItem item) {
SimpleNode node = new SimpleNode(item, _comparer);
if (_queue.Count == _queue.MaxSize) {
_queue.Resize(_queue.MaxSize * 2 + 1);
@@ -677,17 +628,15 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public void Enqueue(TItem item) {
- lock (_queue) {
- IList nodes;
- if (item == null) {
- nodes = _nullNodesCache;
- } else if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- nodes = new List();
- _itemToNodesCache[item] = nodes;
- }
- SimpleNode node = EnqueueNoLockOrCache(item);
- nodes.Add(node);
+ IList nodes;
+ if (item == null) {
+ nodes = _nullNodesCache;
+ } else if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ nodes = new List();
+ _itemToNodesCache[item] = nodes;
}
+ SimpleNode node = EnqueueNoCache(item);
+ nodes.Add(node);
}
///
@@ -697,23 +646,21 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public bool EnqueueWithoutDuplicates(TItem item) {
- lock (_queue) {
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count > 0) {
- return false;
- }
- nodes = _nullNodesCache;
- } else if (_itemToNodesCache.ContainsKey(item)) {
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count > 0) {
return false;
- } else {
- nodes = new List();
- _itemToNodesCache[item] = nodes;
}
- SimpleNode node = EnqueueNoLockOrCache(item);
- nodes.Add(node);
- return true;
+ nodes = _nullNodesCache;
+ } else if (_itemToNodesCache.ContainsKey(item)) {
+ return false;
+ } else {
+ nodes = new List();
+ _itemToNodesCache[item] = nodes;
}
+ SimpleNode node = EnqueueNoCache(item);
+ nodes.Add(node);
+ return true;
}
///
@@ -723,27 +670,25 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public void Remove(TItem item) {
- lock (_queue) {
- SimpleNode removeMe;
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count == 0) {
- throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
- }
- removeMe = _nullNodesCache[0];
- nodes = _nullNodesCache;
- } else {
- if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
- }
- removeMe = nodes[0];
- if (nodes.Count == 1) {
- _itemToNodesCache.Remove(item);
- }
+ SimpleNode removeMe;
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count == 0) {
+ throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
+ }
+ removeMe = _nullNodesCache[0];
+ nodes = _nullNodesCache;
+ } else {
+ if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item);
+ }
+ removeMe = nodes[0];
+ if (nodes.Count == 1) {
+ _itemToNodesCache.Remove(item);
}
- _queue.Remove(removeMe);
- nodes.Remove(removeMe);
}
+ _queue.Remove(removeMe);
+ nodes.Remove(removeMe);
}
///
@@ -755,13 +700,11 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public void UpdatePriority(TItem item) {
- lock (_queue) {
- SimpleNode updateMe = GetExistingNode(item);
- if (updateMe == null) {
- throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + item);
- }
- _queue.UpdatePriority(updateMe);
+ SimpleNode updateMe = GetExistingNode(item);
+ if (updateMe == null) {
+ throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + item);
}
+ _queue.UpdatePriority(updateMe);
}
#region Try* methods for multithreading
@@ -770,15 +713,13 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// Returns true if successful, false otherwise
/// O(1)
public bool TryFirst(out TItem first) {
- lock (_queue) {
- if (_queue.Count <= 0) {
- first = default(TItem);
- return false;
- }
-
- first = _queue.First.Data;
- return true;
+ if (_queue.Count <= 0) {
+ first = default(TItem);
+ return false;
}
+
+ first = _queue.First.Data;
+ return true;
}
///
@@ -788,17 +729,15 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public bool TryDequeue(out TItem first) {
- lock (_queue) {
- if (_queue.Count <= 0) {
- first = default(TItem);
- return false;
- }
-
- SimpleNode node = _queue.Dequeue();
- first = node.Data;
- RemoveFromNodeCache(node);
- return true;
+ if (_queue.Count <= 0) {
+ first = default(TItem);
+ return false;
}
+
+ SimpleNode node = _queue.Dequeue();
+ first = node.Data;
+ RemoveFromNodeCache(node);
+ return true;
}
///
@@ -809,28 +748,26 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public bool TryRemove(TItem item) {
- lock (_queue) {
- SimpleNode removeMe;
- IList nodes;
- if (item == null) {
- if (_nullNodesCache.Count == 0) {
- return false;
- }
- removeMe = _nullNodesCache[0];
- nodes = _nullNodesCache;
- } else {
- if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
- return false;
- }
- removeMe = nodes[0];
- if (nodes.Count == 1) {
- _itemToNodesCache.Remove(item);
- }
+ SimpleNode removeMe;
+ IList nodes;
+ if (item == null) {
+ if (_nullNodesCache.Count == 0) {
+ return false;
+ }
+ removeMe = _nullNodesCache[0];
+ nodes = _nullNodesCache;
+ } else {
+ if (!_itemToNodesCache.TryGetValue(item, out nodes)) {
+ return false;
+ }
+ removeMe = nodes[0];
+ if (nodes.Count == 1) {
+ _itemToNodesCache.Remove(item);
}
- _queue.Remove(removeMe);
- nodes.Remove(removeMe);
- return true;
}
+ _queue.Remove(removeMe);
+ nodes.Remove(removeMe);
+ return true;
}
///
@@ -843,27 +780,17 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
/// O(log n)
///
public bool TryUpdatePriority(TItem item) {
- lock (_queue) {
- SimpleNode updateMe = GetExistingNode(item);
- if (updateMe == null) {
- return false;
- }
- _queue.UpdatePriority(updateMe);
- return true;
+ SimpleNode updateMe = GetExistingNode(item);
+ if (updateMe == null) {
+ return false;
}
+ _queue.UpdatePriority(updateMe);
+ return true;
}
#endregion
public IEnumerator GetEnumerator() {
- List queueData = new List();
- lock (_queue) {
- //Copy to a separate list because we don't want to 'yield return' inside a lock
- foreach (var node in _queue) {
- queueData.Add(node.Data);
- }
- }
-
- return queueData.GetEnumerator();
+ return _queue.Select(x => x.Data).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
@@ -871,26 +798,24 @@ private class SimpleNode : GenericPriorityQueueNode, IComparable, IC
}
public bool IsValidQueue() {
- lock (_queue) {
- // Check all items in cache are in the queue
- foreach (IList nodes in _itemToNodesCache.Values) {
- foreach (SimpleNode node in nodes) {
- if (!_queue.Contains(node)) {
- return false;
- }
- }
- }
-
- // Check all items in queue are in cache
- foreach (SimpleNode node in _queue) {
- if (GetExistingNode(node.Data) == null) {
+ // Check all items in cache are in the queue
+ foreach (IList nodes in _itemToNodesCache.Values) {
+ foreach (SimpleNode node in nodes) {
+ if (!_queue.Contains(node)) {
return false;
}
}
+ }
- // Check queue structure itself
- return _queue.IsValidQueue();
+ // Check all items in queue are in cache
+ foreach (SimpleNode node in _queue) {
+ if (GetExistingNode(node.Data) == null) {
+ return false;
+ }
}
+
+ // Check queue structure itself
+ return _queue.IsValidQueue();
}
}
}
\ No newline at end of file