Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Limit scope of queries to k closest peers #97

Merged
merged 7 commits into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .aegir.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
bundlesize: { maxSize: '191kB' }
bundlesize: { maxSize: '192kB' }
}

2 changes: 1 addition & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports.READ_MESSAGE_TIMEOUT = minute
// The number of records that will be retrieved on a call to getMany()
exports.GET_MANY_RECORD_COUNT = 16

// K is the maximum number of requests to perform before returning failue
// K is the maximum number of requests to perform before returning failure
exports.K = 20

// Alpha is the concurrency for asynchronous requests
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ class KadDHT extends EventEmitter {
*
* @type {number}
*/
this.kBucketSize = options.kBucketSize || 20
this.kBucketSize = options.kBucketSize || c.K

/**
* Number of closest peers to return on kBucket search, default 6
* Number of closest peers to return on kBucket search, default 20
*
* @type {number}
*/
this.ncp = options.ncp || 6
this.ncp = options.ncp || c.K

/**
* The routing table.
Expand Down
101 changes: 101 additions & 0 deletions src/peer-distance-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use strict'

const distance = require('xor-distance')
const utils = require('./utils')
const map = require('async/map')

/**
* Maintains a list of peerIds sorted by distance from a DHT key.
*/
class PeerDistanceList {
/**
* Creates a new PeerDistanceList.
*
* @param {Buffer} originDhtKey - the DHT key from which distance is calculated
* @param {number} capacity - the maximum size of the list
*/
constructor (originDhtKey, capacity) {
this.originDhtKey = originDhtKey
this.capacity = capacity
this.peerDistances = []
}

/**
* The length of the list
*/
get length () {
return this.peerDistances.length
}

/**
* The peerIds in the list, in order of distance from the origin key
*/
get peers () {
return this.peerDistances.map(pd => pd.peerId)
}

/**
* Add a peerId to the list.
*
* @param {PeerId} peerId
* @param {function(Error)} callback
* @returns {void}
*/
add (peerId, callback) {
if (this.peerDistances.find(pd => pd.peerId.id.equals(peerId.id))) {
return callback()
}

utils.convertPeerId(peerId, (err, dhtKey) => {
if (err) {
return callback(err)
}

const el = {
peerId,
distance: distance(this.originDhtKey, dhtKey)
}

this.peerDistances.push(el)
this.peerDistances.sort((a, b) => distance.compare(a.distance, b.distance))
this.peerDistances = this.peerDistances.slice(0, this.capacity)

callback()
})
}

/**
* Indicates whether any of the peerIds passed as a parameter are closer
* to the origin key than the furthest peerId in the PeerDistanceList.
*
* @param {Array<PeerId>} peerIds
* @param {function(Error, Boolean)} callback
* @returns {void}
*/
anyCloser (peerIds, callback) {
if (!peerIds.length) {
return callback(null, false)
}

if (!this.length) {
return callback(null, true)
}

map(peerIds, (peerId, cb) => utils.convertPeerId(peerId, cb), (err, dhtKeys) => {
if (err) {
return callback(err)
}

const furthestDistance = this.peerDistances[this.peerDistances.length - 1].distance
for (const dhtKey of dhtKeys) {
const keyDistance = distance(this.originDhtKey, dhtKey)
if (distance.compare(keyDistance, furthestDistance) < 0) {
return callback(null, true)
}
}
return callback(null, false)
})
}
}

module.exports = PeerDistanceList
Loading