You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

69 lines
1.5 KiB

const xor = require('xor-distance')
class QueryTable {
constructor (id, target) {
this.k = 20
this.id = id
this.target = target
this.closest = []
this.unverified = []
}
addUnverified (node, referrer) {
if (node.id.equals(this.id)) return
node.distance = xor(this.target, node.id)
node.referrer = referrer
insertSorted(node, this.k, this.unverified)
}
addVerified (message, peer) {
if (!message.id || !message.roundtripToken || message.id.equals(this.id)) {
return
}
var prev = getNode(message.id, this.unverified)
if (!prev) {
prev = {
id: message.id,
host: peer.host,
port: peer.port,
distance: xor(message.id, this.target)
}
}
prev.roundtripToken = message.roundtripToken
insertSorted(prev, this.k, this.closest)
}
}
module.exports = QueryTable
function getNode (id, list) {
// find id in the list.
// technically this would be faster with binary search (against distance)
// but this list is always small, so meh
for (var i = 0; i < list.length; i++) {
if (list[i].id.equals(id)) return list[i]
}
return null
}
function insertSorted (node, max, list) {
if (list.length === max && !xor.lt(node.distance, list[max - 1].distance)) return
if (getNode(node.id, list)) return
if (list.length < max) list.push(node)
else list[max - 1] = node
var pos = list.length - 1
while (pos && xor.gt(list[pos - 1].distance, node.distance)) {
list[pos] = list[pos - 1]
list[pos - 1] = node
pos--
}
}