diff -r 4d08fb83a844 -r 21d90a3abc7c E5Utilities/E5Cache.py --- a/E5Utilities/E5Cache.py Mon Oct 16 19:11:25 2017 +0200 +++ b/E5Utilities/E5Cache.py Mon Oct 16 19:39:57 2017 +0200 @@ -9,6 +9,8 @@ from __future__ import unicode_literals +from PyQt5.QtCore import QDateTime, QTimer + # TODO: add timeout for cached entries class E5Cache(object): @@ -32,10 +34,16 @@ # internal objects self.__keyList = [] - self.__store = {} + self.__store = {} # stores the cache entries + self.__accesStore = {} # stores the last access date and times self.__hits = 0 self.__misses = 0 self.__maxsize = 0 + self.__maxCacheTime = 0 # 0 seconds means aging is disabled + + self.__cacheTimer = QTimer() + self.__cacheTimer.setSingleShot(True) + self.__cacheTimer.timeout.connect(self.__pruneCache) def __moveLast(self, key): """ @@ -55,6 +63,7 @@ self.__keyList[:-self.__size], self.__keyList[-self.__size:] for key in removeList: del self.__store[key] + del self.__accesStore[key] def getSize(self): """ @@ -78,6 +87,30 @@ self.__size = newSize self.__adjustToSize() + def getMaximumCacheTime(self): + """ + Public method to get the maximum time entries may exist in the cache. + + @return maximum cache time in seconds + @rtype int + """ + return self.__maxCacheTime + + def setMaximumCacheTime(self, time): + """ + Public method to set the maximum time entries may exist in the cache. + + @param time maximum cache time in seconds + @type int + """ + if time != self.__maxCacheTime: + self.__cacheTimer.stop() + self.__pruneCache() + self.__maxCacheTime = time + if self.__maxCacheTime > 0: + self.__cacheTimer.setInterval(self.__maxCacheTime * 1000) + self.__cacheTimer.start() + def get(self, key): """ Public method to get an entry from the cache given its key. @@ -93,6 +126,7 @@ if key in self.__store: self.__hits += 1 self.__moveLast(key) + self.__accesStore[key] = QDateTime.currentDateTimeUtc() return self.__store[key] else: self.__misses += 1 @@ -115,6 +149,7 @@ else: self.__keyList.append(key) self.__store[key] = item + self.__accesStore[key] = QDateTime.currentDateTimeUtc() self.__adjustToSize() @@ -129,6 +164,7 @@ """ if key in self.__store: del self.__store[key] + del self.__accesStore[key] self.__keyList.remove(key) def clear(self): @@ -137,6 +173,7 @@ """ self.__keyList = [] self.__store = {} + self.__accesStore = {} def reset(self): """ @@ -172,3 +209,19 @@ "maxsize": self.__maxsize, "currsize": self.length(), } + + def __pruneCache(self): + """ + Private slot to prune outdated cache entries and restart the timer. + """ + if self.__maxCacheTime > 0: + current = QDateTime.currentDateTimeUtc() + + keysToBeDeleted = [] + for key, lastAccessTime in self.__accesStore.items(): + if lastAccessTime.secsTo(current) > self.__maxCacheTime: + keysToBeDeleted.append(key) + for key in keysToBeDeleted: + self.remove(key) + + self.__cacheTimer.start()