From 40ca1578a7703448264a4f22832520d23b3118e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20W=C3=A4rting?= Date: Sun, 26 Aug 2018 11:22:52 +0200 Subject: [PATCH 1/3] modernize lib/rarity-map.jsj --- lib/rarity-map.js | 182 ++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 95 deletions(-) diff --git a/lib/rarity-map.js b/lib/rarity-map.js index 430f62f8..f97e602f 100644 --- a/lib/rarity-map.js +++ b/lib/rarity-map.js @@ -1,121 +1,113 @@ -module.exports = RarityMap /** * Mapping of torrent pieces to their respective availability in the torrent swarm. Used * by the torrent manager for implementing the rarest piece first selection strategy. */ -function RarityMap (torrent) { - var self = this +class RarityMap { + constructor (torrent) { + const self = this - self._torrent = torrent - self._numPieces = torrent.pieces.length - self._pieces = [] + self._torrent = torrent + self._numPieces = torrent.pieces.length + self._pieces = new Array(self._numPieces).fill(0) - self._onWire = function (wire) { - self.recalculate() - self._initWire(wire) - } - self._onWireHave = function (index) { - self._pieces[index] += 1 - } - self._onWireBitfield = function () { + self._onWire = wire => { + self.recalculate() + self._initWire(wire) + } + self._onWireHave = index => { + self._pieces[index] += 1 + } + self._onWireBitfield = () => { + self.recalculate() + } + + self._torrent.wires.forEach(wire => { + self._initWire(wire) + }) + self._torrent.on('wire', self._onWire) self.recalculate() } - self._torrent.wires.forEach(function (wire) { - self._initWire(wire) - }) - self._torrent.on('wire', self._onWire) - self.recalculate() -} - -/** - * Get the index of the rarest piece. Optionally, pass a filter function to exclude - * certain pieces (for instance, those that we already have). - * - * @param {function} pieceFilterFunc - * @return {number} index of rarest piece, or -1 - */ -RarityMap.prototype.getRarestPiece = function (pieceFilterFunc) { - if (!pieceFilterFunc) pieceFilterFunc = trueFn - - var candidates = [] - var min = Infinity - - for (var i = 0; i < this._numPieces; ++i) { - if (!pieceFilterFunc(i)) continue + /** + * Get the index of the rarest piece. Optionally, pass a filter function to exclude + * certain pieces (for instance, those that we already have). + * + * @param {function} pieceFilterFunc + * @return {number} index of rarest piece, or -1 + */ + getRarestPiece (pieceFilterFunc) { + let candidates = [] + let min = Infinity + + for (let i = 0; i < this._numPieces; ++i) { + if (pieceFilterFunc && !pieceFilterFunc(i)) continue + + const availability = this._pieces[i] + if (availability === min) { + candidates.push(i) + } else if (availability < min) { + candidates = [ i ] + min = availability + } + } - var availability = this._pieces[i] - if (availability === min) { - candidates.push(i) - } else if (availability < min) { - candidates = [ i ] - min = availability + if (candidates.length) { + // if there are multiple pieces with the same availability, choose one randomly + return candidates[Math.random() * candidates.length | 0] + } else { + return -1 } } - if (candidates.length > 0) { - // if there are multiple pieces with the same availability, choose one randomly - return candidates[Math.random() * candidates.length | 0] - } else { - return -1 + destroy () { + const self = this + self._torrent.removeListener('wire', self._onWire) + self._torrent.wires.forEach(wire => { + self._cleanupWireEvents(wire) + }) + self._torrent = null + self._pieces = null + + self._onWire = null + self._onWireHave = null + self._onWireBitfield = null } -} - -RarityMap.prototype.destroy = function () { - var self = this - self._torrent.removeListener('wire', self._onWire) - self._torrent.wires.forEach(function (wire) { - self._cleanupWireEvents(wire) - }) - self._torrent = null - self._pieces = null - - self._onWire = null - self._onWireHave = null - self._onWireBitfield = null -} -RarityMap.prototype._initWire = function (wire) { - var self = this + _initWire (wire) { + const self = this - wire._onClose = function () { - self._cleanupWireEvents(wire) - for (var i = 0; i < this._numPieces; ++i) { - self._pieces[i] -= wire.peerPieces.get(i) + wire._onClose = function () { + self._cleanupWireEvents(wire) + for (let i = 0; i < this._numPieces; ++i) { + self._pieces[i] -= wire.peerPieces.get(i) + } } - } - - wire.on('have', self._onWireHave) - wire.on('bitfield', self._onWireBitfield) - wire.once('close', wire._onClose) -} -/** - * Recalculates piece availability across all peers in the torrent. - */ -RarityMap.prototype.recalculate = function () { - var i - for (i = 0; i < this._numPieces; ++i) { - this._pieces[i] = 0 + wire.on('have', self._onWireHave) + wire.on('bitfield', self._onWireBitfield) + wire.once('close', wire._onClose) } - var numWires = this._torrent.wires.length - for (i = 0; i < numWires; ++i) { - var wire = this._torrent.wires[i] - for (var j = 0; j < this._numPieces; ++j) { - this._pieces[j] += wire.peerPieces.get(j) + /** + * Recalculates piece availability across all peers in the torrent. + */ + recalculate () { + this._pieces.fill(0) + + for (const wire of this._torrent.wires) { + for (let i = 0; i < this._numPieces; ++i) { + this._pieces[i] += wire.peerPieces.get(i) + } } } -} -RarityMap.prototype._cleanupWireEvents = function (wire) { - wire.removeListener('have', this._onWireHave) - wire.removeListener('bitfield', this._onWireBitfield) - if (wire._onClose) wire.removeListener('close', wire._onClose) - wire._onClose = null + _cleanupWireEvents (wire) { + wire.removeListener('have', this._onWireHave) + wire.removeListener('bitfield', this._onWireBitfield) + if (wire._onClose) wire.removeListener('close', wire._onClose) + wire._onClose = null + } } -function trueFn () { - return true -} +module.exports = RarityMap From 80b40226ba5b86edbe04809d1822bf719090fe46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20W=C3=A4rting?= Date: Sun, 26 Aug 2018 22:09:59 +0200 Subject: [PATCH 2/3] stop using self --- lib/rarity-map.js | 59 ++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/lib/rarity-map.js b/lib/rarity-map.js index f97e602f..bc69921c 100644 --- a/lib/rarity-map.js +++ b/lib/rarity-map.js @@ -5,28 +5,26 @@ */ class RarityMap { constructor (torrent) { - const self = this + this._torrent = torrent + this._numPieces = torrent.pieces.length + this._pieces = new Array(this._numPieces).fill(0) - self._torrent = torrent - self._numPieces = torrent.pieces.length - self._pieces = new Array(self._numPieces).fill(0) - - self._onWire = wire => { - self.recalculate() - self._initWire(wire) + this._onWire = wire => { + this.recalculate() + this._initWire(wire) } - self._onWireHave = index => { - self._pieces[index] += 1 + this._onWireHave = index => { + this._pieces[index] += 1 } - self._onWireBitfield = () => { - self.recalculate() + this._onWireBitfield = () => { + this.recalculate() } - self._torrent.wires.forEach(wire => { - self._initWire(wire) + this._torrent.wires.forEach(wire => { + this._initWire(wire) }) - self._torrent.on('wire', self._onWire) - self.recalculate() + this._torrent.on('wire', this._onWire) + this.recalculate() } /** @@ -61,31 +59,28 @@ class RarityMap { } destroy () { - const self = this - self._torrent.removeListener('wire', self._onWire) - self._torrent.wires.forEach(wire => { - self._cleanupWireEvents(wire) + this._torrent.removeListener('wire', this._onWire) + this._torrent.wires.forEach(wire => { + this._cleanupWireEvents(wire) }) - self._torrent = null - self._pieces = null + this._torrent = null + this._pieces = null - self._onWire = null - self._onWireHave = null - self._onWireBitfield = null + this._onWire = null + this._onWireHave = null + this._onWireBitfield = null } _initWire (wire) { - const self = this - - wire._onClose = function () { - self._cleanupWireEvents(wire) + wire._onClose = () => { + this._cleanupWireEvents(wire) for (let i = 0; i < this._numPieces; ++i) { - self._pieces[i] -= wire.peerPieces.get(i) + this._pieces[i] -= wire.peerPieces.get(i) } } - wire.on('have', self._onWireHave) - wire.on('bitfield', self._onWireBitfield) + wire.on('have', this._onWireHave) + wire.on('bitfield', this._onWireBitfield) wire.once('close', wire._onClose) } From 6815346091a5fd4235d61c705f5b74d28ec83053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20W=C3=A4rting?= Date: Mon, 27 Aug 2018 12:04:05 +0200 Subject: [PATCH 3/3] remove initial fill --- lib/rarity-map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rarity-map.js b/lib/rarity-map.js index bc69921c..76307344 100644 --- a/lib/rarity-map.js +++ b/lib/rarity-map.js @@ -7,7 +7,7 @@ class RarityMap { constructor (torrent) { this._torrent = torrent this._numPieces = torrent.pieces.length - this._pieces = new Array(this._numPieces).fill(0) + this._pieces = new Array(this._numPieces) this._onWire = wire => { this.recalculate()