-
Notifications
You must be signed in to change notification settings - Fork 299
/
Copy pathLRUCache.cs
60 lines (49 loc) · 1.48 KB
/
LRUCache.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.Linq;
using Advanced.Algorithms.DataStructures;
namespace Advanced.Algorithms.Distributed;
/// <summary>
/// A least recently used cache implemetation.
/// </summary>
public class LruCache<TK, TV>
{
private readonly int capacity;
private readonly DoublyLinkedList<Tuple<TK, TV>> dll = new();
private readonly Dictionary<TK, DoublyLinkedListNode<Tuple<TK, TV>>> lookUp = new();
public LruCache(int capacity)
{
if (capacity <= 0) throw new Exception("Capacity must be a positive integer.");
this.capacity = capacity;
}
/// <summary>
/// Time complexity: O(1).
/// </summary>
public TV Get(TK key)
{
if (!lookUp.ContainsKey(key))
return default;
var node = lookUp[key];
//move lately used node to beginning of ddl
dll.Delete(node);
var newNode = dll.InsertFirst(node.Data);
lookUp[key] = newNode;
return node.Data.Item2;
}
/// <summary>
/// Time complexity: O(1).
/// </summary>
public void Put(TK key, TV value)
{
//evict last node of ddl if capacity overflows
if (lookUp.Count == capacity)
{
var nodeToEvict = dll.Last();
lookUp.Remove(nodeToEvict.Item1);
dll.DeleteLast();
}
//insert
var newNode = dll.InsertFirst(new Tuple<TK, TV>(key, value));
lookUp.Add(key, newNode);
}
}