1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 
11 //! A cache that holds a limited number of key-value pairs. When the
12 //! capacity of the cache is exceeded, the least-recently-used
13 //! (where "used" means a look-up or putting the pair into the cache)
14 //! pair is automatically removed.
15 //!
16 //! # Examples
17 //!
18 //! ```
19 //! use lru_cache::LruCache;
20 //!
21 //! let mut cache = LruCache::new(2);
22 //!
23 //! cache.insert(1, 10);
24 //! cache.insert(2, 20);
25 //! cache.insert(3, 30);
26 //! assert!(cache.get_mut(&1).is_none());
27 //! assert_eq!(*cache.get_mut(&2).unwrap(), 20);
28 //! assert_eq!(*cache.get_mut(&3).unwrap(), 30);
29 //!
30 //! cache.insert(2, 22);
31 //! assert_eq!(*cache.get_mut(&2).unwrap(), 22);
32 //!
33 //! cache.insert(6, 60);
34 //! assert!(cache.get_mut(&3).is_none());
35 //!
36 //! cache.set_capacity(1);
37 //! assert!(cache.get_mut(&2).is_none());
38 //! ```
39 
40 extern crate linked_hash_map;
41 
42 use std::borrow::Borrow;
43 use std::collections::hash_map::RandomState;
44 use std::fmt;
45 use std::hash::{Hash, BuildHasher};
46 
47 use linked_hash_map::LinkedHashMap;
48 
49 #[cfg(feature = "heapsize_impl")]
50 mod heapsize;
51 
52 // FIXME(conventions): implement indexing?
53 
54 /// An LRU cache.
55 #[derive(Clone)]
56 pub struct LruCache<K: Eq + Hash, V, S: BuildHasher = RandomState> {
57     map: LinkedHashMap<K, V, S>,
58     max_size: usize,
59 }
60 
61 impl<K: Eq + Hash, V> LruCache<K, V> {
62     /// Creates an empty cache that can hold at most `capacity` items.
63     ///
64     /// # Examples
65     ///
66     /// ```
67     /// use lru_cache::LruCache;
68     /// let mut cache: LruCache<i32, &str> = LruCache::new(10);
69     /// ```
new(capacity: usize) -> Self70     pub fn new(capacity: usize) -> Self {
71         LruCache {
72             map: LinkedHashMap::new(),
73             max_size: capacity,
74         }
75     }
76 }
77 
78 impl<K: Eq + Hash, V, S: BuildHasher> LruCache<K, V, S> {
79     /// Creates an empty cache that can hold at most `capacity` items with the given hash builder.
with_hasher(capacity: usize, hash_builder: S) -> Self80     pub fn with_hasher(capacity: usize, hash_builder: S) -> Self {
81         LruCache { map: LinkedHashMap::with_hasher(hash_builder), max_size: capacity }
82     }
83 
84     /// Checks if the map contains the given key.
85     ///
86     /// # Examples
87     ///
88     /// ```
89     /// use lru_cache::LruCache;
90     ///
91     /// let mut cache = LruCache::new(1);
92     ///
93     /// cache.insert(1, "a");
94     /// assert_eq!(cache.contains_key(&1), true);
95     /// ```
contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool where K: Borrow<Q>, Q: Hash + Eq96     pub fn contains_key<Q: ?Sized>(&mut self, key: &Q) -> bool
97         where K: Borrow<Q>,
98               Q: Hash + Eq
99     {
100         self.get_mut(key).is_some()
101     }
102 
103     /// Inserts a key-value pair into the cache. If the key already existed, the old value is
104     /// returned.
105     ///
106     /// # Examples
107     ///
108     /// ```
109     /// use lru_cache::LruCache;
110     ///
111     /// let mut cache = LruCache::new(2);
112     ///
113     /// cache.insert(1, "a");
114     /// cache.insert(2, "b");
115     /// assert_eq!(cache.get_mut(&1), Some(&mut "a"));
116     /// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
117     /// ```
insert(&mut self, k: K, v: V) -> Option<V>118     pub fn insert(&mut self, k: K, v: V) -> Option<V> {
119         let old_val = self.map.insert(k, v);
120         if self.len() > self.capacity() {
121             self.remove_lru();
122         }
123         old_val
124     }
125 
126     /// Returns a mutable reference to the value corresponding to the given key in the cache, if
127     /// any.
128     ///
129     /// # Examples
130     ///
131     /// ```
132     /// use lru_cache::LruCache;
133     ///
134     /// let mut cache = LruCache::new(2);
135     ///
136     /// cache.insert(1, "a");
137     /// cache.insert(2, "b");
138     /// cache.insert(2, "c");
139     /// cache.insert(3, "d");
140     ///
141     /// assert_eq!(cache.get_mut(&1), None);
142     /// assert_eq!(cache.get_mut(&2), Some(&mut "c"));
143     /// ```
get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Hash + Eq144     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
145         where K: Borrow<Q>,
146               Q: Hash + Eq
147     {
148         self.map.get_refresh(k)
149     }
150 
151     /// Removes the given key from the cache and returns its corresponding value.
152     ///
153     /// # Examples
154     ///
155     /// ```
156     /// use lru_cache::LruCache;
157     ///
158     /// let mut cache = LruCache::new(2);
159     ///
160     /// cache.insert(2, "a");
161     ///
162     /// assert_eq!(cache.remove(&1), None);
163     /// assert_eq!(cache.remove(&2), Some("a"));
164     /// assert_eq!(cache.remove(&2), None);
165     /// assert_eq!(cache.len(), 0);
166     /// ```
remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> where K: Borrow<Q>, Q: Hash + Eq167     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
168         where K: Borrow<Q>,
169               Q: Hash + Eq
170     {
171         self.map.remove(k)
172     }
173 
174     /// Returns the maximum number of key-value pairs the cache can hold.
175     ///
176     /// # Examples
177     ///
178     /// ```
179     /// use lru_cache::LruCache;
180     /// let mut cache: LruCache<i32, &str> = LruCache::new(2);
181     /// assert_eq!(cache.capacity(), 2);
182     /// ```
capacity(&self) -> usize183     pub fn capacity(&self) -> usize {
184         self.max_size
185     }
186 
187     /// Sets the number of key-value pairs the cache can hold. Removes
188     /// least-recently-used key-value pairs if necessary.
189     ///
190     /// # Examples
191     ///
192     /// ```
193     /// use lru_cache::LruCache;
194     ///
195     /// let mut cache = LruCache::new(2);
196     ///
197     /// cache.insert(1, "a");
198     /// cache.insert(2, "b");
199     /// cache.insert(3, "c");
200     ///
201     /// assert_eq!(cache.get_mut(&1), None);
202     /// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
203     /// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
204     ///
205     /// cache.set_capacity(3);
206     /// cache.insert(1, "a");
207     /// cache.insert(2, "b");
208     ///
209     /// assert_eq!(cache.get_mut(&1), Some(&mut "a"));
210     /// assert_eq!(cache.get_mut(&2), Some(&mut "b"));
211     /// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
212     ///
213     /// cache.set_capacity(1);
214     ///
215     /// assert_eq!(cache.get_mut(&1), None);
216     /// assert_eq!(cache.get_mut(&2), None);
217     /// assert_eq!(cache.get_mut(&3), Some(&mut "c"));
218     /// ```
set_capacity(&mut self, capacity: usize)219     pub fn set_capacity(&mut self, capacity: usize) {
220         for _ in capacity..self.len() {
221             self.remove_lru();
222         }
223         self.max_size = capacity;
224     }
225 
226     /// Removes and returns the least recently used key-value pair as a tuple.
227     ///
228     /// # Examples
229     ///
230     /// ```
231     /// use lru_cache::LruCache;
232     ///
233     /// let mut cache = LruCache::new(2);
234     ///
235     /// cache.insert(1, "a");
236     /// cache.insert(2, "b");
237     ///
238     /// assert_eq!(cache.remove_lru(), Some((1, "a")));
239     /// assert_eq!(cache.len(), 1);
240     /// ```
241     #[inline]
remove_lru(&mut self) -> Option<(K, V)>242     pub fn remove_lru(&mut self) -> Option<(K, V)> {
243         self.map.pop_front()
244     }
245 
246     /// Returns the number of key-value pairs in the cache.
len(&self) -> usize247     pub fn len(&self) -> usize { self.map.len() }
248 
249     /// Returns `true` if the cache contains no key-value pairs.
is_empty(&self) -> bool250     pub fn is_empty(&self) -> bool { self.map.is_empty() }
251 
252     /// Removes all key-value pairs from the cache.
clear(&mut self)253     pub fn clear(&mut self) { self.map.clear(); }
254 
255     /// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order.
256     ///
257     /// Accessing the cache through the iterator does _not_ affect the cache's LRU state.
258     ///
259     /// # Examples
260     ///
261     /// ```
262     /// use lru_cache::LruCache;
263     ///
264     /// let mut cache = LruCache::new(2);
265     ///
266     /// cache.insert(1, 10);
267     /// cache.insert(2, 20);
268     /// cache.insert(3, 30);
269     ///
270     /// let kvs: Vec<_> = cache.iter().collect();
271     /// assert_eq!(kvs, [(&2, &20), (&3, &30)]);
272     /// ```
iter(&self) -> Iter<K, V>273     pub fn iter(&self) -> Iter<K, V> { Iter(self.map.iter()) }
274 
275     /// Returns an iterator over the cache's key-value pairs in least- to most-recently-used order,
276     /// with mutable references to the values.
277     ///
278     /// Accessing the cache through the iterator does _not_ affect the cache's LRU state.
279     ///
280     /// # Examples
281     ///
282     /// ```
283     /// use lru_cache::LruCache;
284     ///
285     /// let mut cache = LruCache::new(2);
286     ///
287     /// cache.insert(1, 10);
288     /// cache.insert(2, 20);
289     /// cache.insert(3, 30);
290     ///
291     /// let mut n = 2;
292     ///
293     /// for (k, v) in cache.iter_mut() {
294     ///     assert_eq!(*k, n);
295     ///     assert_eq!(*v, n * 10);
296     ///     *v *= 10;
297     ///     n += 1;
298     /// }
299     ///
300     /// assert_eq!(n, 4);
301     /// assert_eq!(cache.get_mut(&2), Some(&mut 200));
302     /// assert_eq!(cache.get_mut(&3), Some(&mut 300));
303     /// ```
iter_mut(&mut self) -> IterMut<K, V>304     pub fn iter_mut(&mut self) -> IterMut<K, V> { IterMut(self.map.iter_mut()) }
305 }
306 
307 impl<K: Eq + Hash, V, S: BuildHasher> Extend<(K, V)> for LruCache<K, V, S> {
extend<I: IntoIterator<Item=(K, V)>>(&mut self, iter: I)308     fn extend<I: IntoIterator<Item=(K, V)>>(&mut self, iter: I) {
309         for (k, v) in iter {
310             self.insert(k, v);
311         }
312     }
313 }
314 
315 impl<K: fmt::Debug + Eq + Hash, V: fmt::Debug, S: BuildHasher> fmt::Debug for LruCache<K, V, S> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result316     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317         f.debug_map().entries(self.iter().rev()).finish()
318     }
319 }
320 
321 impl<K: Eq + Hash, V, S: BuildHasher> IntoIterator for LruCache<K, V, S> {
322     type Item = (K, V);
323     type IntoIter = IntoIter<K, V>;
324 
into_iter(self) -> IntoIter<K, V>325     fn into_iter(self) -> IntoIter<K, V> {
326         IntoIter(self.map.into_iter())
327     }
328 }
329 
330 impl<'a, K: Eq + Hash, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S> {
331     type Item = (&'a K, &'a V);
332     type IntoIter = Iter<'a, K, V>;
into_iter(self) -> Iter<'a, K, V>333     fn into_iter(self) -> Iter<'a, K, V> { self.iter() }
334 }
335 
336 impl<'a, K: Eq + Hash, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S> {
337     type Item = (&'a K, &'a mut V);
338     type IntoIter = IterMut<'a, K, V>;
into_iter(self) -> IterMut<'a, K, V>339     fn into_iter(self) -> IterMut<'a, K, V> { self.iter_mut() }
340 }
341 
342 /// An iterator over a cache's key-value pairs in least- to most-recently-used order.
343 ///
344 /// # Examples
345 ///
346 /// ```
347 /// use lru_cache::LruCache;
348 ///
349 /// let mut cache = LruCache::new(2);
350 ///
351 /// cache.insert(1, 10);
352 /// cache.insert(2, 20);
353 /// cache.insert(3, 30);
354 ///
355 /// let mut n = 2;
356 ///
357 /// for (k, v) in cache {
358 ///     assert_eq!(k, n);
359 ///     assert_eq!(v, n * 10);
360 ///     n += 1;
361 /// }
362 ///
363 /// assert_eq!(n, 4);
364 /// ```
365 #[derive(Clone)]
366 pub struct IntoIter<K, V>(linked_hash_map::IntoIter<K, V>);
367 
368 impl<K, V> Iterator for IntoIter<K, V> {
369     type Item = (K, V);
370 
next(&mut self) -> Option<(K, V)>371     fn next(&mut self) -> Option<(K, V)> {
372         self.0.next()
373     }
374 
size_hint(&self) -> (usize, Option<usize>)375     fn size_hint(&self) -> (usize, Option<usize>) {
376         self.0.size_hint()
377     }
378 }
379 
380 impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
next_back(&mut self) -> Option<(K, V)>381     fn next_back(&mut self) -> Option<(K, V)> {
382         self.0.next_back()
383     }
384 }
385 
386 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
len(&self) -> usize387     fn len(&self) -> usize {
388         self.0.len()
389     }
390 }
391 
392 /// An iterator over a cache's key-value pairs in least- to most-recently-used order.
393 ///
394 /// Accessing a cache through the iterator does _not_ affect the cache's LRU state.
395 pub struct Iter<'a, K: 'a, V: 'a>(linked_hash_map::Iter<'a, K, V>);
396 
397 impl<'a, K, V> Clone for Iter<'a, K, V> {
clone(&self) -> Iter<'a, K, V>398     fn clone(&self) -> Iter<'a, K, V> { Iter(self.0.clone()) }
399 }
400 
401 impl<'a, K, V> Iterator for Iter<'a, K, V> {
402     type Item = (&'a K, &'a V);
next(&mut self) -> Option<(&'a K, &'a V)>403     fn next(&mut self) -> Option<(&'a K, &'a V)> { self.0.next() }
size_hint(&self) -> (usize, Option<usize>)404     fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
405 }
406 
407 impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
next_back(&mut self) -> Option<(&'a K, &'a V)>408     fn next_back(&mut self) -> Option<(&'a K, &'a V)> { self.0.next_back() }
409 }
410 
411 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
len(&self) -> usize412     fn len(&self) -> usize { self.0.len() }
413 }
414 
415 /// An iterator over a cache's key-value pairs in least- to most-recently-used order with mutable
416 /// references to the values.
417 ///
418 /// Accessing a cache through the iterator does _not_ affect the cache's LRU state.
419 pub struct IterMut<'a, K: 'a, V: 'a>(linked_hash_map::IterMut<'a, K, V>);
420 
421 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
422     type Item = (&'a K, &'a mut V);
next(&mut self) -> Option<(&'a K, &'a mut V)>423     fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.0.next() }
size_hint(&self) -> (usize, Option<usize>)424     fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
425 }
426 
427 impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
next_back(&mut self) -> Option<(&'a K, &'a mut V)>428     fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { self.0.next_back() }
429 }
430 
431 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
len(&self) -> usize432     fn len(&self) -> usize { self.0.len() }
433 }
434 
435 #[cfg(test)]
436 mod tests {
437     use super::LruCache;
438 
439     #[test]
test_put_and_get()440     fn test_put_and_get() {
441         let mut cache = LruCache::new(2);
442         cache.insert(1, 10);
443         cache.insert(2, 20);
444         assert_eq!(cache.get_mut(&1), Some(&mut 10));
445         assert_eq!(cache.get_mut(&2), Some(&mut 20));
446         assert_eq!(cache.len(), 2);
447     }
448 
449     #[test]
test_put_update()450     fn test_put_update() {
451         let mut cache = LruCache::new(1);
452         cache.insert("1", 10);
453         cache.insert("1", 19);
454         assert_eq!(cache.get_mut("1"), Some(&mut 19));
455         assert_eq!(cache.len(), 1);
456     }
457 
458     #[test]
test_contains_key()459     fn test_contains_key() {
460         let mut cache = LruCache::new(1);
461         cache.insert("1", 10);
462         assert_eq!(cache.contains_key("1"), true);
463     }
464 
465     #[test]
test_expire_lru()466     fn test_expire_lru() {
467         let mut cache = LruCache::new(2);
468         cache.insert("foo1", "bar1");
469         cache.insert("foo2", "bar2");
470         cache.insert("foo3", "bar3");
471         assert!(cache.get_mut("foo1").is_none());
472         cache.insert("foo2", "bar2update");
473         cache.insert("foo4", "bar4");
474         assert!(cache.get_mut("foo3").is_none());
475     }
476 
477     #[test]
test_pop()478     fn test_pop() {
479         let mut cache = LruCache::new(2);
480         cache.insert(1, 10);
481         cache.insert(2, 20);
482         assert_eq!(cache.len(), 2);
483         let opt1 = cache.remove(&1);
484         assert!(opt1.is_some());
485         assert_eq!(opt1.unwrap(), 10);
486         assert!(cache.get_mut(&1).is_none());
487         assert_eq!(cache.len(), 1);
488     }
489 
490     #[test]
test_change_capacity()491     fn test_change_capacity() {
492         let mut cache = LruCache::new(2);
493         assert_eq!(cache.capacity(), 2);
494         cache.insert(1, 10);
495         cache.insert(2, 20);
496         cache.set_capacity(1);
497         assert!(cache.get_mut(&1).is_none());
498         assert_eq!(cache.capacity(), 1);
499     }
500 
501     #[test]
test_debug()502     fn test_debug() {
503         let mut cache = LruCache::new(3);
504         cache.insert(1, 10);
505         cache.insert(2, 20);
506         cache.insert(3, 30);
507         assert_eq!(format!("{:?}", cache), "{3: 30, 2: 20, 1: 10}");
508         cache.insert(2, 22);
509         assert_eq!(format!("{:?}", cache), "{2: 22, 3: 30, 1: 10}");
510         cache.insert(6, 60);
511         assert_eq!(format!("{:?}", cache), "{6: 60, 2: 22, 3: 30}");
512         cache.get_mut(&3);
513         assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60, 2: 22}");
514         cache.set_capacity(2);
515         assert_eq!(format!("{:?}", cache), "{3: 30, 6: 60}");
516     }
517 
518     #[test]
test_remove()519     fn test_remove() {
520         let mut cache = LruCache::new(3);
521         cache.insert(1, 10);
522         cache.insert(2, 20);
523         cache.insert(3, 30);
524         cache.insert(4, 40);
525         cache.insert(5, 50);
526         cache.remove(&3);
527         cache.remove(&4);
528         assert!(cache.get_mut(&3).is_none());
529         assert!(cache.get_mut(&4).is_none());
530         cache.insert(6, 60);
531         cache.insert(7, 70);
532         cache.insert(8, 80);
533         assert!(cache.get_mut(&5).is_none());
534         assert_eq!(cache.get_mut(&6), Some(&mut 60));
535         assert_eq!(cache.get_mut(&7), Some(&mut 70));
536         assert_eq!(cache.get_mut(&8), Some(&mut 80));
537     }
538 
539     #[test]
test_clear()540     fn test_clear() {
541         let mut cache = LruCache::new(2);
542         cache.insert(1, 10);
543         cache.insert(2, 20);
544         cache.clear();
545         assert!(cache.get_mut(&1).is_none());
546         assert!(cache.get_mut(&2).is_none());
547         assert_eq!(format!("{:?}", cache), "{}");
548     }
549 
550     #[test]
test_iter()551     fn test_iter() {
552         let mut cache = LruCache::new(3);
553         cache.insert(1, 10);
554         cache.insert(2, 20);
555         cache.insert(3, 30);
556         cache.insert(4, 40);
557         cache.insert(5, 50);
558         assert_eq!(cache.iter().collect::<Vec<_>>(),
559                    [(&3, &30), (&4, &40), (&5, &50)]);
560         assert_eq!(cache.iter_mut().collect::<Vec<_>>(),
561                    [(&3, &mut 30), (&4, &mut 40), (&5, &mut 50)]);
562         assert_eq!(cache.iter().rev().collect::<Vec<_>>(),
563                    [(&5, &50), (&4, &40), (&3, &30)]);
564         assert_eq!(cache.iter_mut().rev().collect::<Vec<_>>(),
565                    [(&5, &mut 50), (&4, &mut 40), (&3, &mut 30)]);
566     }
567 }
568