Source code for dahu.cache

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

"""
Data Analysis RPC server over Tango: 

Class Cache for storing the data in a Borg  
"""
from __future__ import with_statement, print_function, absolute_import, division

__authors__ = ["Jérôme Kieffer"]
__contact__ = "Jerome.Kieffer@ESRF.eu"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "07/02/2020" 
__status__ = "production"

import os
import logging
from threading import Semaphore
logger = logging.getLogger("dahu.cache")


[docs]class DataCache(dict): """ This class is a Borg : always returns the same values regardless to the instance of the object it is used as data storage for images ... with a limit on the number of images to keep in memory. """ __shared_state = {} __data_initialized = False def __init__(self, max_size=10): """ Constructor of DataCache @param max_size: number of element to keep in memory """ self.__dict__ = self.__shared_state if DataCache.__data_initialized is False: DataCache.__data_initialized = True logger.debug("DataCache.__init__: initalization of the Borg") self.ordered = [] self.dict = {} self.max_size = max_size self._sem = Semaphore() def __repr__(self): """ """ out = ["{"] for key in self.ordered: out.append(" '%s': %s," % (key, self.dict[key])) out.append("}") return os.linesep.join(out) def __setitem__(self, key, value): """ x.__setitem__(i, y) <==> x[i]=y """ with self._sem: logger.debug("DataCache.__setitem__: %s", key) self.dict[key] = value if key in self.ordered: index = self.ordered.index(key) self.ordered.pop(index) if len(self.ordered) > self.max_size: firstKey = self.ordered.pop(0) logger.debug("Removing from cache: %s", firstKey) self.dict.pop(firstKey) self.ordered.append(key) def __getitem__(self, key): """ x.__getitem__(y) <==> x[y] """ with self._sem: logger.debug("DataCache.__setitem__: %s", key) index = self.ordered.index(key) self.ordered.pop(index) self.ordered.append(key) return self.dict[key] def __contains__(self, key): """ D.__contains__(k) -> True if D has a key k, else False """ return key in self.dict has_key = __contains__ def __len__(self): """ Returns the length of the object """ return len(self.ordered)
[docs] def get(self, key, default=None): """ get method with default answer implemented """ if key in self.ordered: return self.__getitem__(key) elif default is not None: self.__setitem__(key, default) return default
[docs] def keys(self): """ Returns the list of keys, ordered """ logger.debug("DataCache.keys") return self.ordered[:]
[docs] def pop(self, key): """ Remove a key for the dictionary and return it's value """ with self._sem: logger.debug("DataCache.pop %s", key) try: index = self.ordered.index(key) except: raise KeyError self.ordered.pop(index) myData = self.dict.pop(key) return myData