IDictionary有LRU实现吗?我想实现一个简单的内存LRU缓存系统,我正在考虑一个基于IDictionary实现的解决方案,它可以处理散列LRU机制。来自java,我有LinkedHashMap的经验,它是满足我需要的LinkedHashMap:我找不到任何类似的.NET解决方案。有没有人开发过它或者有没有人有过这方面的经验?基类库中没有任何东西可以做到这一点。在免费方面,也许像C5的HashedLinkedList这样的东西会起作用。如果您愿意付费,也许可以查看此C#工具包。它包含一个实现。这是我们为我们拥有的网站开发的一个非常简单的快速实现。我们尽可能改进代码,但保持线程安全。我认为代码非常简单,但如果您需要一些解释或指导如何使用它,请不要犹豫。命名空间LRUCache{公共类LRUCache{私有int容量;privateDictionary>>cacheMap=newDictionary>>();私有链表>lruList=新链表>();publicLRUCache(intcapacity){this.capacity=capacity;}[MethodImpl(MethodImplOptions.Synchronized)]publicVget(Kkey){LinkedListNode>node;if(cacheMap.TryGetValue(key,outnode)){Vvalue=node.Value.value;lruList.Remove(节点);lruList.AddLast(节点);返回值;}返回默认值(V);}[MethodImpl(MethodImplOptions.Synchronized)]publicvoidadd(Kkey,Vval){if(cacheMap.Count>=capacity){RemoveFirst();}LRUCacheItemcacheItem=newLRUCacheItem(key,val);LinkedListNode>node=newLinkedListNode>(cacheItem);lruList.AddLast(节点);cacheMap.Add(key,node);}privatevoidRemoveFirst(){//从LRUPriority中移除LinkedListNode>node=lruList.First;lruList.RemoveFirst();//从缓存中移除cacheMap.Remove(node.Value.key);}}类LRUCacheItem{公共LRUCacheItem(Kk,Vv){key=k;值=v;}公钥;公共V值;在谷歌搜索时找到了你的答案,还发现了这个:http://code.google.com/p/csharp-lru-cache/csharp-lru-cache:LRUcachecollectionclasslibraryThisisacollectionclassthatacts作为最近最少使用的缓存。它实现了ICollection,但也公开了其他三个成员:我最近发布了一个名为LurchTable的类来满足对LinkedHashMap的C#变体的需要。可以在此处找到对LurchTable的简短讨论。基本功能:源代码:http://csharptest.net/browse/src/Library/Collections/LurchTable.csGitHub:https://github.com/csharptest/CSharpTest.Net.CollectionsHTML帮助:http://help.csharptest.net/PM>安装包CSharpTest.Net.Collections这采用了Martin的代码和T先生的建议,并使Stylecop变得友好。哦,它还允许在循环出缓存时操作值。命名空间LruCache{使用系统;使用System.Collections.Generic;//////像字典一样存储的最近最少使用的缓存。/////////缓存项的键类型/////////缓存项的类型。/////////来自https://stackoverflow.com/a/3719378/240845///publicclassLruCache{privatereadonlyDictionary>cacheMap=newDictionary>();privatereadonlyLinkedListlruList=newLinkedList();私人只读行动处置;//////初始化///类的新实例。/////////要缓存的最大元素数。/////////当元素循环出缓存时,释放它们。可能为空。///publicLruCache(intcapacity,Actiondispose=null){this.Capacity=capacity;this.dispose=处理;}//////获取缓存的容量。///publicint容量{get;}///获取与指定键关联的值。//////要获取的值的键。/////////什么时候此方法返回,包含与指定///键关联的值,如果找到该键;否则,///参数类型的默认值。此参数传递///未初始化。/////////如果///包含具有指定键的元素,则为真;否则,假的。///publicboolTryGetValue(TKeykey,outTValuevalue){lock(this.cacheMap){LinkedListNode节点;if(this.cacheMap.TryGetValue(key,outnode)){value=node.Value.Value;this.lruList.Remove(节点);this.lruList.AddLast(节点);返回真;}值=默认值(TValue);返回假;}}//////寻找匹配的值。如果未找到,///调用以检索值并将其添加到///缓存中。/////////要查找的值的键。/////////如果找不到则生成一个值。/////////请求的值。///publicTValueGet(TKeykey,FuncvalueGenerator){lock(this.cacheMap){LinkedListNode节点;T值值e;if(this.cacheMap.TryGetValue(key,outnode)){value=node.Value.Value;this.lruList.Remove(节点);this.lruList.AddLast(节点);}else{value=valueGenerator();if(this.cacheMap.Count>=this.Capacity){this.RemoveFirst();}LruCacheItemcacheItem=newLruCacheItem(key,value);node=newLinkedListNode(cacheItem);this.lruList.AddLast(节点);this.cacheMap.Add(key,node);}返回值;}}//////将指定的键和值添加到字典中。/////////要添加的元素的键。/////////要添加的元素的值。对于引用类型,该值可以为null。///publicvoidAdd(TKeykey,TValuevalue){lock(this.cacheMap){if(this.cacheMap.Count>=this.Capacity){this.RemoveFirst();}LruCacheItemcacheItem=newLruCacheItem(key,value);LinkedListNode节点=newLinkedListNode(cacheItem);this.lruList.AddLast(节点);this.cacheMap.Add(key,node);}}privatevoidRemoveFirst(){//从LRUPriorit中移除yLinkedListNodenode=this.lruList.First;this.lruList.RemoveFirst();//从缓存中移除this.cacheMap.Remove(node.Value.Key);//处理this.dispose?.Invoke(node.Value.Value);}privateclassLruCacheItem{publicLruCacheItem(TKeyk,TValuev){this.Key=k;这个.Value=v;}公共TKey密钥{得到;}公共TValue值{得到;我不相信我,我确实看到在各种不相关的项目中多次实现手动滚动(这或多或少证实了这一点。当然至少有一个项目,如果有的话,会使用它)。它的实现非常简单,通常通过创建一个包含Dictionary和List的类来完成。键进入列表(按顺序),项目进入字典。当您向集合中添加新项目时,该函数会检查列表的长度,如果太长则提取最后一个键,然后从字典中删除键和值以进行匹配。真的没那么多。EntLib的缓存应用程序块具有开箱即用的LRU清理选项,可以在内存中。对于您想要的东西,它可能有点重量级。我喜欢劳伦斯的实施。Hashtable+LinkedList是一个很好的解决方案。关于线程,我不会锁定[MethodImpl(MethodImplOptions.Synchronized)],而是使用ReaderWriterLockSlim或自旋锁(因为争用通常很快)。在get函数中,我会检查它是否已经是第一项,而不是总是删除和添加。这使您可以在不阻止其他阅读器的情况下保持阅读器锁定。如果它是一个asp.net应用程序,您可以使用缓存类[1],但您将与其他缓存内容竞争空间,这可能是您想要的,也可能不是您想要的。[1]http://msdn.microsoft.com/en-us/library/system.web.caching.cache.aspx以上是C#学习教程:IDictionary有LRU实现吗?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
