Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SimplePriorityQueue.Try...() overloads that expose priority as out parameter #55

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
75 changes: 74 additions & 1 deletion Priority Queue/SimplePriorityQueue.cs
Expand Up @@ -423,7 +423,36 @@ public bool TryDequeue(out TItem first)
}

/// <summary>
/// Attempts to remove an item from the queue. The item does not need to be the head of the queue.
/// Removes the head of the queue (node with minimum priority; ties are broken by order of insertion),
/// and sets it to first along with its priority.
/// Useful for multi-threading, where the queue may become empty between calls to Contains(), GetPriority() and Dequeue()
/// Returns true if successful; false if queue was empty
/// O(log n)
/// </summary>
public bool TryDequeue(out TItem first, out TPriority firstPriority)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a duplicate method. Create method, that dequeues simple node (private bool TryDequeue(out SimpleNode node)) and use it in both TryDequeue overrides

{
if (_queue.Count > 0)
{
lock (_queue)
{
if (_queue.Count > 0)
{
SimpleNode node = _queue.Dequeue();
first = node.Data;
firstPriority = node.Priority;
RemoveFromNodeCache(node);
return true;
}
}
}

first = default(TItem);
firstPriority = default(TPriority);
return false;
}

/// <summary>
/// Attempts to remove an item from the queue. The item does not need to be the head of the queue.
/// Useful for multi-threading, where the queue may become empty between calls to Contains() and Remove()
/// Returns true if the item was successfully removed, false if it wasn't in the queue.
/// If multiple copies of the item are enqueued, only the first one is removed.
Expand Down Expand Up @@ -462,6 +491,50 @@ public bool TryRemove(TItem item)
}
}

/// <summary>
/// Attempts to remove an item from the queue. The item does not need to be the head of the queue.
/// Useful for multi-threading, where the queue may become empty between calls to Contains(), GetPriority() and Remove()
/// Returns true if the item was successfully removed, false if it wasn't in the queue.
/// Assigns priority to priority of removed item if successfully removed.
/// If multiple copies of the item are enqueued, only the first one is removed.
/// O(log n)
/// </summary>
public bool TryRemove(TItem item, out TPriority priority)
{
lock (_queue)
{
SimpleNode removeMe;
IList<SimpleNode> nodes;
if (item == null)
{
if (_nullNodesCache.Count == 0)
{
priority = default(TPriority);
return false;
}
removeMe = _nullNodesCache[0];
nodes = _nullNodesCache;
}
else
{
if (!_itemToNodesCache.TryGetValue(item, out nodes))
{
priority = default(TPriority);
return false;
}
removeMe = nodes[0];
if (nodes.Count == 1)
{
_itemToNodesCache.Remove(item);
}
}
_queue.Remove(removeMe);
nodes.Remove(removeMe);
priority = removeMe.Priority;
return true;
}
}

/// <summary>
/// Call this method to change the priority of an item.
/// Useful for multi-threading, where the queue may become empty between calls to Contains() and UpdatePriority()
Expand Down