import UserDict import constants from interface import IDataStore from zope.interface import implements class DictDataStore(UserDict.DictMixin): """ A datastore using an in-memory Python dictionary """ implements(IDataStore) def __init__(self, getTime=None): # Dictionary format: # { : (, , , ) } self._dict = {} if not getTime: from twisted.internet import reactor getTime = reactor.seconds self._getTime = getTime self.completed_blobs = set() def keys(self): """ Return a list of the keys in this data store """ return self._dict.keys() def filter_bad_and_expired_peers(self, key): """ Returns only non-expired and unknown/good peers """ return filter( lambda peer: self._getTime() - peer[3] < constants.dataExpireTimeout and peer[0].contact_is_good is not False, self._dict[key] ) def filter_expired_peers(self, key): """ Returns only non-expired peers """ return filter(lambda peer: self._getTime() - peer[3] < constants.dataExpireTimeout, self._dict[key]) def removeExpiredPeers(self): for key in self._dict.keys(): unexpired_peers = self.filter_expired_peers(key) if not unexpired_peers: del self._dict[key] else: self._dict[key] = unexpired_peers def hasPeersForBlob(self, key): return True if key in self._dict and len(self.filter_bad_and_expired_peers(key)) else False def addPeerToBlob(self, contact, key, compact_address, lastPublished, originallyPublished, originalPublisherID): if key in self._dict: if compact_address not in map(lambda store_tuple: store_tuple[1], self._dict[key]): self._dict[key].append( (contact, compact_address, lastPublished, originallyPublished, originalPublisherID) ) else: self._dict[key] = [(contact, compact_address, lastPublished, originallyPublished, originalPublisherID)] def getPeersForBlob(self, key): return [] if key not in self._dict else [val[1] for val in self.filter_bad_and_expired_peers(key)] def getStoringContacts(self): contacts = set() for key in self._dict: for values in self._dict[key]: contacts.add(values[0]) return list(contacts)