[英]How would I implement a Queue of type Dictionary<int, string> and iterate/enqueue/dequeue in C#
[英]How would I implement a QueueDictionary, a combination of Queue and Dictionary in C#?
基本上我想要的數據結構將鏡像MSMQ,但會在內存中,因為它在一個進程中使用。 通過鏡像MSMQ,我的意思是你會將對象排隊,然后你可以將對象出列或使用密鑰檢索它們。 這是我最初的嘗試。 這個嘗試的主要問題是Get by id會頻繁使用,因此隊列最終會有很多“死”對象。
public class QueueDictionary<TKey, TValue>
{
private readonly Queue _queue = new Queue();
private readonly Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
private readonly object _syncRoot = new object();
public TValue Dequeue()
{
lock (_syncRoot)
{
TKey key = (TKey)_queue.Dequeue();
while (!_dictionary.ContainsKey(key))
key = (TKey)_queue.Dequeue();
return _dictionary[key];
}
}
public TValue Get(TKey key)
{
lock (_syncRoot)
{
TValue result = _dictionary[key];
_dictionary.Remove(key);
return result;
}
}
public void Enqueue(TKey key, TValue value)
{
lock (_syncRoot)
{
_dictionary.Add(key, value);
_queue.Enqueue(key);
}
}
}
您可以使用LinkedList,而不是在內部使用Queue。 然后在Dictionary中,您可以存儲Key和LinkedListNode。 然后,當您從字典中刪除該項時,您可以取消鏈接列表中的LinkedListNode鏈接。 當然,你放棄了隊列的局部性,但獲得了隨機訪問的性能。
這是一個快速而骯臟的例子,沒有經過測試,因此可以解釋任何錯誤和錯誤檢查。 例如,您應檢查隊列是否為空,確保具有相同鍵的項目尚未在字典中等。
public class QueueDictionary<TKey, TValue>
{
private readonly LinkedList<Tuple<TKey, TValue>> _queue =
new LinkedList<Tuple<TKey, TValue>>();
private readonly Dictionary<TKey, LinkedListNode<Tuple<TKey, TValue>>>
_dictionary = new Dictionary<TKey, LinkedListNode<Tuple<TKey, TValue>>>();
private readonly object _syncRoot = new object();
public TValue Dequeue()
{
lock (_syncRoot)
{
Tuple<TKey, TValue> item = _queue.First();
_queue.RemoveFirst();
_dictionary.Remove(item.Item1);
return item.Item2;
}
}
public TValue Dequeue(TKey key)
{
lock (_syncRoot)
{
LinkedListNode<Tuple<TKey, TValue>> node = _dictionary[key];
_dictionary.Remove(key);
_queue.Remove(node);
return node.Value.Item2;
}
}
public void Enqueue(TKey key, TValue value)
{
lock (_syncRoot)
{
LinkedListNode<Tuple<TKey, TValue>> node =
_queue.AddLast(new Tuple<TKey, TValue>(key, value));
_dictionary.Add(key, node);
}
}
}
那么你的對象可以像隊列實際上並沒有使用Queue類作為它的內部存儲。 根據您計划保留的項目數量,可能更容易維護單個LinkedList(T),而不是將項目存儲在LinkedList(T)和Dictionary(K,V)中。
但基本上,您可以使用LinkedList(T)而不是在內部使用Queue,只需將新項添加到列表的末尾,然后從列表的前面出列。 當你需要通過鍵找到一個時,你可以只掃描列表中的匹配鍵,或者如果項目數量使這個表現不佳,你可以用一個字典(K,LinkedListNode(T))加倍你的存儲並使用密鑰查找的字典。
如果您使用雙鏈表作為隊列,那么您可以完全控制Enqueue,Dequeue,特別是Get方法。 因此,在Get方法中,您只需從雙鏈表中刪除鍵即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.