Last active
December 3, 2024 00:54
-
-
Save mikerochip/abcdcc6278982cb58d2b31ddb5177612 to your computer and use it in GitHub Desktop.
LRU Cache C# Data Structure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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