65.9K
CodeProject 正在变化。 阅读更多。
Home

缓存集合

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.57/5 (4投票s)

2008 年 8 月 11 日

CPOL
viewsIcon

21141

downloadIcon

112

一个固定大小集合的数据结构实现: 如果达到最大容量, 最旧的元素会自动删除

引言

这是一个具有固定容量的集合类的实现。当达到最大容量时,添加到集合的最旧元素会被自动清除。

通常,这可以用于缓存对象集合。
与 ASP.NET 或 Enterprise Library 提供的其他缓存解决方案不同,这里的优势在于可以遍历该集合。

Using the Code

使用一个简单的 string 集合时,您可以使用任何其他类型

CacheCollection<string> col = new CacheCollection<string>(3);
col.Add("A", "AA");
col.Add("B", "BB");
col.Add("C", "CC");

// access A => it becomes the newest element
string s = col.Get("A");

// the maximum capacity is reached => the oldest element "B" is deleted
col.Add("D", "DD");

当添加 D 元素时,会删除 B,因为它最旧。

-- newest --
D
A
C
B <-- deleted
-- oldest --

代码实现

内部,它使用 2 个集合

  • dic 是包含集合实际值的字典
  • stack 用于标记最新元素:较高的索引包含最新元素的键

技巧:当达到最大容量时,索引为 0 的元素会被删除。

public class CacheCollection<T> : IEnumerable<T>
{
   int capacity = 10000;
   Dictionary<string, T> dic;
   List<string> stack = new List<string>(); // new element on top

   public CacheCollection(int capacity)
   {
      dic = new Dictionary<string, T>();
      stack = new List<string>(capacity);
      this.capacity = capacity;
   }

   public void Add(string key, T v)
   {
      if (!dic.ContainsKey(key))
      {
         dic.Add(key, v);
         stack.Add(key);
         if (dic.Count > capacity)
         {
            // delete oldest
            string keyDelete = stack[0];
            stack.RemoveAt(0);
            dic.Remove(keyDelete);
         }
      }
      else
      {
         dic[key] = v;
         BubbleUp(key);
      }
   }

   public T Get(string key)
   {
      if (dic.ContainsKey(key))
      {
          BubbleUp(key);
          return dic[key];
      }
      else
          throw new InvalidOperationException("the collection does not contain the key");
   }

    /// <summary>
    /// Set the element on the top to make it the freshest 
    /// </summary>
    /// <param name="key"></param>
    private void BubbleUp(string key)
    {
       stack.Remove(key);
       stack.Add(key);
    }

    public bool Contains(string key)
    {
       return dic.ContainsKey(key);
    }


    public int Count
    {
       get { return dic.Count; }
    }

    #region IEnumerable<T> Members
    public IEnumerator<T> GetEnumerator()
    {
        return dic.Values.GetEnumerator();
    }
    #endregion

    #region IEnumerable Members
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return dic.Values.GetEnumerator();
    }
    #endregion
} 

历史

  • 2008 年 8 月 11 日:初始发布
© . All rights reserved.