using System; namespace ln.collections { public class Cache { public int Count => values.Count; BTree values; BTree> itemTree; LinkedList items = new LinkedList(); int maxCacheSize = 4096; public Cache() { values = new BTree(); itemTree = new BTree>(); } public Cache(Comparison compare) { values = new BTree(compare); itemTree = new BTree>(compare); } public int MaxCacheSize { get => maxCacheSize; set { maxCacheSize = value; while (maxCacheSize < values.Count) { Forget(); } } } public void Clear() { values.Clear(); itemTree.Clear(); items.Clear(); } public bool TryGet(K key,out V value) { return values.TryGet(key, out value); } public void Forget() { lock (this) { Forget(items.FirstItem); } } public void Forget(K key) { lock (this) { if (itemTree.TryGet(key,out LinkedListItem item)) Forget(item); } } private void Forget(LinkedListItem item) { if (item == null) return; values.Remove(item.Value); itemTree.Remove(item.Value); items.Remove(item); } public void Ensure(K key,V value) { lock (this) { if (!itemTree.TryGet(key, out LinkedListItem item)) { item = new LinkedListItem(key); values.Add(key,value); } Ensure(item); } } private void Ensure(LinkedListItem item) { if (!item.IsLinked) itemTree.Add(item.Value, item); items.Add(item); } } }