-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLRUCache.cs
171 lines (153 loc) · 5.21 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// <copyright file="LRUCache.cs" company="Michael Miceli">
// Copyright Michael Miceli. All rights are reserved.
// </copyright>
namespace Cache
{
using System.Collections.Generic;
using System.Text;
/// <summary>
/// A simple LRU implementation
/// </summary>
/// <typeparam name="T">The type the LRU can hold</typeparam>
public class LRUCache<T> : ICollection<T>
{
/// <summary>
/// The default capacity of the LRU cache
/// </summary>
private const int DefaultCapacity = 5;
/// <summary>
/// An internal collection that holds our LRU cache
/// </summary>
private LinkedList<T> cache;
/// <summary>
/// Initializes a new instance of <see cref="LRUCache"/> class.
/// </summary>
public LRUCache()
: this(DefaultCapacity)
{
}
/// <summary>
/// Initializes a new instance of <see cref="LRUCache"/> class.
/// </summary>
/// <param name="capacity">The capacity of the LRU cache</param>
public LRUCache(int capacity)
{
this.cache = new LinkedList<T>();
this.Capacity = capacity;
}
/// <summary>
/// Gets the capacity of the LRU cache
/// </summary>
public int Capacity { get; private set; }
/// <summary>
/// Gets the number of elements in the LRU cache
/// </summary>
public int Count
{
get { return this.cache.Count; }
}
/// <summary>
/// Gets a value indicating whether or not the list is read only
/// </summary>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Adds an element to the LRU cache. If the cache is full, the oldest element is removed
/// </summary>
/// <param name="item">The element to add to the cache</param>
public void Add(T item)
{
if (this.cache.Contains(item))
{
// the item is already in the list, just move to the newest
this.cache.Remove(item);
this.cache.AddLast(item);
}
else if (this.cache.Count < this.Capacity)
{
// the item can be added in this list as the newest element, because there is available room
this.cache.AddLast(item);
}
else
{
// The LRU cache is at capacity and needs to remove the oldest item
this.cache.RemoveFirst();
this.cache.AddLast(item);
}
}
/// <summary>
/// Empties the cache
/// </summary>
public void Clear()
{
this.cache.Clear();
}
/// <summary>
/// Determines whether or not the item is in the LRU cache
/// </summary>
/// <param name="item">The item to check for in the LRU cache</param>
/// <returns>Whether or not the item is in the cache</returns>
public bool Contains(T item)
{
return (this.cache.Contains(item));
}
/// <summary>
/// Copies the elements of the LRUCache to an array, starting at index arrayIndex.
/// </summary>
/// <param name="array">The destination of items from the LRU cache.</param>
/// <param name="arrayIndex">The index in array where the elements to insert start</param>
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T item in this)
{
array[arrayIndex] = item;
// CA2233 overflow will cause an exception instead
checked
{
arrayIndex++;
}
}
}
/// <summary>
/// Removes an element from the LRU caches
/// </summary>
/// <param name="item">The item to remove</param>
/// <returns>True if the item was successfully removed, false otherwise, e.g. the item is not in the list</returns>
public bool Remove(T item)
{
return this.cache.Remove(item);
}
/// <summary>
/// Gets an enumerator to traverse the LRU cache
/// </summary>
/// <returns>An enumerator</returns>
public IEnumerator<T> GetEnumerator()
{
return this.cache.GetEnumerator();
}
/// <summary>
/// Gets an enumerator to traverse the LRU cache
/// </summary>
/// <returns>An enumerator</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.cache.GetEnumerator();
}
/// <summary>
/// A convenient method for printing the LRU cache
/// </summary>
/// <returns>A string representation of the LRU cache</returns>
public override string ToString()
{
StringBuilder retval = new StringBuilder("{ ");
foreach (T item in this)
{
retval.Append(item.ToString()).Append(" ");
}
retval.Append("}");
return retval.ToString();
}
}
}