网站建设价格明细表和网站预算,google下载官方版,巴中 网站建设,wordpress 添加证书C# 实现Lru缓存
LRU 算法全称是最近最少使用算法#xff08;Least Recently Use#xff09;#xff0c;是一种简单的缓存策略。 通常用在对象池等需要频繁获取但是又需要释放不用的地方。
代码实现的基本原理就是使用链表#xff0c;当某个元素被访问时#xff08;Get或…C# 实现Lru缓存
LRU 算法全称是最近最少使用算法Least Recently Use是一种简单的缓存策略。 通常用在对象池等需要频繁获取但是又需要释放不用的地方。
代码实现的基本原理就是使用链表当某个元素被访问时Get或Set就将该元素放到链表的头部或者尾部根据用户自己定义规则即可当达到了缓存的最大容量时对最不常使用的元素进行移除移除的时候可以定义一系列的规则用于判读如何移除是否移除
下面直接贴出来代码供大家参考
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;namespace ET
{public class LruCacheTKey, TValue: IEnumerableKeyValuePairTKey, TValue{private const int DEFAULT_CAPACITY 255;private int capacity;private ReaderWriterLockSlim locker;private DictionaryTKey, TValue dictionary;private LinkedListTKey linkedList;private FuncTKey, TValue, bool checkCanPopFunc;private ActionTKey, TValue popCb;public LruCache(): this(DEFAULT_CAPACITY){}public LruCache(int capacity){this.locker new ReaderWriterLockSlim();this.capacity capacity 0? capacity : DEFAULT_CAPACITY;this.dictionary new DictionaryTKey, TValue(DEFAULT_CAPACITY);this.linkedList new LinkedListTKey();}/// summary/// 设置检测什么条件可以释放/// /summary/// param namefunc/parampublic void SetCheckCanPopCallBack(FuncTKey, TValue, bool func){this.checkCanPopFunc func;}/// summary/// 设置如何释放/// /summary/// param nameaction/parampublic void SetPopCallBack(ActionTKey, TValue action){this.popCb action;}public TValue this[TKey t]{get{if (TryGet(t, out TValue val))return val;throw new ArgumentException();}set{Set(t,value);}}public bool TryGet(TKey key, out TValue value){this.locker.EnterUpgradeableReadLock();try{bool b this.dictionary.TryGetValue(key, out value);if (b){this.locker.EnterWriteLock();try{this.linkedList.Remove(key);this.linkedList.AddFirst(key);}finally{this.locker.ExitWriteLock();}}return b;}finally{this.locker.ExitUpgradeableReadLock();}}public void Set(TKey key, TValue value){this.locker.EnterWriteLock();try{if (this.checkCanPopFunc ! null)this.MakeFreeSpace();this.dictionary[key] value;this.linkedList.Remove(key);this.linkedList.AddFirst(key);//没有设置检测释放条件的话容量超载了就移除if (this.checkCanPopFunc null this.linkedList.Count this.capacity){this.dictionary.Remove(this.linkedList.Last.Value);this.linkedList.RemoveLast();}}finally{this.locker.ExitWriteLock();}}public DictionaryTKey, TValue GetAll(){return this.dictionary;}public void Remove(TKey key){this.locker.EnterWriteLock();try{this.dictionary.Remove(key);this.linkedList.Remove(key);}finally{this.locker.ExitWriteLock();}}public bool TryOnlyGet(TKey key, out TValue value){bool b this.dictionary.TryGetValue(key, out value);return b;}public bool ContainsKey(TKey key){this.locker.EnterReadLock();try{return this.dictionary.ContainsKey(key);}finally{this.locker.ExitReadLock();}}public int Count{get{this.locker.EnterReadLock();try{return this.dictionary.Count;}finally{this.locker.ExitReadLock();}}}public int Capacity{get{this.locker.EnterReadLock();try{return this.capacity;}finally{this.locker.ExitReadLock();}}set{this.locker.EnterUpgradeableReadLock();try{if (value 0 this.capacity ! value){this.locker.EnterWriteLock();try{this.capacity value;while (this.linkedList.Count this.capacity){this.linkedList.RemoveLast();}}finally{this.locker.ExitWriteLock();}}}finally{this.locker.ExitUpgradeableReadLock();}}}public ICollectionTKey Keys{get{this.locker.EnterReadLock();try{return this.dictionary.Keys;}finally{this.locker.ExitReadLock();}}}public ICollectionTValue Values{get{this.locker.EnterReadLock();try{return this.dictionary.Values;}finally{this.locker.ExitReadLock();}}}public void Clear(){this.dictionary.Clear();this.linkedList.Clear();}private void MakeFreeSpace(){LinkedListNodeTKey node this.linkedList.Last;//检测最不常用的10个int max_check_free_times 10; //最大检测空闲次数int cur_check_free_time 0; //当前检测空闲次数while (this.linkedList.Count 1 this.capacity){if (node null)break;LinkedListNodeTKey tuple_prev node.Previous;if (this.checkCanPopFunc null || this.checkCanPopFunc(node.Value, this.dictionary[node.Value])){//可以释放var value this.dictionary[node.Value];this.dictionary.Remove(node.Value);this.linkedList.RemoveLast();this.popCb?.Invoke(node.Value, value);}else{cur_check_free_time;if (cur_check_free_time max_check_free_times){break;}}node tuple_prev;}}public IEnumeratorKeyValuePairTKey, TValue GetEnumerator(){foreach (var item in this.dictionary){yield return item;}}IEnumerator IEnumerable.GetEnumerator(){foreach (var item in this.dictionary){yield return item;}}}
}