这是一个固定长度的双向链表,没有闭合,当然是起初没写成闭合的。
怎么缓存的呢? 就是比如 长度是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));
}
}
用处?有什么用处呢?,其实就是缓存起来呗,避免一条热门记录的反复查询。