Skip to content

Instantly share code, notes, and snippets.

@mikerochip
Last active December 3, 2024 00:54
Show Gist options
  • Save mikerochip/abcdcc6278982cb58d2b31ddb5177612 to your computer and use it in GitHub Desktop.
Save mikerochip/abcdcc6278982cb58d2b31ddb5177612 to your computer and use it in GitHub Desktop.
LRU Cache C# Data Structure
public class LruCache<TKey, TValue> where TKey : IEquatable<TKey>
{
#region Private Types
private struct Entry
{
public TKey Key { get; set; }
public TValue Value { get; set; }
}
#endregion
#region Private Fields
private readonly SortedList<DateTime, Entry> _entries = new SortedList<DateTime, Entry>();
private readonly Dictionary<TKey, DateTime> _keyToTimestamps = new Dictionary<TKey, DateTime>();
private int _capacity = 100;
#endregion
#region Public Properties
public int Count => _entries.Count;
public int Capacity
{
get => _capacity;
set
{
_capacity = value;
if (_capacity <= 0)
{
Clear();
return;
}
while (Count > _capacity)
RemoveEarliest();
}
}
#endregion
#region Public Methods
public void Clear()
{
_entries.Clear();
_keyToTimestamps.Clear();
}
public DateTime Add(TKey key, TValue val)
{
if (Capacity <= 0)
return default;
if (Count == Capacity)
RemoveEarliest();
var timestamp = DateTime.Now;
_entries.Add(timestamp, new Entry { Key = key, Value = val });
_keyToTimestamps.Add(key, timestamp);
return timestamp;
}
public bool TryGet(TKey key, out DateTime timestamp, out TValue val)
{
if (!_keyToTimestamps.TryGetValue(key, out timestamp))
{
val = default;
return false;
}
val = _entries[timestamp].Value;
return true;
}
public bool Remove(TKey key)
{
if (!_keyToTimestamps.Remove(key, out var timestamp))
return false;
_entries.Remove(timestamp);
return true;
}
public TValue RemoveEarliest()
{
var lruEntry = _entries.Values[0];
_entries.RemoveAt(0);
_keyToTimestamps.Remove(lruEntry.Key);
return lruEntry.Value;
}
public bool RemoveEarliest(out DateTime timestamp, out TValue val)
{
timestamp = default;
val = default;
if (_entries.Count == 0)
return false;
var lruEntry = _entries.Values[0];
val = lruEntry.Value;
timestamp = _keyToTimestamps[lruEntry.Key];
_entries.RemoveAt(0);
_keyToTimestamps.Remove(lruEntry.Key);
return true;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment