diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py index a637f3ff7..1c593c676 100644 --- a/picard/ui/coverartbox.py +++ b/picard/ui/coverartbox.py @@ -26,7 +26,8 @@ from picard.album import Album from picard.coverart.image import CoverArtImage, CoverArtImageError from picard.track import Track from picard.file import File -from picard.util import encode_filename, imageinfo +from picard.util import encode_filename, imageinfo, get_file_path +from picard.util.lrucache import LRUCache if sys.platform == 'darwin': try: @@ -37,38 +38,7 @@ if sys.platform == 'darwin': log.warning("Unable to import NSURL, file drag'n'drop might not work correctly") -class LRUCache(dict): - - def __init__(self, max_size): - self._ordered_keys = [] - self._max_size = max_size - - def __getitem__(self, key): - if key in self: - self._ordered_keys.remove(key) - self._ordered_keys.insert(0, key) - return super(LRUCache, self).__getitem__(key) - - def __setitem__(self, key, value): - if key in self: - self._ordered_keys.remove(key) - self._ordered_keys.insert(0, key) - - r = super(LRUCache, self).__setitem__(key, value) - - if len(self) > self._max_size: - item = self._ordered_keys.pop() - super(LRUCache, self).__delitem__(item) - - return r - - def __delitem__(self, key): - self._ordered_keys.remove(key) - super(LRUCache, self).__delitem__(key) - - class ActiveLabel(QtGui.QLabel): - """Clickable QLabel.""" clicked = QtCore.pyqtSignal() diff --git a/picard/util/lrucache.py b/picard/util/lrucache.py new file mode 100644 index 000000000..72261b8cf --- /dev/null +++ b/picard/util/lrucache.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +# +# Picard, the next-generation MusicBrainz tagger +# Copyright (C) 2017 Antonio Larrosa +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +""" +Helper class to cache items using a Least Recently Used policy. + +It's originally used to cache generated pixmaps in the CoverArtBox object +but it's generic enough to be used for other purposes if necessary. +The cache will never hold more than max_size items and the item least +recently used will be discarded. + +>>> cache = LRUCache(3) +>>> cache['item1'] = 'some value' +>>> cache['item2'] = 'some other value' +>>> cache['item3'] = 'yet another value' +>>> cache['item1'] +'some value' +>>> cache['item4'] = 'This will push item 2 out of the cache' +>>> cache['item2'] +Traceback (most recent call last): + File "", line 1, in + File "lrucache.py", line 48, in __getitem__ + return super(LRUCache, self).__getitem__(key) +KeyError: 'item2' +>>> cache['item5'] = 'This will push item3 out of the cache' +>>> cache['item3'] +Traceback (most recent call last): + File "", line 1, in + File "lrucache.py", line 48, in __getitem__ + return super(LRUCache, self).__getitem__(key) +KeyError: 'item3' +>>> cache['item1'] +'some value' +""" + + +class LRUCache(dict): + def __init__(self, max_size): + self._ordered_keys = [] + self._max_size = max_size + + def __getitem__(self, key): + if key in self: + self._ordered_keys.remove(key) + self._ordered_keys.insert(0, key) + return super(LRUCache, self).__getitem__(key) + + def __setitem__(self, key, value): + if key in self: + self._ordered_keys.remove(key) + self._ordered_keys.insert(0, key) + + r = super(LRUCache, self).__setitem__(key, value) + + if len(self) > self._max_size: + item = self._ordered_keys.pop() + super(LRUCache, self).__delitem__(item) + + return r + + def __delitem__(self, key): + self._ordered_keys.remove(key) + super(LRUCache, self).__delitem__(key)