100 lines
1.7 KiB
C#
100 lines
1.7 KiB
C#
using System;
|
|
using ln.types.btree;
|
|
using ln.types.collections;
|
|
using ln.types.odb.ng.storage;
|
|
namespace ln.types.cache
|
|
{
|
|
public class Cache<K,V>
|
|
{
|
|
public int Count => values.Count;
|
|
|
|
BTree<K, V> values;
|
|
BTree<K, LinkedListItem<K>> itemTree;
|
|
LinkedList<K> items = new LinkedList<K>();
|
|
|
|
int maxCacheSize = 4096;
|
|
|
|
public Cache()
|
|
{
|
|
values = new BTree<K, V>();
|
|
itemTree = new BTree<K, cache.LinkedListItem<K>>();
|
|
}
|
|
public Cache(Comparison<K> compare)
|
|
{
|
|
values = new BTree<K, V>(compare);
|
|
itemTree = new BTree<K, cache.LinkedListItem<K>>(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<K> item))
|
|
Forget(item);
|
|
}
|
|
}
|
|
|
|
private void Forget(LinkedListItem<K> 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<K> item))
|
|
{
|
|
item = new LinkedListItem<K>(key);
|
|
values.Add(key,value);
|
|
}
|
|
Ensure(item);
|
|
}
|
|
}
|
|
|
|
private void Ensure(LinkedListItem<K> item)
|
|
{
|
|
if (!item.IsLinked)
|
|
itemTree.Add(item.Value, item);
|
|
items.Add(item);
|
|
}
|
|
|
|
}
|
|
}
|