using System.Collections; namespace Toolkit.Foundation; public class Cache(IComparer? comparer = default) : ICache { private readonly List items = []; public IEnumerable Items => items; public TValue this[int index] => items[index]; public void Add(TValue item) { int index = items.BinarySearch(item, comparer); if (index < 0) { index = ~index; } items.Insert(index, item); } public void Clear() => items.Clear(); public IEnumerator GetEnumerator() => items.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator(); public int IndexOf(TValue item) => items.BinarySearch(item, comparer); public bool Remove(TValue item) { int index = items.BinarySearch(item, comparer); if (index >= 0) { items.RemoveAt(index); return true; } return false; } public bool Contains(TValue key) { int index = items.BinarySearch(key, comparer); if (index >= 0) { return true; } return false; } public bool TryGetValue(TValue key, out TValue? item) { int index = items.BinarySearch(key, comparer); if (index >= 0) { item = items[index]; return true; } item = default; return false; } } public class Cache(IComparer comparer) : ICache where TKey : notnull where TValue : notnull { private readonly List> items = []; public TValue? this[TKey key] { get { int index = items.BinarySearch(new KeyValuePair(key, default), new KeyValuePairComparer(comparer)); if (index >= 0) { return items[index].Value; } return default; } set { int index = items.BinarySearch(new KeyValuePair(key, default), new KeyValuePairComparer(comparer)); if (index >= 0) { items[index] = new KeyValuePair(key, value); } else { items.Insert(~index, new KeyValuePair(key, value)); } } } public void Add(TKey key, TValue value) { int index = items.BinarySearch(new KeyValuePair(key, default), new KeyValuePairComparer(comparer)); if (index < 0) { index = ~index; } items.Insert(index, new KeyValuePair(key, value)); } public void Clear() => items.Clear(); public IEnumerator> 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) { int index = items.BinarySearch(new KeyValuePair(key, default(TValue)), new KeyValuePairComparer(comparer)); if (index >= 0) { value = items[index].Value; return true; } value = default; return false; } public bool Contains(TKey key) { int index = items.FindIndex(kvp => comparer.Compare(kvp.Key, key) == 0); if (index >= 0) { items.RemoveAt(index); return true; } return false; } private class KeyValuePairComparer(IComparer comparer) : IComparer> { private readonly IComparer comparer = comparer ?? Comparer.Default; public int Compare(KeyValuePair x, KeyValuePair y) => comparer.Compare(x.Key, y.Key); } }