public LFUNode RemoveLFUNode() { LFUNode target = Tail.Previous; RemoveNode(target); return(target); }
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; } } } }
public void AddToTop(LFUNode node) { node.Previous = Head; node.Next = Head.Next; node.Next.Previous = node; Head.Next = node; Count++; }
public void RemoveNode(LFUNode node) { node.Previous.Next = node.Next; node.Next.Previous = node.Previous; node.Previous = null; node.Next = null; Count--; }
public LFUDoubleLinkedList() { Head = new LFUNode(); Tail = new LFUNode(); Head.Next = Tail; Tail.Previous = Head; Count = 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); } }
// 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); }
/// <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); }
/// <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); } }
/// <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(); } }
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)); }
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()); }
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); }
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); }
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); } }
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); }
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); }
// 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); }
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); }
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++; } }
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()); }
/// <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); } }
/// <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; } } }
/// <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); } }