|
|
@ -16,7 +16,7 @@ module.exports = class Query extends Readable { |
|
|
|
this.concurrency = opts.concurrency || this.dht.concurrency |
|
|
|
this.inflight = 0 |
|
|
|
this.map = opts.map || defaultMap |
|
|
|
this.closest = [] |
|
|
|
this.closestReplies = [] |
|
|
|
|
|
|
|
this._slowdown = false |
|
|
|
this._seen = new Set() |
|
|
@ -28,7 +28,7 @@ module.exports = class Query extends Readable { |
|
|
|
this._commiting = false |
|
|
|
this._ropts = { socket: (opts && opts.socket) || this.dht.rpc.socket, expectOk: false } |
|
|
|
|
|
|
|
const nodes = opts.nodes || opts.closest |
|
|
|
const nodes = opts.nodes || opts.closestNodes |
|
|
|
|
|
|
|
if (nodes) { |
|
|
|
// add them reverse as we pop below
|
|
|
@ -39,6 +39,22 @@ module.exports = class Query extends Readable { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
get closestNodes () { |
|
|
|
const nodes = new Array(this.closestReplies.length) |
|
|
|
|
|
|
|
for (let i = 0; i < nodes.length; i++) { |
|
|
|
const c = this.closestReplies[i] |
|
|
|
|
|
|
|
nodes[i] = { |
|
|
|
id: c.id, |
|
|
|
host: c.from.host, |
|
|
|
port: c.from.port |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return nodes |
|
|
|
} |
|
|
|
|
|
|
|
finished () { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
const self = this |
|
|
@ -85,7 +101,7 @@ module.exports = class Query extends Readable { |
|
|
|
} |
|
|
|
|
|
|
|
_isCloser (id) { |
|
|
|
return this.closest.length < this.k || this._compare(id, this.closest[this.closest.length - 1].id) < 0 |
|
|
|
return this.closestReplies.length < this.k || this._compare(id, this.closestReplies[this.closestReplies.length - 1].id) < 0 |
|
|
|
} |
|
|
|
|
|
|
|
_addPending (id, host, port) { |
|
|
@ -136,7 +152,7 @@ module.exports = class Query extends Readable { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (!this.closest.length) { |
|
|
|
if (!this.closestReplies.length) { |
|
|
|
this.destroy(new Error('Too few nodes responded')) |
|
|
|
return |
|
|
|
} |
|
|
@ -145,7 +161,7 @@ module.exports = class Query extends Readable { |
|
|
|
this._commiting = true |
|
|
|
|
|
|
|
const p = [] |
|
|
|
for (const node of this.closest) p.push(this._commit(node, this.dht, this)) |
|
|
|
for (const m of this.closestReplies) p.push(this._commit(m, this.dht, this)) |
|
|
|
|
|
|
|
race(p, 1, p.length) |
|
|
|
.then(() => this.push(null), (err) => this.destroy(err)) |
|
|
@ -158,13 +174,7 @@ module.exports = class Query extends Readable { |
|
|
|
this.inflight-- |
|
|
|
|
|
|
|
if (m.status === 0 && m.id !== null && this._isCloser(m.id)) { |
|
|
|
this._pushClosest({ |
|
|
|
id: m.id, |
|
|
|
host: m.from.host, |
|
|
|
port: m.from.port, |
|
|
|
token: m.token, |
|
|
|
to: m.to |
|
|
|
}) |
|
|
|
this._pushClosest(m) |
|
|
|
} |
|
|
|
|
|
|
|
if (m.closerNodes !== null) { |
|
|
@ -196,23 +206,23 @@ module.exports = class Query extends Readable { |
|
|
|
this._readMore() |
|
|
|
} |
|
|
|
|
|
|
|
_pushClosest (node) { |
|
|
|
this.closest.push(node) |
|
|
|
for (let i = this.closest.length - 2; i >= 0; i--) { |
|
|
|
const prev = this.closest[i] |
|
|
|
const cmp = this._compare(prev.id, node.id) |
|
|
|
_pushClosest (m) { |
|
|
|
this.closestReplies.push(m) |
|
|
|
for (let i = this.closestReplies.length - 2; i >= 0; i--) { |
|
|
|
const prev = this.closestReplies[i] |
|
|
|
const cmp = this._compare(prev.id, m.id) |
|
|
|
// if sorted, done!
|
|
|
|
if (cmp < 0) break |
|
|
|
// if dup, splice it out (rare)
|
|
|
|
if (cmp === 0) { |
|
|
|
this.closest.splice(i + 1, 1) |
|
|
|
this.closestReplies.splice(i + 1, 1) |
|
|
|
break |
|
|
|
} |
|
|
|
// swap and continue down
|
|
|
|
this.closest[i + 1] = prev |
|
|
|
this.closest[i] = node |
|
|
|
this.closestReplies[i + 1] = prev |
|
|
|
this.closestReplies[i] = m |
|
|
|
} |
|
|
|
if (this.closest.length > this.k) this.closest.pop() |
|
|
|
if (this.closestReplies.length > this.k) this.closestReplies.pop() |
|
|
|
} |
|
|
|
|
|
|
|
_compare (a, b) { |
|
|
|