diff options
author | Marco Pesenti Gritti <mpg@redhat.com> | 2007-08-26 10:08:50 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <mpg@redhat.com> | 2007-08-26 10:08:50 (GMT) |
commit | a8938ab8ba7aa15254c32f5df9c35f7b99fda315 (patch) | |
tree | 6ee5498a222c4403911da1b7999af0c2bdce4f1f /sugar | |
parent | 65871156f5ae87e757536012087e77a81b2541f8 (diff) |
Add an svg cache for SVGLoader
Diffstat (limited to 'sugar')
-rw-r--r-- | sugar/graphics/icon.py | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/sugar/graphics/icon.py b/sugar/graphics/icon.py index c53d34b..ce84839 100644 --- a/sugar/graphics/icon.py +++ b/sugar/graphics/icon.py @@ -41,17 +41,76 @@ def _get_svg_loader(): _svg_loader = _SVGLoader() return _svg_loader +class _SVGIcon(object): + def __init__(self, data): + self.data = data + self.data_size = len(data) + self.last_used = time.time() + class _SVGLoader(object): + CACHE_MAX_SIZE = 50000 + CACHE_MAX_ICON_SIZE = 5000 + + def __init__(self): + self._cache = {} + self._cache_size = 0 + def load(self, file_name, entities): - icon_file = open(file_name, 'r') - data = icon_file.read() - icon_file.close() + icon = self._get_icon(file_name) for entity, value in entities.items(): xml = '<!ENTITY %s "%s">' % (entity, value) - data = re.sub('<!ENTITY %s .*>' % entity, xml, data) + icon.data = re.sub('<!ENTITY %s .*>' % entity, xml, icon.data) - return rsvg.Handle(data=data) + return rsvg.Handle(data=icon.data) + + def _get_icon(self, file_name): + if self._cache.has_key(file_name): + data = self._cache[file_name] + data.last_used = time.time() + return data + + icon_file = open(file_name, 'r') + icon = _SVGIcon(icon_file.read()) + icon_file.close() + + self._cache[file_name] = icon + self._cleanup_cache() + + return icon + + def _cleanup_cache(self): + now = time.time() + while self._cache_size > self.CACHE_MAX_SIZE: + evict_key = None + oldest_key = None + oldest_time = now + + for icon_key, icon in self._cache.items(): + # evict large icons first + if icon.data_size > self.CACHE_MAX_ICON_SIZE: + evict_key = icon_key + break + + # evict older icons next; those used over 2 minutes ago + if icon.last_used < now - 120: + evict_key = icon_key + break + + # otherwise, evict the oldest + if oldest_time > icon.last_used: + oldest_time = icon.last_used + oldest_key = icon_key + + # If there's nothing specific to evict, try evicting + # the oldest thing + if not evict_key: + if not oldest_key: + break + evict_key = oldest_key + + self._cache_size -= self._cache[evict_key].data_size + del self._cache[evict_key] class _IconInfo(object): def __init__(self): |