2010-10-19 10 views
6

मूल रूप से मैं एक MSMQ दर्पण हैं चाहते हैं, लेकिन, स्मृति में किया जाएगा, क्योंकि यह एक प्रक्रिया में इस्तेमाल किया जा रहा है डेटा संरचना। एमएसएमक्यू का मिरर करके मेरा मतलब है कि आप ऑब्जेक्ट्स को एनक्यू करेंगे, फिर आप या तो ऑब्जेक्ट को डिस्क्वाय कर सकते हैं या एक कुंजी का उपयोग करके उन्हें पुनर्प्राप्त कर सकते हैं। यहां मुझे प्रारंभिक प्रयास है। इस प्रयास के साथ मेरी मुख्य समस्या यह है कि आईडी द्वारा प्राप्त अक्सर उपयोग किया जाएगा और इसलिए कतार में बहुत सारी "मृत" वस्तुएं समाप्त हो जाएंगी।मैं क्यूई डिक्शनरी, सी # में कतार और शब्दकोश का संयोजन कैसे कार्यान्वित करूं?

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); 
     } 
    } 
} 
+0

"कतार का एक बहुत हो रही हो जाएंगे" मृत "यह में वस्तुओं" - तो यह एक कतार के बहुत .... –

+0

क्यों आप "मृत" वस्तुओं मिलेगा हो सकता है? आप * दूर करने के लिए * 'Get' में कुछ भी ... और अगर आप को धोखा दे नहीं कर रहे हैं * कि *, आप' while' पाश ... जो btw शायद ही रक्षा करनी चाहिए की जरूरत नहीं हैं नहीं है एक खाली कतार –

+0

@Marc - मुझे लगता है कि ओपी विधि वह है जो ओपी मदद के लिए पूछ रही है क्योंकि आप कतार से मनमानी आइटम को नहीं हटा सकते हैं। – Josh

उत्तर

6

आंतरिक रूप से एक कतार का उपयोग करने के बजाय, आप एक लिंक्डलिस्ट का उपयोग कर सकते हैं। फिर शब्दकोश में आप कुंजी और लिंक्ड लिस्ट नोड स्टोर कर सकते हैं। फिर जब आप शब्दकोश से आइटम को हटाते हैं, तो आप लिंक की गई सूची से 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); 
    } 
    } 
} 
+0

से ऊपर कोड तय किया है जो मुझे लगता है कि अच्छी तरह से काम करेगा। मैं भी चाहूंगा "_dictionary.Remove (कुंजी);" डेक्यू (टीके कुंजी) विधि में। –

0

क्या होगा यदि आप कतार के रूप में और कहा कि कार्य करने के लिए एक डबल लिंक्ड सूची का इस्तेमाल किया जिस तरह से आप Enqueue, Dequeue, और विशेष रूप से Get विधि का पूर्ण नियंत्रण प्राप्त कर सकते हैं। तो गेट विधि में आप डबल-लिंक्ड सूची से कुंजी को आसानी से हटा सकते हैं।

1

वैसे आपका ऑब्जेक्ट एक्ट कतार की तरह वास्तव में क्यूई क्लास का आंतरिक संग्रहण के रूप में उपयोग किए बिना कतार की तरह कर सकता है। कितने आइटम आप रखने पर योजना पर निर्भर करता है, यह सिर्फ एक भी LinkedList (टी) बनाए रखने के लिए के बजाय दोनों एक LinkedList (टी) और एक शब्दकोश में आइटम के भंडारण आसान हो सकता है (कश्मीर, वी)।

लेकिन मूल रूप से, बजाय एक कतार आंतरिक रूप से उपयोग करने का है, तो आप एक LinkedList (टी) इस्तेमाल कर सकते हैं और बस सूची और सूची के सामने से विपंक्ति के अंत में नए आइटम जोड़ते। जब आप कुंजी के द्वारा एक खोजने की जरूरत है, तो आप सिर्फ मिलान कुंजी के लिए सूची स्कैन कर सकते हैं या आइटम की संख्या इस खराब प्रदर्शन करता है, तो आप एक शब्दकोश के साथ अपने भंडारण अप दोगुनी हो सकती है (कश्मीर, LinkedListNode (टी)) और प्रयोग अपने कुंजी लुकअप के लिए शब्दकोश।

संबंधित मुद्दे