Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar
diff options
context:
space:
mode:
authorMarco 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)
commita8938ab8ba7aa15254c32f5df9c35f7b99fda315 (patch)
tree6ee5498a222c4403911da1b7999af0c2bdce4f1f /sugar
parent65871156f5ae87e757536012087e77a81b2541f8 (diff)
Add an svg cache for SVGLoader
Diffstat (limited to 'sugar')
-rw-r--r--sugar/graphics/icon.py69
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):