Ejemplo n.º 1
0
        public LFUNode RemoveLFUNode()
        {
            LFUNode target = Tail.Previous;

            RemoveNode(target);
            return(target);
        }
Ejemplo n.º 2
0
 private void release(LFUNode <K, V> lastNode)
 {
     LFUNode <K, V>[] array = new LFUNode <K, V> [this.linked.Count];
     this.linked.Values.CopyTo(array, 0);
     Array.Sort <LFUNode <K, V> >(array);
     for (int i = array.Length - 1; i >= 0; i--)
     {
         if (array[i] != lastNode)
         {
             if (this.mDestroy == null)
             {
                 this.linked.Remove(array[i].Key);
                 if (this.DestroyAction != null)
                 {
                     this.DestroyAction(array[i]);
                 }
                 break;
             }
             bool flag = this.mDestroy.CanDestroy(array[i]);
             if (flag)
             {
                 this.linked.Remove(array[i].Key);
                 this.mDestroy.DestroyNode(array[i]);
                 break;
             }
         }
     }
 }
Ejemplo n.º 3
0
 public void AddToTop(LFUNode node)
 {
     node.Previous      = Head;
     node.Next          = Head.Next;
     node.Next.Previous = node;
     Head.Next          = node;
     Count++;
 }
Ejemplo n.º 4
0
 public void RemoveNode(LFUNode node)
 {
     node.Previous.Next = node.Next;
     node.Next.Previous = node.Previous;
     node.Previous      = null;
     node.Next          = null;
     Count--;
 }
Ejemplo n.º 5
0
 public LFUDoubleLinkedList()
 {
     Head          = new LFUNode();
     Tail          = new LFUNode();
     Head.Next     = Tail;
     Tail.Previous = Head;
     Count         = 0;
 }
Ejemplo n.º 6
0
    private void addGhostLFUCache(Node <K, V> node)
    {
        LFUNode <K, V> lFUNode = node as LFUNode <K, V>;

        this.fuGhostCache.Put(node.Key, node.Value, lFUNode.RefCount);
        if (this.DestroyCallback != null)
        {
            this.DestroyCallback(node);
        }
    }
Ejemplo n.º 7
0
        // get the value and then promote the node
        public int Get(int key)
        {
            if (!map.ContainsKey(key))
            {
                return(-1);
            }
            LFUNode node = map[key];

            PromoteNode(node);
            return(node.Value);
        }
Ejemplo n.º 8
0
    /// <summary>
    /// 添加元素
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    public void Put(K key, V value)
    {
        //先从LRU缓存中进行命中测试
        Node <K, V> node = ruCache.GetNode(key);

        if (node != null)
        {
            //lru缓存链中被命中,则添加到LFU中
            ruCache.RemoveKey(key);
            fuCache.Put(key, value);
            return;
        }

        //从LFU中进行命中测试
        node = fuCache.GetNode(key);
        if (node != null)
        {
            return;
        }

        //检测幽灵命中,已经被释放的资源重新添加
        int maxCapactity = initCapactity + initCapactity / 2;

        node = ruGhostCache.GetNode(key);
        if (node != null)
        {
            if (ruCache.Full && ruCache.Capactity < maxCapactity)
            {
                ruCache.Capactity++;
                fuCache.CapacityMax--;
            }
            ruCache.Put(key, value);
            ruGhostCache.RemoveKey(key);
            return;
        }

        node = fuGhostCache.GetNode(key);
        if (node != null)
        {
            if (fuCache.Full && fuCache.CapacityMax < maxCapactity)
            {
                fuCache.CapacityMax++;
                ruCache.Capactity--;
            }

            LFUNode <K, V> fuNode = node as LFUNode <K, V>;
            fuCache.Put(key, value, fuNode.RefCount);
            fuGhostCache.RemoveKey(key);
            return;
        }

        //新资源处理
        ruCache.Put(key, value);
    }
Ejemplo n.º 9
0
    /// <summary>
    /// 添加到镜像LFU缓存
    /// </summary>
    /// <param name="node"></param>
    private void addGhostLFUCache(Node <K, V> node)
    {
        LFUNode <K, V> fuNode = node as LFUNode <K, V>;

        fuGhostCache.Put(node.Key, node.Value, fuNode.RefCount);

        //只会销毁缓存数据,而会保留缓存引用记录
        if (DestroyCallback != null)
        {
            DestroyCallback.Invoke(node);
        }
    }
Ejemplo n.º 10
0
        /// <summary>
        /// 添加元素
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public void Add(TKey key, TValue value)
        {
            var lockSeed = false;

            if (!this.spinLock.IsHeldByCurrentThread)
            {
                this.spinLock.Enter(ref lockSeed);
            }

            LFUNode currentEntity = null;

            if (_dictionary.ContainsKey(key))
            {
                Log?.Invoke(this, $"覆盖已有的键:{key}={value}");
                currentEntity       = _dictionary[key];
                currentEntity.Value = value;

                RemoveFromSet(currentEntity);
                currentEntity.Frequency++;
                AddToSet(currentEntity);
            }
            else
            {
                Log?.Invoke(this, $"新增缓存:{key}={value}");
                if (_dictionary.Count == capacity)
                {
                    Log?.Invoke(this, $"缓存过多,需要删除最不常用缓存...");
                    var removeEntity = GetLeastFrequentEntity();
                    if (removeEntity != null)
                    {
                        Remove(removeEntity.Key);
                    }
                }

                if (_dictionary.Count < capacity)
                {
                    currentEntity       = new LFUNode();
                    currentEntity.Key   = key;
                    currentEntity.Value = value;
                    this._dictionary.Add(key, currentEntity);
                    AddToSet(currentEntity);
                }
            }

            if (lockSeed)
            {
                this.spinLock.Exit();
            }
        }
Ejemplo n.º 11
0
        public int CompareTo(object other)
        {
            LFUNode <K, V> yNode = other as LFUNode <K, V>;

            if (RefCount == yNode.RefCount)
            {
                TimeSpan span = UserTime.Subtract(yNode.UserTime);
                if (span.Milliseconds == 0)
                {
                    return(0);
                }
                return(span.Milliseconds > 0 ? -1 : 1);
            }
            return(-RefCount.CompareTo(yNode.RefCount));
        }
Ejemplo n.º 12
0
    public override string ToString()
    {
        LFUNode <K, V>[] nodeArr = new LFUNode <K, V> [linked.Count];
        linked.Values.CopyTo(nodeArr, 0);
        Array.Sort(nodeArr);

        StringBuilder sb = new StringBuilder();

        foreach (LFUNode <K, V> lfuNode in nodeArr)
        {
            sb.AppendFormat("refCount:{1} , dataTime : {2} key :{0} / {3}\r\n",
                            lfuNode.Key, lfuNode.RefCount, lfuNode.UserTime.Millisecond, lfuNode.Value);
        }
        return(sb.ToString());
    }
Ejemplo n.º 13
0
    private void releaseMax(List <LFUNode <K, V> > nodeArr)
    {
        if (this.Size <= this.capacityMax)
        {
            return;
        }
        LFUNode <K, V> lFUNode = nodeArr[nodeArr.Count - 1];

        this.linked.Remove(lFUNode.Key);
        nodeArr.RemoveAt(nodeArr.Count - 1);
        if (this.DestroyAction != null)
        {
            this.DestroyAction(lFUNode);
        }
        this.releaseMax(nodeArr);
    }
Ejemplo n.º 14
0
    public int CompareTo(object other)
    {
        LFUNode <K, V> lFUNode = other as LFUNode <K, V>;

        if (this.RefCount != lFUNode.RefCount)
        {
            return(-this.RefCount.CompareTo(lFUNode.RefCount));
        }
        TimeSpan timeSpan = this.UserTime.Subtract(lFUNode.UserTime);

        if (timeSpan.Milliseconds == 0)
        {
            return(0);
        }
        return((timeSpan.Milliseconds <= 0) ? 1 : -1);
    }
Ejemplo n.º 15
0
    public void Put(K key, V value, int refCount = 1)
    {
        LFUNode <K, V> lFUNode;

        if (!this.linked.ContainsKey(key))
        {
            lFUNode = new LFUNode <K, V>(key, value);
            this.linked.Add(key, lFUNode);
        }
        lFUNode           = this.linked[key];
        lFUNode.Value     = value;
        lFUNode.UserTime  = DateTime.UtcNow;
        lFUNode.RefCount += refCount;
        if (this.linked.Count > this.capacityMax)
        {
            this.release(lFUNode);
        }
    }
Ejemplo n.º 16
0
    public void Put(K key, V value)
    {
        Node <K, V> node = this.ruCache.GetNode(key);

        if (node != null)
        {
            this.ruCache.RemoveKey(key);
            this.fuCache.Put(key, value, 1);
            return;
        }
        node = this.fuCache.GetNode(key);
        if (node != null)
        {
            return;
        }
        int num = this.initCapactity + this.initCapactity / 2;

        node = this.ruGhostCache.GetNode(key);
        if (node != null)
        {
            if (this.ruCache.Full && this.ruCache.Capactity < num)
            {
                this.ruCache.Capactity++;
                this.fuCache.CapacityMax--;
            }
            this.ruCache.Put(key, value);
            this.ruGhostCache.RemoveKey(key);
            return;
        }
        node = this.fuGhostCache.GetNode(key);
        if (node != null)
        {
            if (this.fuCache.Full && this.fuCache.CapacityMax < num)
            {
                this.fuCache.CapacityMax++;
                this.ruCache.Capactity--;
            }
            LFUNode <K, V> lFUNode = node as LFUNode <K, V>;
            this.fuCache.Put(key, value, lFUNode.RefCount);
            this.fuGhostCache.RemoveKey(key);
            return;
        }
        this.ruCache.Put(key, value);
    }
Ejemplo n.º 17
0
    private void releaseMax(List <LFUNode <K, V> > nodeArr)
    {
        if (Size <= capacityMax)
        {
            return;
        }

        LFUNode <K, V> lastNode = nodeArr[nodeArr.Count - 1];

        linked.Remove(lastNode.Key);
        nodeArr.RemoveAt(nodeArr.Count - 1);

        if (DestroyAction != null)
        {
            DestroyAction(lastNode);
        }

        releaseMax(nodeArr);
    }
Ejemplo n.º 18
0
        // remove target node from current frequency double-linked list,
        // and then promote it to higher frequency double-linked list
        private void PromoteNode(LFUNode node)
        {
            LFUDoubleLinkedList dll = frequencyMap[node.Frequency];

            dll.RemoveNode(node);
            if (dll.Count == 0)
            {
                frequencyMap.Remove(node.Frequency);
                if (minFrequency == node.Frequency)
                {
                    minFrequency++;
                }
            }
            node.Frequency++;
            if (!frequencyMap.ContainsKey(node.Frequency))
            {
                frequencyMap[node.Frequency] = new LFUDoubleLinkedList();
            }
            frequencyMap[node.Frequency].AddToTop(node);
        }
Ejemplo n.º 19
0
        private void Add(int key, int value)
        {
            if (Values.Count == size)
            {
                return; // size zero or eviction didn't succeed
            }
            var newkv = new LFUNode(key, value);
            var node  = new LinkedListNode <LFUNode>(newkv);

            var newFreq = 1;

            Values.Add(key, node);
            Counts.Add(key, newFreq);
            if (!Frequencies.ContainsKey(newFreq))
            {
                Frequencies.Add(newFreq, new LinkedList <LFUNode>());
            }
            // Insert the node to the new frequency list
            Frequencies[newFreq].AddLast(node);
        }
Ejemplo n.º 20
0
        public void Add(int key, int value)
        {
            if (capacity == 0)
            {
                return;
            }

            // update the value of that node and then promote the node
            if (map.ContainsKey(key))
            {
                LFUNode node = map[key];
                node.Value = value;
                PromoteNode(node);
            }
            else
            {
                // remove the LFU node
                if (count == capacity)
                {
                    LFUDoubleLinkedList dll     = frequencyMap[minFrequency];
                    LFUNode             lfuNode = dll.RemoveLFUNode();
                    if (dll.Count == 0)
                    {
                        frequencyMap.Remove(minFrequency);
                    }
                    map.Remove(lfuNode.Key);
                    count--;
                }

                // add a new node
                LFUNode node = new LFUNode(key, value);
                minFrequency = node.Frequency;
                map[key]     = node;
                if (!frequencyMap.ContainsKey(node.Frequency))
                {
                    frequencyMap[node.Frequency] = new LFUDoubleLinkedList();
                }
                frequencyMap[node.Frequency].AddToTop(node);
                count++;
            }
        }
Ejemplo n.º 21
0
    public override string ToString()
    {
        LFUNode <K, V>[] array = new LFUNode <K, V> [this.linked.Count];
        this.linked.Values.CopyTo(array, 0);
        Array.Sort <LFUNode <K, V> >(array);
        StringBuilder stringBuilder = new StringBuilder();

        LFUNode <K, V>[] array2 = array;
        for (int i = 0; i < array2.Length; i++)
        {
            LFUNode <K, V> lFUNode = array2[i];
            stringBuilder.AppendFormat("refCount:{1} , dataTime : {2} key :{0} / {3}\r\n", new object[]
            {
                lFUNode.Key,
                lFUNode.RefCount,
                lFUNode.UserTime.Millisecond,
                lFUNode.Value
            });
        }
        return(stringBuilder.ToString());
    }
Ejemplo n.º 22
0
    /// <summary>
    /// 添加缓存元素
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    public void Put(K key, V value, int refCount = 1)
    {
        LFUNode <K, V> lfuNode = null;

        if (!linked.ContainsKey(key))
        {
            lfuNode = new LFUNode <K, V>(key, value);
            linked.Add(key, lfuNode);
        }

        lfuNode           = linked[key];
        lfuNode.Value     = value;
        lfuNode.UserTime  = System.DateTime.UtcNow;
        lfuNode.RefCount += refCount;

        //如果满容,进行排序释放
        if (linked.Count > capacityMax)
        {
            release(lfuNode);
        }
    }
Ejemplo n.º 23
0
    /// <summary>
    /// 释放使用率最小的结节
    /// </summary>
    private void release(LFUNode <K, V> lastNode)
    {
        LFUNode <K, V>[] nodeArr = new LFUNode <K, V> [linked.Count];
        linked.Values.CopyTo(nodeArr, 0);

        Array.Sort(nodeArr);

        for (int i = nodeArr.Length - 1; i >= 0; i--)
        {
            //删除末尾,如果最末尾是最新加入的,则删除前一个
            if (nodeArr[i] == lastNode)
            {
                continue;
            }

            if (mDestroy != null)
            {
                bool destroy = mDestroy.CanDestroy(nodeArr[i]);
                if (destroy)
                {
                    linked.Remove(nodeArr[i].Key);
                    mDestroy.DestroyNode(nodeArr[i]);
                    break;
                }
            }
            else
            {
                linked.Remove(nodeArr[i].Key);
                if (DestroyAction != null)
                {
                    DestroyAction.Invoke(nodeArr[i]);
                }
                break;
            }
        }
    }
Ejemplo n.º 24
0
    /// <summary>
    /// 释放使用率最小的结节
    /// </summary>
    private void release(LFUNode <K, V> lastNode)
    {
        LFUNode <K, V>[] nodeArr = new LFUNode <K, V> [linked.Count];
        linked.Values.CopyTo(nodeArr, 0);

        Array.Sort(nodeArr);


        //删除末尾,如果最末尾是最新加入的,则删除前一个
        if (lastNode == null || nodeArr[nodeArr.Length - 1] != lastNode)
        {
            lastNode = nodeArr[nodeArr.Length - 1];
        }
        else
        {
            lastNode = nodeArr[nodeArr.Length - 2];
        }

        linked.Remove(lastNode.Key);
        if (DestroyAction != null)
        {
            DestroyAction(lastNode);
        }
    }