from collections import UserDict from . import constants class DictDataStore(UserDict): """ A datastore using an in-memory Python dictionary """ #implements(IDataStore) def __init__(self, getTime=None): # Dictionary format: # { <key>: (<contact>, <value>, <lastPublished>, <originallyPublished> <originalPublisherID>) } super().__init__() if not getTime: from twisted.internet import reactor getTime = reactor.seconds self._getTime = getTime self.completed_blobs = set() 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[key] ) def filter_expired_peers(self, key): """ Returns only non-expired peers """ return filter(lambda peer: self._getTime() - peer[3] < constants.dataExpireTimeout, self[key]) def removeExpiredPeers(self): expired_keys = [] for key in self.keys(): unexpired_peers = list(self.filter_expired_peers(key)) if not unexpired_peers: expired_keys.append(key) else: self[key] = unexpired_peers for key in expired_keys: del self[key] def hasPeersForBlob(self, key): return True if key in self and len(tuple(self.filter_bad_and_expired_peers(key))) else False def addPeerToBlob(self, contact, key, compact_address, lastPublished, originallyPublished, originalPublisherID): if key in self: if compact_address not in map(lambda store_tuple: store_tuple[1], self[key]): self[key].append( (contact, compact_address, lastPublished, originallyPublished, originalPublisherID) ) else: self[key] = [(contact, compact_address, lastPublished, originallyPublished, originalPublisherID)] def getPeersForBlob(self, key): return [] if key not in self else [val[1] for val in self.filter_bad_and_expired_peers(key)] def getStoringContacts(self): contacts = set() for key in self: for values in self[key]: contacts.add(values[0]) return list(contacts)