123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- using System.Collections.Generic;
- namespace CommonAIClient.Unity.Utils
- {
- public class LRUCache<K, V>
- {
- public delegate void BeforRemoveDelegate(V val);
- private BeforRemoveDelegate OnBeforRemove = null;
- public LRUCache(int capacity, BeforRemoveDelegate function)
- {
- this.capacity = capacity;
- this.OnBeforRemove = function;
- }
- public V Get(K key)
- {
- HashSet<LinkedListNode<LRUCacheItem<K, V>>> nodes;
- if (cacheMap.TryGetValue(key, out nodes))
- {
- //System.Console.WriteLine("Cache HIT " + key);
- var iter = nodes.GetEnumerator();
- iter.MoveNext();
- LinkedListNode<LRUCacheItem<K, V>> node = iter.Current;
- V value = node.Value.value;
- nodes.Remove(node);
- lruList.Remove(node);
- //lruList.AddLast(node);
- return value;
- }
- //System.Console.WriteLine("Cache MISS " + key);
- return default(V);
- }
- public void Add(K key, V val)
- {
- if (capacity > 0)
- {
- if (lruList.Count >= capacity)
- {
- removeFirst();
- }
- LRUCacheItem<K, V> cacheItem = new LRUCacheItem<K, V>(key, val);
- LinkedListNode<LRUCacheItem<K, V>> node = new LinkedListNode<LRUCacheItem<K, V>>(cacheItem);
- lruList.AddLast(node);
- if (!cacheMap.ContainsKey(key))
- cacheMap.Add(key, new HashSet<LinkedListNode<LRUCacheItem<K, V>>>());
- cacheMap[key].Add(node);
- }
- else
- {
- if (this.OnBeforRemove != null) this.OnBeforRemove(val);
- }
- }
- public bool ContainsKey(K key)
- {
- if (!cacheMap.ContainsKey(key))
- return false;
- else
- {
- if (cacheMap[key].Count == 0)
- {
- return false;
- }
- else
- {
- var iter = cacheMap[key].GetEnumerator();
- iter.MoveNext();
- LinkedListNode<LRUCacheItem<K, V>> node = iter.Current;
- V value = node.Value.value;
- if (value == null || (value is UnityEngine.Object && (value as UnityEngine.Object) == null))
- {
- //GameDebug.Log("what fuck? " + key.ToString());
- lruList.Remove(node);
- cacheMap[key].Remove(node);
- return false;
- }
- else
- {
- return true;
- }
- }
- }
- }
- public void Clear()
- {
- while (cacheMap.Count > 0 && lruList.First != null)
- {
- removeFirst();
- }
- }
- protected void removeFirst()
- {
- // Remove from LRUPriority
- LinkedListNode<LRUCacheItem<K, V>> node = lruList.First;
- if (node != null)
- {
- if (this.OnBeforRemove != null) this.OnBeforRemove(node.Value.value);
- lruList.RemoveFirst();
- // Remove from cache
- //cacheMap.Remove(node.Value.key);
- cacheMap[node.Value.key].Remove(node);
- }
- }
- int capacity;
- Dictionary<K, HashSet<LinkedListNode<LRUCacheItem<K, V>>>> cacheMap =
- new Dictionary<K, HashSet<LinkedListNode<LRUCacheItem<K, V>>>>();
- LinkedList<LRUCacheItem<K, V>> lruList = new LinkedList<LRUCacheItem<K, V>>();
- }
- internal class LRUCacheItem<K, V>
- {
- public LRUCacheItem(K k, V v)
- {
- key = k;
- value = v;
- }
- public K key;
- public V value;
- }
- }
|