forked from LBRYCommunity/lbry-sdk
improve findCloseNodes, choose closest contacts from higher and lower buckets
This commit is contained in:
parent
c654bfe296
commit
5631a24881
1 changed files with 22 additions and 15 deletions
|
@ -106,7 +106,7 @@ class TreeRoutingTable(object):
|
||||||
# contact, and append the new one
|
# contact, and append the new one
|
||||||
df.addErrback(replaceContact, head_contact.id)
|
df.addErrback(replaceContact, head_contact.id)
|
||||||
|
|
||||||
def findCloseNodes(self, key, count, _rpcNodeID=None):
|
def findCloseNodes(self, key, count, sender_node_id=None):
|
||||||
""" Finds a number of known nodes closest to the node/value with the
|
""" Finds a number of known nodes closest to the node/value with the
|
||||||
specified key.
|
specified key.
|
||||||
|
|
||||||
|
@ -114,10 +114,10 @@ class TreeRoutingTable(object):
|
||||||
@type key: str
|
@type key: str
|
||||||
@param count: the amount of contacts to return
|
@param count: the amount of contacts to return
|
||||||
@type count: int
|
@type count: int
|
||||||
@param _rpcNodeID: Used during RPC, this is be the sender's Node ID
|
@param sender_node_id: Used during RPC, this is be the sender's Node ID
|
||||||
Whatever ID is passed in the paramater will get
|
Whatever ID is passed in the paramater will get
|
||||||
excluded from the list of returned contacts.
|
excluded from the list of returned contacts.
|
||||||
@type _rpcNodeID: str
|
@type sender_node_id: str
|
||||||
|
|
||||||
@return: A list of node contacts (C{kademlia.contact.Contact instances})
|
@return: A list of node contacts (C{kademlia.contact.Contact instances})
|
||||||
closest to the specified key.
|
closest to the specified key.
|
||||||
|
@ -129,7 +129,8 @@ class TreeRoutingTable(object):
|
||||||
bucketIndex = self._kbucketIndex(key)
|
bucketIndex = self._kbucketIndex(key)
|
||||||
|
|
||||||
if bucketIndex < len(self._buckets):
|
if bucketIndex < len(self._buckets):
|
||||||
closestNodes = self._buckets[bucketIndex].getContacts(count, _rpcNodeID)
|
# sort these
|
||||||
|
closestNodes = self._buckets[bucketIndex].getContacts(count, sender_node_id, sort_distance_to=key)
|
||||||
else:
|
else:
|
||||||
closestNodes = []
|
closestNodes = []
|
||||||
# This method must return k contacts (even if we have the node
|
# This method must return k contacts (even if we have the node
|
||||||
|
@ -142,21 +143,27 @@ class TreeRoutingTable(object):
|
||||||
def get_remain(closest):
|
def get_remain(closest):
|
||||||
return min(count, constants.k) - len(closest)
|
return min(count, constants.k) - len(closest)
|
||||||
|
|
||||||
# Fill up the node list to k nodes, starting with the closest neighbouring nodes known
|
distance = Distance(key)
|
||||||
|
|
||||||
while len(closestNodes) < min(count, constants.k) and (canGoLower or canGoHigher):
|
while len(closestNodes) < min(count, constants.k) and (canGoLower or canGoHigher):
|
||||||
# TODO: this may need to be optimized
|
iteration_contacts = []
|
||||||
# TODO: add "key" kwarg to getContacts() to sort contacts returned by xor distance
|
# get contacts from lower and/or higher buckets without sorting them
|
||||||
# to the key
|
|
||||||
if canGoLower and len(closestNodes) < min(count, constants.k):
|
if canGoLower and len(closestNodes) < min(count, constants.k):
|
||||||
closestNodes.extend(
|
lower_bucket = self._buckets[bucketIndex - i]
|
||||||
self._buckets[bucketIndex - i].getContacts(get_remain(closestNodes),
|
contacts = lower_bucket.getContacts(get_remain(closestNodes), sender_node_id, sort_distance_to=False)
|
||||||
_rpcNodeID))
|
iteration_contacts.extend(contacts)
|
||||||
canGoLower = bucketIndex - (i + 1) >= 0
|
canGoLower = bucketIndex - (i + 1) >= 0
|
||||||
|
|
||||||
if canGoHigher and len(closestNodes) < min(count, constants.k):
|
if canGoHigher and len(closestNodes) < min(count, constants.k):
|
||||||
closestNodes.extend(self._buckets[bucketIndex + i].getContacts(
|
higher_bucket = self._buckets[bucketIndex + i]
|
||||||
get_remain(closestNodes), _rpcNodeID))
|
contacts = higher_bucket.getContacts(get_remain(closestNodes), sender_node_id, sort_distance_to=False)
|
||||||
|
iteration_contacts.extend(contacts)
|
||||||
canGoHigher = bucketIndex + (i + 1) < len(self._buckets)
|
canGoHigher = bucketIndex + (i + 1) < len(self._buckets)
|
||||||
i += 1
|
i += 1
|
||||||
|
# sort the combined contacts and add as many as possible/needed to the combined contact list
|
||||||
|
iteration_contacts.sort(key=lambda c: distance(c.id), reverse=True)
|
||||||
|
while len(iteration_contacts) and len(closestNodes) < min(count, constants.k):
|
||||||
|
closestNodes.append(iteration_contacts.pop())
|
||||||
return closestNodes
|
return closestNodes
|
||||||
|
|
||||||
def getContact(self, contactID):
|
def getContact(self, contactID):
|
||||||
|
|
Loading…
Reference in a new issue