Fix caching work

This commit is contained in:
TheXamlGuy
2024-05-23 20:42:03 +01:00
parent 246dab4297
commit 40a150fe80
3 changed files with 110 additions and 42 deletions
+107 -37
View File
@@ -1,49 +1,61 @@
using System.Collections; using System.Collections;
using System.Collections.Immutable;
using System.Reactive.Disposables;
namespace Toolkit.Foundation; namespace Toolkit.Foundation;
public class Cache<TValue>(IDisposer disposer, public class Cache<TValue>(IComparer<TValue>? comparer = default) :
IComparer<TValue>? comparer = default) :
ICache<TValue> ICache<TValue>
{ {
private readonly List<TValue> cache = []; private readonly List<TValue> items = [];
public int IndexOf(TValue value) => public IEnumerable<TValue> Items =>
cache.IndexOf(value); items;
public void Add(TValue value) public TValue this[int index] =>
items[index];
public void Add(TValue item)
{ {
if (value is null) int index = items.BinarySearch(item, comparer);
if (index < 0)
{ {
return; index = ~index;
}
items.Insert(index, item);
} }
disposer.Add(value, Disposable.Create(() => Remove(value))); public void Clear() => items.Clear();
cache.Add(value);
cache.Sort(comparer);
}
public bool TryGetValue(TValue key, out TValue? value) public IEnumerator<TValue> GetEnumerator() =>
items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator();
public int IndexOf(TValue item) =>
items.BinarySearch(item, comparer);
public bool Remove(TValue item)
{ {
if (cache.FirstOrDefault(x => x is not null && x.Equals(key)) is TValue returningValue) int index = items.BinarySearch(item, comparer);
if (index >= 0)
{ {
value = returningValue; items.RemoveAt(index);
return true; return true;
} }
value = default;
return false; return false;
} }
public void Clear() => cache.Clear(); public bool TryGetValue(TValue key, out TValue? item)
{
int index = items.BinarySearch(key, comparer);
if (index >= 0)
{
item = items[index];
return true;
}
public IEnumerator<TValue> GetEnumerator() => cache.GetEnumerator(); item = default;
return false;
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); }
public bool Remove(TValue value) => cache.Remove(value);
} }
public class Cache<TKey, TValue>(IComparer<TKey> comparer) : public class Cache<TKey, TValue>(IComparer<TKey> comparer) :
@@ -53,34 +65,92 @@ public class Cache<TKey, TValue>(IComparer<TKey> comparer) :
where TValue : where TValue :
notnull notnull
{ {
private readonly SortedList<TKey, TValue> cache = new(comparer); private readonly List<KeyValuePair<TKey, TValue?>> items = [];
public TValue? this[TKey key]
public void Add(TKey key,
TValue value)
{ {
cache.TryAdd(key, value); get
{
int index = items.BinarySearch(new KeyValuePair<TKey, TValue?>(key, default),
new KeyValuePairComparer<TKey, TValue?>(comparer));
if (index >= 0)
{
return items[index].Value;
} }
public void Clear() => cache.Clear(); return default;
}
set
{
int index = items.BinarySearch(new KeyValuePair<TKey, TValue?>(key, default),
new KeyValuePairComparer<TKey, TValue?>(comparer));
public bool ContainsKey(TKey key) => cache.ContainsKey(key); if (index >= 0)
{
items[index] = new KeyValuePair<TKey, TValue?>(key, value);
}
else
{
items.Insert(~index, new KeyValuePair<TKey, TValue?>(key, value));
}
}
}
public int IndexOf(TKey key) => cache.IndexOfKey(key); public void Add(TKey key, TValue value)
{
int index = items.BinarySearch(new KeyValuePair<TKey, TValue?>(key, default),
new KeyValuePairComparer<TKey, TValue?>(comparer));
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => cache.GetEnumerator(); if (index < 0)
{
index = ~index;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); items.Insert(index, new KeyValuePair<TKey, TValue?>(key, value));
}
public void Clear() => items.Clear();
public bool Remove(TKey key) => cache.Remove(key, out _); public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() =>
items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
public int IndexOf(TKey key) =>
items.FindIndex(kvp => comparer.Compare(kvp.Key, key) == 0);
public bool Remove(TKey key)
{
int index = items.FindIndex(kvp => comparer.Compare(kvp.Key, key) == 0);
if (index >= 0)
{
items.RemoveAt(index);
return true;
}
return false;
}
public bool TryGetValue(TKey key, out TValue? value) public bool TryGetValue(TKey key, out TValue? value)
{ {
if (cache.TryGetValue(key, out value)) int index = items.BinarySearch(new KeyValuePair<TKey, TValue?>(key, default(TValue)),
new KeyValuePairComparer<TKey, TValue?>(comparer));
if (index >= 0)
{ {
value = items[index].Value;
return true; return true;
} }
value = default; value = default;
return false; return false;
} }
private class KeyValuePairComparer<TK, TV>(IComparer<TK> comparer) :
IComparer<KeyValuePair<TK, TV>>
{
private readonly IComparer<TK> comparer = comparer ?? Comparer<TK>.Default;
public int Compare(KeyValuePair<TK, TV> x, KeyValuePair<TK, TV> y) =>
comparer.Compare(x.Key, y.Key);
}
} }
+2 -4
View File
@@ -7,11 +7,11 @@ public interface ICache<TValue> :
void Clear(); void Clear();
bool TryGetValue(TValue key, out TValue? item);
int IndexOf(TValue value); int IndexOf(TValue value);
bool Remove(TValue value); bool Remove(TValue value);
bool TryGetValue(TValue key, out TValue? value);
} }
public interface ICache<TKey, TValue> : public interface ICache<TKey, TValue> :
@@ -25,8 +25,6 @@ public interface ICache<TKey, TValue> :
void Clear(); void Clear();
bool ContainsKey(TKey key);
int IndexOf(TKey key); int IndexOf(TKey key);
bool Remove(TKey key); bool Remove(TKey key);