using System; using System.Collections; using System.Collections.Generic; namespace Substrate.Utility { class LRUCache : IDictionary { private Dictionary _data; private IndexedLinkedList _index; private int _capacity; public LRUCache (int capacity) { if (_capacity <= 0) { throw new ArgumentException("Cache capacity must be positive"); } _capacity = capacity; _data = new Dictionary(); _index = new IndexedLinkedList(); } #region IDictionary Members public void Add (TKey key, TValue value) { if (_data.ContainsKey(key)) { throw new ArgumentException("Attempted to insert a duplicate key"); } _data[key] = value; _index.Add(key); if (_data.Count > _capacity) { _data.Remove(_index.First); _index.RemoveFirst(); } } public bool ContainsKey (TKey key) { return _data.ContainsKey(key); } public ICollection Keys { get { return _data.Keys; } } public bool Remove (TKey key) { if (_data.Remove(key)) { _index.Remove(key); return true; } return false; } public bool TryGetValue (TKey key, out TValue value) { if (!_data.TryGetValue(key, out value)) { return false; } _index.Remove(key); _index.Add(key); return true; } public ICollection Values { get { return _data.Values; } } public TValue this[TKey key] { get { TValue value = _data[key]; _index.Remove(key); _index.Add(key); return value; } set { _data[key] = value; _index.Remove(key); _index.Add(key); if (_data.Count > _capacity) { _data.Remove(_index.First); _index.RemoveFirst(); } } } #endregion #region ICollection> Members public void Add (KeyValuePair item) { Add(item.Key, item.Value); } public void Clear () { _data.Clear(); _index.Clear(); } public bool Contains (KeyValuePair item) { return ((ICollection>)_data).Contains(item); } public void CopyTo (KeyValuePair[] array, int arrayIndex) { ((ICollection>)_data).CopyTo(array, arrayIndex); } public int Count { get { return _data.Count; } } public bool IsReadOnly { get { return false; } } public bool Remove (KeyValuePair item) { if (((ICollection>)_data).Remove(item)) { _index.Remove(item.Key); return true; } return false; } #endregion #region IEnumerable> Members public IEnumerator> GetEnumerator () { return _data.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator () { return _data.GetEnumerator(); } #endregion } }