簡體   English   中英

C#中的CircularBuffer IDictionary?

[英]CircularBuffer IDictionary in C#?

我需要一個CircularBuffer IDictionary。 任何人都可以指出我一個良好的開源實現。

所以IDictionary具有最大容量,比如說配置為100個項目,當添加項目101時,從字典中彈出/刪除原始的第一個項目,從而確保項目計數永遠不會超過100。

謝謝

要保持O(1)插入(刪除最舊的項目超過100)和O(1)查找,您將需要一個實現IDictionary的類保留內部有序列表。 如果內存更受關注,那么像SortedList這樣的BST實現可能更合適。 無論如何,你的類將包含T[]Dictionary<T,K> (或SortedList<T,K> )。 執行您自己的循環緩沖區索引(簡單),並在添加,刪除等方法中保持兩個集合的最新狀態。 你有:

  • O(1)入隊(后面)
  • O(n)插入違反添加順序(因為你必須使數組保持最新); 無論如何你可能永遠都不需要這個
  • O(1)出隊(從前面)
  • O(1)或O(log n)鍵控查找

使它成為通用的並實現IDictionary<T,K>IDictionary因為沒有理由不這樣做,你將獲得性能優勢。

一個主要考慮因素 :你如何處理重復鍵? 我假設你實際上不能保留重復,所以:

  • 拋出一個異常(如果從來沒有重復的鍵,那么插入兩次只是一個錯誤)
  • 向后移動:檢查字典的Count ,然后使用this[key]索引器插入密鑰。 如果大小增加,則檢查列表是否已具有最大容量,從列表和字典中刪除前項並將新項添加到后面。 如果字典的大小沒有增加,請將項目從列表中的現有位置移動到列表的后面。
  • 不移動時覆蓋:與上一項相同,但您不必亂用列表。

最后,請注意內部列表保留鍵,而不是值。 這是為了確保在超出列表容量時O(1)出列。

谷歌搜索后發現兩個五分鍾:

我不知道任何這樣的實現,但它自己聽起來並不難。 由於字典沒有任何固有順序,因此字典中的鍵或值類型需要具有一些屬性,表示它插入字典的順序。 然后,在重寫Add方法時,它可以檢查計數是否為最大值。 如果是,則查看現有的鍵值對以查找其insert-order屬性最低的那個,並將其替換為新的鍵值對。 否則,像往常一樣插入新的鍵值對。

我不久前在C#3.0中編寫了一個循環緩沖區的完整實現,並在CodePlex上發布了源代碼。 它遵循BCL設計指南,並實現System.Collections所有適當接口。

我相信應該很容易適應使用Dictionary<TKey, TValue>作為后台集合而不是List<T>

這個怎么樣:

    public class CircularDictionary<TKey, TValue> : Dictionary<TKey, TValue>
    {
        private Queue<TKey> m_ItemInsertList = new Queue<TKey>();
        private int m_ItemsToHold = 100;

        public int ItemsToHold
        {
            get { return m_ItemsToHold; }
            set {
                if (value < 1)
                    throw new ArgumentException("Items to hold must be at least 1");
                m_ItemsToHold = value; 
            }
        }

        public new void Add(TKey key, TValue value)
        {
            base.Add(key, value);
            if (m_ItemInsertList.Count == m_ItemsToHold)
                base.Remove(m_ItemInsertList.Dequeue());
            m_ItemInsertList.Enqueue(key);
        }
    }

我通過System.Data.Sqlite( http://sqlite.phxsoftware.com/ )包裝器使用SQLite數據庫表實現了類似於此的東西。 您可以將其存儲在磁盤上或作為內存數據庫。 您可以選擇是否具有唯一鍵,並讓數據庫引擎為您處理索引。 您甚至可以為每個鍵設置多個值。

當您寫入表格時,請檢查您是否處於100個記錄限制,如果是,則在插入之前刪除。 如果要保留唯一鍵,SQLite支持“插入或替換”命令。 也許這不像自定義IDictionary派生那么優雅,但它可以工作,它很靈活,並且可以在線程之間輕松共享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM