Exemplo n.º 1
0
 /// <summary>
 /// 将指定的节点添加到链表热端的头部。
 /// </summary>
 /// <param name="node">要添加的节点。</param>
 private void AddHotFirst(LruNodeNoSync <TKey, TValue> node)
 {
     if (this.head == null)
     {
         node.Next = node.Prev = node;
     }
     else
     {
         this.head.AddBefore(node);
         // 热端长度增加,将冷端头节点像前移动一个位置。
         if (this.codeHead != null)
         {
             this.codeHead = this.codeHead.Prev;
         }
     }
     this.head = node;
 }
Exemplo n.º 2
0
 /// <summary>
 /// 从链表中移除指定的节点。
 /// </summary>
 /// <param name="node">要移除的节点。</param>
 private void Remove(LruNodeNoSync <TKey, TValue> node)
 {
     if (node.Next == node)
     {
         this.head = null;
     }
     else
     {
         node.Next.Prev = node.Prev;
         node.Prev.Next = node.Next;
         if (this.head == node)
         {
             this.head = node.Next;
         }
         else if (this.codeHead == node)
         {
             this.codeHead = node.Next;
         }
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// 将指定的键和对象添加到缓存中,并返回添加的节点。
        /// </summary>
        /// <param name="key">要添加的对象的键。</param>
        /// <param name="value">要添加的对象。</param>
        private void AddInternal(TKey key, TValue value)
        {
            LruNodeNoSync <TKey, TValue> node;

            if (count < maxSize)
            {
                // 将节点添加到热端的头。
                node = new LruNodeNoSync <TKey, TValue>(key, value);
                AddHotFirst(node);
                count++;
                if (count == hotSize + 1)
                {
                    codeHead = head.Prev;
                }
            }
            else
            {
                // 从冷端末尾尝试淘汰旧节点,将访问次数大于 1 的移动到热端的头。
                // 由于双向链表是环形存储的,就相当于将 head 前移。
                while (head.Prev.VisitCount >= 2)
                {
                    // 清零访问计数。
                    head.Prev.VisitCount = 0;
                    head     = head.Prev;
                    codeHead = codeHead.Prev;
                }
                // 将 node 移除,并添加到冷端的头。
                node = head.Prev;
                this.cacheDict.Remove(node.Key);
                this.Remove(node);
                // 这里直接重用旧节点。
                node.Key        = key;
                node.Value      = value;
                node.VisitCount = 1;
                this.AddCodeFirst(node);
            }
            cacheDict.Add(key, node);
        }
Exemplo n.º 4
0
 /// <summary>
 /// 将指定的节点添加到链表冷端的头部。
 /// </summary>
 /// <param name="node">要添加的节点。</param>
 private void AddCodeFirst(LruNodeNoSync <TKey, TValue> node)
 {
     // 这里 codeHead != null,在调用的时候已经保证了这一点。
     this.codeHead.AddBefore(node);
     this.codeHead = node;
 }
Exemplo n.º 5
0
 /// <summary>
 /// 清空缓存中的所有对象。
 /// </summary>
 public void Clear()
 {
     cacheDict.Clear();
     head  = codeHead = null;
     count = 0;
 }