From a32596131ac729ee5de241b3190242b1a1862e0b Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 13 Apr 2017 16:57:51 +0800 Subject: [PATCH] Optimize LRUCache by using a VecDeque. We also reverse the order, so that we don't need iter.rev(). --- components/style/cache.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/components/style/cache.rs b/components/style/cache.rs index 2b12c8acf8f..fcdd7c79b8f 100644 --- a/components/style/cache.rs +++ b/components/style/cache.rs @@ -6,27 +6,28 @@ #![deny(missing_docs)] -use std::{iter, slice}; +use std::collections::VecDeque; +use std::collections::vec_deque; /// A LRU cache used to store a set of at most `n` elements at the same time. /// -/// Currently used for the style sharing candidate cache. +/// The most-recently-used entry is at index zero. pub struct LRUCache { - entries: Vec, + entries: VecDeque, cache_size: usize, } /// A iterator over the items of the LRU cache. -pub type LRUCacheIterator<'a, K> = iter::Rev>; +pub type LRUCacheIterator<'a, K> = vec_deque::Iter<'a, K>; /// A iterator over the mutable items of the LRU cache. -pub type LRUCacheMutIterator<'a, K> = iter::Rev>; +pub type LRUCacheMutIterator<'a, K> = vec_deque::IterMut<'a, K>; impl LRUCache { /// Create a new LRU cache with `size` elements at most. pub fn new(size: usize) -> Self { LRUCache { - entries: vec![], + entries: VecDeque::with_capacity(size), cache_size: size, } } @@ -37,32 +38,33 @@ impl LRUCache { } #[inline] - /// Touch a given position, and put it in the last item on the list. + /// Touch a given entry, putting it first in the list. pub fn touch(&mut self, pos: usize) { let last_index = self.entries.len() - 1; if pos != last_index { - let entry = self.entries.remove(pos); - self.entries.push(entry); + let entry = self.entries.remove(pos).unwrap(); + self.entries.push_front(entry); } } /// Iterate over the contents of this cache, from more to less recently /// used. - pub fn iter(&self) -> LRUCacheIterator { - self.entries.iter().rev() + pub fn iter(&self) -> vec_deque::Iter { + self.entries.iter() } /// Iterate mutably over the contents of this cache. - pub fn iter_mut(&mut self) -> LRUCacheMutIterator { - self.entries.iter_mut().rev() + pub fn iter_mut(&mut self) -> vec_deque::IterMut { + self.entries.iter_mut() } /// Insert a given key in the cache. pub fn insert(&mut self, key: K) { if self.entries.len() == self.cache_size { - self.entries.remove(0); + self.entries.pop_back(); } - self.entries.push(key); + self.entries.push_front(key); + debug_assert!(self.entries.len() <= self.cache_size); } /// Evict all elements from the cache.