lib: searialize searches
This commit is contained in:
parent
66d920df0e
commit
8535fa6fa7
@ -299,9 +299,14 @@ Chain.prototype.has = function has(hash, noProbe, cb) {
|
||||
return cb(!!this.orphan.map[hash]);
|
||||
};
|
||||
|
||||
Chain.prototype.get = function get(hash, cb) {
|
||||
Chain.prototype.get = function get(hash, force, cb) {
|
||||
if (typeof force === 'function') {
|
||||
cb = force;
|
||||
force = false;
|
||||
}
|
||||
|
||||
// Cached block found
|
||||
if (this.block.bloom.test(hash, 'hex')) {
|
||||
if (!force && this.block.bloom.test(hash, 'hex')) {
|
||||
for (var i = 0; i < this.block.list.length; i++) {
|
||||
if (this.block.list[i].hash('hex') === hash) {
|
||||
// NOTE: we return right after the statement - so `block` should be
|
||||
@ -317,6 +322,7 @@ Chain.prototype.get = function get(hash, cb) {
|
||||
}
|
||||
|
||||
if (this.request.add(hash, cb))
|
||||
false;
|
||||
this.emit('missing', hash, null, null);
|
||||
};
|
||||
|
||||
@ -344,7 +350,21 @@ Chain.prototype.hashesInRange = function hashesInRange(start, end, cb) {
|
||||
start--;
|
||||
end = utils.binaryInsert(ts, end, compareTs, true);
|
||||
|
||||
return cb(this.index.hashes.slice(start, end));
|
||||
// Zip hashes and heights together and sort them by height
|
||||
var hashes = this.index.hashes.slice(start, end);
|
||||
var heights = this.index.heights.slice(start, end);
|
||||
var zip = [];
|
||||
for (var i = 0; i < hashes.length; i++)
|
||||
zip.push({ hash: hashes[i], height: heights[i] });
|
||||
zip = zip.sort(function(a, b) {
|
||||
return a.height - b.height;
|
||||
});
|
||||
var hashes = zip.map(function(a) {
|
||||
return a.hash;
|
||||
});
|
||||
|
||||
var count = zip[zip.length - 1].height - zip[0].height + 1;
|
||||
return cb(hashes, count);
|
||||
};
|
||||
|
||||
Chain.prototype.getLast = function getLast(cb) {
|
||||
|
||||
@ -62,6 +62,7 @@ function Pool(options) {
|
||||
// getTX map
|
||||
map: {}
|
||||
};
|
||||
this.searching = false;
|
||||
|
||||
// Currently broadcasted TXs
|
||||
this.tx = {
|
||||
@ -355,7 +356,18 @@ Pool.prototype.unwatch = function unwatch(id) {
|
||||
this.peers.block[i].updateWatch();
|
||||
};
|
||||
|
||||
Pool.prototype.search = function search(id, range) {
|
||||
Pool.prototype.search = function search(id, range, e) {
|
||||
e = e || new EventEmitter();
|
||||
|
||||
// Serialize searches
|
||||
if (this.searching) {
|
||||
this.once('_searchEnd', function() {
|
||||
this.search(id, range, e);
|
||||
});
|
||||
return e;
|
||||
}
|
||||
this.searching = true;
|
||||
|
||||
// Optional id argument
|
||||
if (typeof id === 'object' && !Array.isArray(id) ||
|
||||
typeof id === 'number') {
|
||||
@ -378,33 +390,52 @@ Pool.prototype.search = function search(id, range) {
|
||||
range.start = +new Date() / 1000 - 432000;
|
||||
|
||||
var self = this;
|
||||
var e = new EventEmitter();
|
||||
this.chain.hashesInRange(range.start, range.end, function(hashes) {
|
||||
var waiting = hashes.length;
|
||||
this.chain.hashesInRange(range.start, range.end, function(hashes, count) {
|
||||
var waiting = count;
|
||||
|
||||
if (id)
|
||||
self.watch(id);
|
||||
|
||||
self._loadRange(hashes, true);
|
||||
hashes.slice().reverse().forEach(function(hash) {
|
||||
hashes = hashes.slice().reverse();
|
||||
hashes.forEach(function(hash, i) {
|
||||
// Get the block that is in index
|
||||
self.chain.get(hash, loadBlock);
|
||||
self.chain.get(hash, true, function(block) {
|
||||
loadBlock(block, hashes[i + 1]);
|
||||
});
|
||||
});
|
||||
|
||||
function loadBlock(block) {
|
||||
function loadBlock(block, stop) {
|
||||
// Stop block reached
|
||||
if (block.hash('hex') === stop)
|
||||
return;
|
||||
|
||||
// Get block's prev and request it and all of it's parents up to
|
||||
// the next known block hash
|
||||
self.chain.get(block.prevBlock, function() {
|
||||
waiting--;
|
||||
e.emit('progress', hashes.length - waiting, hashes.length);
|
||||
if (waiting === 0) {
|
||||
if (id)
|
||||
self.unwatch(id);
|
||||
e.emit('end');
|
||||
}
|
||||
self.chain.get(block.prevBlock, block.prevBlock !== stop, function(prev) {
|
||||
done();
|
||||
|
||||
// First hash loaded
|
||||
if (!stop)
|
||||
return;
|
||||
|
||||
// Continue loading blocks
|
||||
loadBlock(prev, stop);
|
||||
});
|
||||
}
|
||||
|
||||
function done() {
|
||||
waiting--;
|
||||
e.emit('progress', count - waiting, count);
|
||||
if (waiting === 0) {
|
||||
if (id)
|
||||
self.unwatch(id);
|
||||
self.searching = false;
|
||||
self.emit('_searchEnd');
|
||||
e.emit('end');
|
||||
}
|
||||
}
|
||||
|
||||
// Empty search
|
||||
if (hashes.length === 0) {
|
||||
bcoin.utils.nextTick(function() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user