Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/webtorrent/webtorrent.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDC <dcposch@dcpos.ch>2016-04-02 01:00:41 +0300
committerDC <dcposch@dcpos.ch>2016-04-02 03:47:30 +0300
commit3756ae636c242ea9423874cdfeeb608b4ba1a507 (patch)
tree93c5de75db623cb3ebb3a3132c4c4b0923fe1809 /lib
parent715dafe597efb0ae9b332a6681f8934ba380cbcd (diff)
Optimization: don't re-verify unchanged files
Let the user specify known-good file modtimes. If the files modtime is at least that old, then the file hasn't changed and does not need to be re-verified. This is only valid in node when using FS backing storage, not in the browser
Diffstat (limited to 'lib')
-rw-r--r--lib/torrent.js69
1 files changed, 62 insertions, 7 deletions
diff --git a/lib/torrent.js b/lib/torrent.js
index 527ba55..475b41f 100644
--- a/lib/torrent.js
+++ b/lib/torrent.js
@@ -5,12 +5,12 @@ module.exports = Torrent
var addrToIPPort = require('addr-to-ip-port')
var BitField = require('bitfield')
var ChunkStoreWriteStream = require('chunk-store-stream/write')
-var cpus = require('cpus')
var debug = require('debug')('webtorrent:torrent')
var Discovery = require('torrent-discovery')
var EventEmitter = require('events').EventEmitter
var extend = require('xtend')
var extendMutable = require('xtend/mutable')
+var fs = require('fs')
var FSChunkStore = require('fs-chunk-store') // browser: `memory-chunk-store`
var ImmediateChunkStore = require('immediate-chunk-store')
var inherits = require('inherits')
@@ -45,6 +45,8 @@ var PIPELINE_MAX_DURATION = 1
var RECHOKE_INTERVAL = 10000 // 10 seconds
var RECHOKE_OPTIMISTIC_DURATION = 2 // 30 seconds
+var FILESYSTEM_CONCURRENCY = 2
+
var TMP = typeof pathExists.sync === 'function'
? path.join(pathExists.sync('/tmp') ? '/tmp' : os.tmpDir(), 'webtorrent')
: '/tmp/webtorrent'
@@ -99,6 +101,9 @@ function Torrent (torrentId, client, opts) {
// for cleanup
this._servers = []
+ // optimization: don't recheck every file if it hasn't changed
+ this._fileModtimes = opts.fileModtimes
+
if (torrentId !== null) this._onTorrentId(torrentId)
}
@@ -403,7 +408,55 @@ Torrent.prototype._onMetadata = function (metadata) {
})
self._debug('verifying existing torrent data')
- parallelLimit(self.pieces.map(function (piece, index) {
+ if (self._fileModtimes && self._store === FSChunkStore) {
+ // don't verify if the files haven't been modified since we last checked
+ self.getFileModtimes(function (err, fileModtimes) {
+ if (err) return self._onError(err)
+
+ var unchanged = self.files.map(function (_, index) {
+ return fileModtimes[index] === self._fileModtimes[index]
+ }).reduce(function (a, b) {
+ return a && b
+ })
+ if (unchanged) {
+ for (var index = 0; index < self.pieces.length; index++) {
+ self._markVerified(index)
+ }
+ self._onStore()
+ } else {
+ self._verifyPieces()
+ }
+ })
+ } else {
+ self._verifyPieces()
+ }
+
+ self.emit('metadata')
+}
+
+/*
+ * Gets the last modified time of every file on disk for this torrent.
+ * Only valid in Node, not in the browser.
+ */
+Torrent.prototype.getFileModtimes = function (cb) {
+ var self = this
+ var ret = []
+ parallelLimit(self.files.map(function (file, index) {
+ return function (cb) {
+ fs.stat(path.join(self.path, file.path), function (err, stat) {
+ ret[index] = stat && stat.mtime.getTime()
+ cb(err)
+ })
+ }
+ }), FILESYSTEM_CONCURRENCY, function (err) {
+ self._debug('done getting file modtimes')
+ cb(err, ret)
+ })
+}
+
+Torrent.prototype._verifyPieces = function () {
+ var self = this
+ parallelLimit(self.pieces.map(function (_, index) {
return function (cb) {
self.store.get(index, function (err, buf) {
if (err) return cb(null) // ignore error
@@ -411,9 +464,7 @@ Torrent.prototype._onMetadata = function (metadata) {
if (hash === self._hashes[index]) {
if (!self.pieces[index]) return
self._debug('piece verified %s', index)
- self.pieces[index] = null
- self._reservations[index] = null
- self.bitfield.set(index, true)
+ self._markVerified(index)
} else {
self._debug('piece invalid %s', index)
}
@@ -421,13 +472,17 @@ Torrent.prototype._onMetadata = function (metadata) {
})
})
}
- }), cpus().length, function (err) {
+ }), FILESYSTEM_CONCURRENCY, function (err) {
if (err) return self._onError(err)
self._debug('done verifying')
self._onStore()
})
+}
- self.emit('metadata')
+Torrent.prototype._markVerified = function (index) {
+ this.pieces[index] = null
+ this._reservations[index] = null
+ this.bitfield.set(index, true)
}
/**