profiler. refactoring.

This commit is contained in:
Christopher Jeffrey 2016-02-24 23:55:41 -08:00
parent afd6ee15c9
commit a9c116c98c
5 changed files with 86 additions and 81 deletions

View File

@ -47,38 +47,6 @@ function AbstractBlock(data) {
this.lowVersion = this.version & 7;
}
AbstractBlock.prototype.getMerkleBranch = function getMerkleBranch(index) {
var tree = utils.buildMerkleTree(this.merkleRoot);
var branch = [];
var j = 0;
for (var size = this.totalTX; size > 1; size = (size + 1) / 2 | 0) {
var i = Math.min(index ^ 1, size - 1);
branch.push(tree[j + i]);
index >>= 1;
j += size;
}
return branch;
};
AbstractBlock.prototype.hasMerkleItem = function hasMerkleItem(hash, branch, index) {
if (index === -1)
return false;
if (typeof hash === 'string')
hash = new Buffer(hash, 'hex');
for (var i = 0; i < branch.length; i++) {
var otherside = branch[i];
if (index & 1)
hash = utils.dsha256(Buffer.concat([otherside, hash]));
else
hash = utils.dsha256(Buffer.concat([hash, otherside]));
index >>= 1;
}
return utils.toHex(hash) === this.merkleRoot;
};
AbstractBlock.prototype.hash = function hash(enc) {
if (!this._hash)
this._hash = utils.dsha256(this.abbr());

View File

@ -1172,9 +1172,14 @@ Chain.prototype.add = function add(initial, peer, callback, force) {
// validated, and emitted. Hopefully the deserialized
// blocks get cleaned up by the GC quickly.
if (block.type === 'compactblock') {
block = block.toBlock(peer);
if (!block)
return done(new Error('Failed to parse block.'));
try {
block = block.toBlock();
} catch (e) {
// Ugly hack to handle
// the error properly.
peer.parser.emit('error', e);
return done(e);
}
}
// Do "contextual" verification on our block
@ -1326,6 +1331,10 @@ Chain.prototype.add = function add(initial, peer, callback, force) {
// Keep track of total blocks handled.
self.total += total;
// Take heap snapshot for debugging.
if (self.total % 10 === 0)
bcoin.profiler.snapshot();
// We intentionally did not asyncify the
// callback so if it calls chain.add, it
// still gets added to the queue. The

View File

@ -38,17 +38,7 @@ CompactBlock.prototype.getCoinbaseHeight = function getCoinbaseHeight() {
};
CompactBlock.prototype.toBlock = function toBlock(peer) {
var block;
// XXX Hack
try {
block = bcoin.protocol.parser.parseBlock(this._raw);
} catch (e) {
peer.parser.emit('error', e);
return;
}
return new bcoin.block(block);
return new bcoin.block(bcoin.protocol.parser.parseBlock(this._raw));
};
/**

View File

@ -13,38 +13,43 @@ var profiler;
if (bcoin.profile && !bcoin.isBrowser)
profiler = require('v8-' + 'profiler');
if (profiler) {
utils.nextTick(function() {
utils.debug('Starting node with profiler enabled.');
});
}
/**
* Profile
*/
function Profile(name) {
if (profiler) {
if (!name)
name = '';
name += '-' + Profile.uid++;
name = 'profile-' + (name ? name + '-' : '') + Profile.uid++;
this.profile = profiler.startProfiling(name, true);
this.name = name;
utils.debug('Starting CPU profile: %s', this.name);
}
}
Profile.uid = 0;
Profile.prototype.stopProfiling = function stopProfiling(callback) {
Profile.prototype.stopProfiling = function stopProfiling() {
if (!profiler)
return;
assert(this.profile);
this.profile.stopProfiling();
return this.profile.stopProfiling();
};
Profile.prototype.del = function del(callback) {
Profile.prototype.del = function del() {
if (!profiler)
return;
assert(this.profile);
this.profile['delete']();
return this.profile['delete']();
};
Profile.prototype.save = function save(callback) {
@ -57,22 +62,20 @@ Profile.prototype.save = function save(callback) {
assert(this.profile);
this.profile['export'](function(err, result) {
utils.debug('Saving CPU profile: %s', this.name);
return this.profile['export'](function(err, result) {
var file;
if (err) {
self.profile['delete']();
delete self.profile;
self.profile['delete']();
delete self.profile;
if (err)
return callback(err);
}
file = bcoin.prefix + '/profile-' + self.name + '.json';
file = bcoin.prefix + '/' + self.name + '.cpuprofile';
fs.writeFile(file, result, function(err) {
self.profile['delete']();
delete self.profile;
callback(err);
});
fs.writeFile(file, result, callback);
});
};
@ -82,11 +85,10 @@ Profile.prototype.save = function save(callback) {
function Snapshot(name) {
if (profiler) {
if (!name)
name = '';
name += '-' + Snapshot.uid++;
name = 'snapshot-' + (name ? name + '-' : '') + Snapshot.uid++;
this.snapshot = profiler.takeSnapshot(name);
this.name = name;
utils.debug('Taking heap snapshot: %s', this.name);
}
}
@ -129,22 +131,20 @@ Snapshot.prototype.save = function save(callback) {
assert(this.snapshot);
this.snapshot['export'](function(err, result) {
utils.debug('Saving heap snapshot: %s', this.name);
return this.snapshot['export'](function(err, result) {
var file;
if (err) {
self.profile['delete']();
delete self.profile;
self.snapshot['delete']();
delete self.snapshot;
if (err)
return callback(err);
}
file = bcoin.prefix + '/snapshot-' + self.name + '.json';
file = bcoin.prefix + '/' + self.name + '.heapsnapshot';
fs.writeFile(file, result, function(err) {
self.snapshot['delete']();
delete self.snapshot;
callback(err);
});
fs.writeFile(file, result, callback);
});
};
@ -168,6 +168,9 @@ exports.snapshot = function snapshot(name, callback) {
name = null;
}
if (!profiler)
return callback ? utils.nextTick(callback) : null;
snapshot = new Snapshot(name);
snapshot.save(callback);
};

View File

@ -1628,7 +1628,42 @@ utils.getMerkleRoot = function getMerkleRoot(items) {
return tree[tree.length - 1];
};
// Hook into bn here to ensure we get a toBuffer() method.
bn.prototype.toBuffer = function toBuffer(order, size) {
return new Buffer(this.toArray(order, size));
utils.getMerkleBranch = function getMerkleBranch(index, hashes) {
var tree = utils.buildMerkleTree(hashes);
var branch = [];
var size = this.totalTX;
var j = 0;
var i;
for (; size > 1; size = (size + 1) / 2 | 0) {
i = Math.min(index ^ 1, size - 1);
branch.push(tree[j + i]);
index >>= 1;
j += size;
}
return branch;
};
utils.checkMerkleBranch = function checkMerkleBranch(hash, branch, index) {
var otherside, i;
if (index === -1)
return false;
if (typeof hash === 'string')
hash = new Buffer(hash, 'hex');
for (i = 0; i < branch.length; i++) {
otherside = branch[i];
if (index & 1)
hash = utils.dsha256(Buffer.concat([otherside, hash]));
else
hash = utils.dsha256(Buffer.concat([hash, otherside]));
index >>= 1;
}
return hash;
};