• 本地缓存类(LRU Cache),喜欢的朋友拿去用


    这是一个固定长度的双向链表,没有闭合,当然是起初没写成闭合的。

    怎么缓存的呢? 就是比如 长度是3000,你缓存一篇文章 就放进去一个, 如果你从里面获取一个A,则A被提到链表的头部,再放入一个B,则B在头部, 其他的就会靠后排。如果缓存的数量超过的3000,再缓存新的时候会踢掉尾部的那个。因为那个用的次数很少。

    public class CacheList<T> where T : class
     {
         public class Item
         {
             public string Key { get; set; }
             public T Value { get; set; }
             public Item Left { get; set; }
             public Item Right { get; set; }
    
             public Item(string key, T value)
             {
                 Key = key;
                 Value = value;
             }
         }
    
         private readonly static object _locked = new object();
    
         private readonly IDictionary<string, Item> _dict;
    
         public int Length { get; private set; }
    
         public CacheList(int maxLength)
         {
             _dict = new Dictionary<string, Item>();
             Length = maxLength;
         }
    
         private Item _first;
         private Item _last;
    
         public bool HasKey(string key)
         {
             lock (_locked)
             {
                 return _dict.ContainsKey(key);
             }
         }
    
         public void Add(string key, T value)
         {
             var item = new Item(key, value);
             lock (_locked)
             {
                 if (_dict.Count == 0)
                 {
                     _last = _first = item;
                 }
                 else if (_dict.Count == 1)
                 {
                     _last = _first;
                     _first = item;
    
                     _last.Left = _first;
                     _first.Right = _last;
                 }
                 else
                 {
                     item.Right = _first;
                     _first.Left = item;
                     _first = item;
                 }
    
                 if (_dict.Count >= Length)
                 {
                     _last.Left.Right = null;
                     _dict.Remove(_last.Key);
                     _last = _last.Left;
                 }
    
                 _dict.AddValue(key, item);
             }
         }
    
    
         public T Get(string key)
         {
             Item item = null;
             lock (_locked)
             {
                 _dict.TryGetValue(key, out item);
             }
             if (item == null) return null;
             lock (_locked)
             {
                 if (_dict.Count == 1)
                 {
                     return _first.Value;
                 }
    
                 if (item.Left != null)
                 {
                     item.Left.Right = item.Right;
                 }
                 else
                 {
                     return item.Value;
                 }
    
                 if (item.Right != null)
                 {
                     item.Right.Left = item.Left;
                 }
                 else
                 {
                     _last.Left.Right = null;
                     _last = _last.Left;
                 }
    
                 item.Left = null;
                 item.Right = _first;
                 _first.Left = item;
                 _first = item;
             }
             return item.Value;
         }
    
         public void Remove(string key)
         {
             Item item = null;
             lock (_locked)
             {
                 _dict.TryGetValue(key, out item);
             }
             if (item == null) return;
    
             lock (_locked)
             {
                 if (item.Left != null)
                 {
                     item.Left.Right = item.Right;
                 }
                 else
                 {
                     _first = item.Right;
                 }
    
                 if (item.Right != null)
                 {
                     item.Right.Left = item.Left;
                 }
                 else
                 {
                     _last = item.Left;
                 }
    
                 _dict.Remove(key);
             }
         }
    
     }
    
    用法如下:
    public class ArticleCacheProvider
      {
          private static readonly CacheList<Article> CacheList;
    
          private static string GetCacheKey(string fileNameOrArticleId, int blogId)
          {
              return ("article_" + fileNameOrArticleId + "_" + blogId).ToLower();
          }
    
          static ArticleCacheProvider()
          {
              CacheList = new CacheList<Article>(3000);
          }
    
          public static Article Get(string fileNameOrArticleId, int blogId)
          {
              return CacheList.Get(GetCacheKey(fileNameOrArticleId, blogId));
          }
    
          public static void Set(Article entity)
          {
              //如果文章有别名,则存2份key,filename和articleId都可以获取缓存实体
              if (entity.FileName != entity.ArticleId.ToString())
              {
                  CacheList.Add(GetCacheKey(entity.ArticleId.ToString(), entity.BlogId), entity);
              }
              CacheList.Add(GetCacheKey(entity.FileName, entity.BlogId), entity);
          }
    
          public static void Remove(string fileNameOrArticleId, int blogId)
          {
              CacheList.Remove(GetCacheKey(fileNameOrArticleId, blogId));
          }
    
          public static bool HasArticle(string fileNameOrArticleId, int blogId)
          {
              return CacheList.HasKey(GetCacheKey(fileNameOrArticleId, blogId));
          }
      } 
    

    用处?有什么用处呢?,其实就是缓存起来呗,避免一条热门记录的反复查询。 

  • 相关阅读:
    SQL server多表联合查询
    Linux at命令
    git用法总结详细
    vue插槽
    vue组件通信
    vue高阶函数
    vue过滤器
    vue侦听器watch
    Vue 计算属性 computed
    Spring事务失效的场景
  • 原文地址:https://www.cnblogs.com/mad/p/LRU_Cache.html
Copyright © 2020-2023  润新知