1# -*- coding: utf-8 -*- 2''' pixbuf_cache.py - Caches book covers for the library display.''' 3 4from collections import OrderedDict 5from threading import Lock 6 7__all__ = ['get_pixbuf_cache'] 8 9class _PixbufCache(object): 10 11 ''' Pixbuf cache for the library window. Instead of loading book covers 12 from disk again after switching collection or using filtering, this class 13 stores a pre-defined amount of pixbufs in memory, evicting older pixbufs 14 as necessary. 15 ''' 16 17 def __init__(self, size): 18 #: Cache size, in images 19 assert size > 0 20 self.cachesize = size 21 #: Store book id => pixbuf 22 self._cache = OrderedDict() 23 #: Ensure thread safety 24 self._lock = Lock() 25 26 def add(self, path, pixbuf): 27 ''' Add a pixbuf to cache with path as key. ''' 28 with self._lock: 29 if path in self._cache: 30 return 31 while len(self._cache) > self.cachesize: 32 self._cache.popitem(last=False) 33 self._cache[path] = pixbuf 34 35 def get(self, path): 36 ''' Return the pixbuf for the given cache path, or None if not exists. ''' 37 with self._lock: 38 return self._cache.get(path, None) 39 40 def pop(self, path): 41 ''' Remove the object with the given cache path. ''' 42 with self._lock: 43 self._cache.pop(path, None) 44 45 def clear(self): 46 ''' Clear all cached objects. ''' 47 with self._lock: 48 self._cache.clear() 49 50 51_cache = None 52 53def get_pixbuf_cache(): 54 global _cache 55 56 if _cache is None: 57 # 500 items is about 130 MB of RAM with 500px thumbnails, 58 # and about 35 MB at 250px. 59 _cache = _PixbufCache(500) 60 return _cache 61 62# vim: expandtab:sw=4:ts=4 63