diff --git a/src/lib.rs b/src/lib.rs index aeaa9ee..df52963 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -200,9 +200,14 @@ where S: BuildHasher + Clone, { fn clone(&self) -> Self { + let map_cap = if self.is_unbounded() { + self.len() + } else { + self.cap().get() + }; let mut new_lru = LruCache::construct( self.cap(), - HashMap::with_capacity_and_hasher(self.cap().get(), self.map.hasher().clone()), + HashMap::with_capacity_and_hasher(map_cap, self.map.hasher().clone()), ); for (key, value) in self.iter().rev() { @@ -298,6 +303,11 @@ impl LruCache { cache } + /// Whether this LRU cache is unbounded. + fn is_unbounded(&self) -> bool { + self.cap() == NonZeroUsize::MAX + } + /// Puts a key-value pair into cache. If the key already exists in the cache, then it updates /// the key's value and returns the old value. Otherwise, `None` is returned. /// @@ -2818,6 +2828,28 @@ mod tests { assert_eq!(cache.pop_lru(), None); assert_eq!(cloned.pop_lru(), None); } + + #[test] + fn test_clone_unbounded() { + let mut cache = LruCache::unbounded(); + cache.put("a", 1); + cache.put("b", 2); + cache.put("c", 3); + + let mut cloned = cache.clone(); + + assert_eq!(cache.pop_lru(), Some(("a", 1))); + assert_eq!(cloned.pop_lru(), Some(("a", 1))); + + assert_eq!(cache.pop_lru(), Some(("b", 2))); + assert_eq!(cloned.pop_lru(), Some(("b", 2))); + + assert_eq!(cache.pop_lru(), Some(("c", 3))); + assert_eq!(cloned.pop_lru(), Some(("c", 3))); + + assert_eq!(cache.pop_lru(), None); + assert_eq!(cloned.pop_lru(), None); + } } /// Doctests for what should *not* compile