C# 中的 CircularBuffer IDictionary?
我需要一个 CircularBuffer IDictionary。 谁能指出我一个好的开源实现。
因此,一个具有最大容量的 IDictionary,假设配置为 100 个项目,当添加第 101 个项目时,原始第一个项目将从字典中弹出/删除,从而确保项目计数永远不会超过 100。
谢谢
I need a CircularBuffer IDictionary. Can anyone point me to a good open source implementation.
So a IDictionary that has a maximum capacity, say configured to 100 items, which when item 101 is added the original first item is popped/removed from the dictionary thus ensuring the item count never exceeds 100.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不久前,我用 C# 3.0 编写了一个循环缓冲区的完整实现,并在 CodePlex 上发布了源代码。 它遵循 BCL 设计准则,并实现 System.Collections 中的所有适当接口。
我相信使用
Dictionary
作为支持集合而不是List
应该很容易适应。I wrote a complete implementation of a circular buffer in C# 3.0 not too long ago, and release the source on CodePlex. It follows BCL design guidelines, and implements all the appropiate interfaces from
System.Collections
.I believe it should be very easy to adapt to use a
Dictionary<TKey, TValue>
as the backing collection instead of aList<T>
.五分钟谷歌搜索后发现两个:
http://www.codeproject.com/KB/recipes/circularbuffer.aspx
自由性证明:
http://www.codeproject.com/KB/recipes/circularbuffer .aspx?msg=402807#xx402807xx
http://blog.umut.tezduyar .com/2008/06/c-circular-buffer-not-thread-safe.html
Found two after five minutes of googling:
http://www.codeproject.com/KB/recipes/circularbuffer.aspx
Proof of freeness:
http://www.codeproject.com/KB/recipes/circularbuffer.aspx?msg=402807#xx402807xx
http://blog.umut.tezduyar.com/2008/06/c-circular-buffer-not-thread-safe.html
这个怎么样:
How about this:
我不知道有任何这样的实现,但自己实现听起来并不难。 由于字典没有任何固有的顺序,因此字典中的键或值类型都需要有一些属性来表示它插入字典的顺序。 然后,在重写
Add
方法时,它可以检查计数是否达到最大值。 如果是,则查找现有的键值对,找到插入顺序属性最低的键值对,并将其替换为新的键值对。 否则,照常插入新的键值对。I don't know of any such implementations, but it doesn't sound hard to implement yourself. Since dictionaries don't have any inherent order, either the key or the value type in the dictionary would need to have some property representing the order in which it was inserted into the dictionary. Then, in your override of the
Add
method, it could check to see if the count was at the max. If so, then look through the existing key-value pairs to find the one whose insert-order property is lowest and replace it with the new key-value pair. Otherwise, insert the new key-value pair as usual.为了保持 O(1) 插入(删除超过 100 的最旧项目)和 O(1) 查找,您需要一个实现 IDictionary 的类并保留内部有序列表。 如果更关心内存,那么像
SortedList
这样的 BST 实现可能更合适。 无论如何,您的类将包含T[]
和Dictionary
(或SortedList
)。 执行您自己的循环缓冲区索引(简单),并在添加、删除等方法中保持两个集合最新。 您将拥有:使其通用并实现
IDictionary
和IDictionary
因为没有理由不这样做,并且您将获得性能优势。一个主要考虑因素:如何处理重复的键? 我假设您实际上无法保留重复项,因此:
Count
字典,然后使用this[key]
索引器插入键。 如果大小增加,则检查列表是否已达到最大容量,从列表和字典中删除前面的项目,并将新项目添加到后面。 如果字典的大小没有增加,则将项目从列表中的现有位置移动到列表的后面。最后,请注意内部列表保留键,而不是值。 这是为了确保超出列表容量时 O(1) 出队。
To keep O(1) insertion (with removal of the oldest item past 100) and O(1) lookups, you'll need a class that implements IDictionary and keeps an internal ordered list. If memory is more a concern, a BST implementation like
SortedList
could be more appropriate. Anyway, your class will contain both aT[]
and aDictionary<T,K>
(orSortedList<T,K>
). Do your own circular buffer indexing (easy), and keep both collections current in the add, remove, etc. methods. You'll have:Make it generic and implement
IDictionary<T,K>
andIDictionary
since there's no reason not to and you'll get an edge in performance.One major consideration: what do you do about duplicate keys? I'm assuming you can't actually keep the duplicates, so:
Count
of the dictionary, then insert the key using thethis[key]
indexer. if the size increases, then check if the list already has the maximum capacity, remove the front item from the list and dictionary and add the new item to the back. If the dictionary did not increase in size, move the item from its existing place in the list to the back of the list.Finally, note that the internal list keeps keys, not values. This is to ensure O(1) dequeue when the list capacity is exceeded.
我通过 System.Data.Sqlite (http://sqlite .phxsoftware.com/)包装器。 您可以将其存储在磁盘上或作为内存数据库。 您可以选择是否具有唯一键,并让数据库引擎为您处理索引。 您甚至可以为每个键设置多个值。
当您写入表时,请检查是否达到 100 条记录的限制,如果是,则在插入之前删除。 如果您想保留唯一键,SQLite 支持“插入或替换”命令。 也许这不像自定义 IDictionary 派生那么优雅,但它有效、灵活,并且很容易跨线程共享。
I've implemented something akin to this by using a SQLite database table via the System.Data.Sqlite (http://sqlite.phxsoftware.com/) wrapper. You can store it on disk or as an in-memory database. You can choose whether or not to have unique keys and let the database engine handle the indexing for you. You can even have multiple values per key.
As you write to the table, check to see if you're at the 100-record limit, and if so then delete before inserting. SQLite supports an "insert or replace" command if you want to preserve unique keys. Perhaps this isn't as elegant as a custom IDictionary derivation, but it works, it's flexible, and it's readily shared across threads.