diff options
-rw-r--r-- | src/components/gfx/font.rs | 8 | ||||
-rw-r--r-- | src/components/gfx/font_context.rs | 7 | ||||
-rw-r--r-- | src/components/util/cache.rs | 97 |
3 files changed, 81 insertions, 31 deletions
diff --git a/src/components/gfx/font.rs b/src/components/gfx/font.rs index ae0d2e4acc0..e3b7f32da53 100644 --- a/src/components/gfx/font.rs +++ b/src/components/gfx/font.rs @@ -86,7 +86,7 @@ pub struct FontMetrics { } // TODO(Issue #200): use enum from CSS bindings for 'font-weight' -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub enum CSSFontWeight { FontWeight100, FontWeight200, @@ -114,7 +114,7 @@ impl CSSFontWeight { // the instance's properties. // // For now, the cases are differentiated with a typedef -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct FontStyle { pt_size: float, weight: CSSFontWeight, @@ -139,7 +139,7 @@ struct ResolvedFont { // It's used to swizzle/unswizzle gfx::Font instances when // communicating across tasks, such as the display list between layout // and render tasks. -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct FontDescriptor { style: UsedFontStyle, selector: FontSelector, @@ -155,7 +155,7 @@ impl FontDescriptor { } // A FontSelector is a platform-specific strategy for serializing face names. -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub enum FontSelector { SelectorPlatformIdentifier(~str), } diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs index d4479a8e310..5433da8751c 100644 --- a/src/components/gfx/font_context.rs +++ b/src/components/gfx/font_context.rs @@ -6,8 +6,7 @@ use font::{Font, FontDescriptor, FontGroup, FontHandleMethods, FontStyle, SelectorPlatformIdentifier}; use font::{SpecifiedFontStyle, UsedFontStyle}; use font_list::FontList; -use servo_util::cache::Cache; -use servo_util::cache::LRUCache; +use servo_util::cache::{Cache, LRUCache}; use servo_util::time::ProfilerChan; use platform::font::FontHandle; @@ -90,7 +89,7 @@ impl<'self> FontContext { None => { debug!("font group cache miss"); let fg = self.create_font_group(style); - self.group_cache.insert(style, fg); + self.group_cache.insert(style.clone(), fg); fg } } @@ -107,7 +106,7 @@ impl<'self> FontContext { let result = self.create_font_instance(desc); match result { Ok(font) => { - self.instance_cache.insert(desc, font); + self.instance_cache.insert(desc.clone(), font); }, _ => {} }; result diff --git a/src/components/util/cache.rs b/src/components/util/cache.rs index a03afdf961d..5e35a440088 100644 --- a/src/components/util/cache.rs +++ b/src/components/util/cache.rs @@ -2,8 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -pub trait Cache<K: Copy + Eq, V: Copy> { - fn insert(&mut self, key: &K, value: V); +use std::hashmap::HashMap; + +pub trait Cache<K: Eq, V: Clone> { + fn insert(&mut self, key: K, value: V); fn find(&mut self, key: &K) -> Option<V>; fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V; fn evict_all(&mut self); @@ -13,34 +15,35 @@ pub struct MonoCache<K, V> { entry: Option<(K,V)>, } -impl<K: Copy + Eq, V: Copy> MonoCache<K,V> { +impl<K: Clone + Eq, V: Clone> MonoCache<K,V> { pub fn new(_size: uint) -> MonoCache<K,V> { MonoCache { entry: None } } } -impl<K: Copy + Eq, V: Copy> Cache<K,V> for MonoCache<K,V> { - fn insert(&mut self, key: &K, value: V) { - self.entry = Some((copy *key, value)); +impl<K: Clone + Eq, V: Clone> Cache<K,V> for MonoCache<K,V> { + fn insert(&mut self, key: K, value: V) { + self.entry = Some((key, value)); } fn find(&mut self, key: &K) -> Option<V> { match self.entry { None => None, - Some((ref k, ref v)) => if *k == *key { Some(copy *v) } else { None } + Some((ref k, ref v)) => if *k == *key { Some(v.clone()) } else { None } } } fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V { - return match self.find(key) { + match self.entry { None => { let value = blk(key); - self.entry = Some((copy *key, copy value)); + self.entry = Some((key.clone(), value.clone())); value }, - Some(v) => v - }; + Some((ref _k, ref v)) => v.clone() + } } + fn evict_all(&mut self) { self.entry = None; } @@ -60,12 +63,60 @@ fn test_monocache() { assert!(cache.find(&1).is_none()); } +pub struct HashCache<K, V> { + entries: HashMap<K, V>, +} + +impl<K: Clone + Eq + Hash, V: Clone> HashCache<K,V> { + pub fn new() -> HashCache<K, V> { + HashCache { + entries: HashMap::new(), + } + } +} + +impl<K: Clone + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> { + fn insert(&mut self, key: K, value: V) { + self.entries.insert(key, value); + } + + fn find(&mut self, key: &K) -> Option<V> { + match self.entries.find(key) { + Some(v) => Some(v.clone()), + None => None, + } + } + + fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V { + self.entries.find_or_insert_with(key.clone(), blk).clone() + } + + fn evict_all(&mut self) { + self.entries.clear(); + } +} + +#[test] +fn test_hashcache() { + let cache = HashCache::new(); + let one = @"one"; + let two = @"two"; + + cache.insert(&1, one); + assert!(cache.find(&1).is_some()); + assert!(cache.find(&2).is_none()); + + cache.find_or_create(&2, |_v| { two }); + assert!(cache.find(&1).is_some()); + assert!(cache.find(&2).is_some()); +} + pub struct LRUCache<K, V> { entries: ~[(K, V)], cache_size: uint, } -impl<K: Copy + Eq, V: Copy> LRUCache<K,V> { +impl<K: Clone + Eq, V: Clone> LRUCache<K,V> { pub fn new(size: uint) -> LRUCache<K, V> { LRUCache { entries: ~[], @@ -74,21 +125,21 @@ impl<K: Copy + Eq, V: Copy> LRUCache<K,V> { } pub fn touch(&mut self, pos: uint) -> V { - let (key, val) = copy self.entries[pos]; - if pos != self.cache_size { - self.entries.remove(pos); - self.entries.push((key, copy val)); + let last_index = self.entries.len() - 1; + if pos != last_index { + let entry = self.entries.remove(pos); + self.entries.push(entry); } - val + self.entries[last_index].second_ref().clone() } } -impl<K: Copy + Eq, V: Copy> Cache<K,V> for LRUCache<K,V> { - fn insert(&mut self, key: &K, val: V) { +impl<K: Clone + Eq, V: Clone> Cache<K,V> for LRUCache<K,V> { + fn insert(&mut self, key: K, val: V) { if self.entries.len() == self.cache_size { self.entries.remove(0); } - self.entries.push((copy *key, val)); + self.entries.push((key, val)); } fn find(&mut self, key: &K) -> Option<V> { @@ -102,9 +153,9 @@ impl<K: Copy + Eq, V: Copy> Cache<K,V> for LRUCache<K,V> { match self.entries.position(|&(k, _)| k == *key) { Some(pos) => self.touch(pos), None => { - let val = blk(key); - self.insert(key, copy val); - val + let val = blk(key); + self.insert(key.clone(), val.clone()); + val } } } |