lbry-sdk/lbrynet/dht/datastore.py
Jack Robison 07f92014d7
omit bad contacts from getPeersForBlob
-refresh stored contacts to detect when they go offline or come back
2018-06-07 15:02:47 -04:00

74 lines
2.7 KiB
Python

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:
# { <key>: (<value>, <lastPublished>, <originallyPublished> <originalPublisherID>) }
self._dict = {}
if not getTime:
from twisted.internet import reactor
getTime = reactor.seconds
self._getTime = getTime
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[2] < 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):
if key in self._dict and len(self.filter_bad_and_expired_peers(key)):
return True
return 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 removePeer(self, value):
for key in self._dict:
self._dict[key] = [val for val in self._dict[key] if val[1] != value]
if not self._dict[key]:
del self._dict[key]
def getStoringContacts(self):
contacts = set()
for key in self._dict:
for values in self._dict[key]:
contacts.add(values[0])
return list(contacts)