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]);
|
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
|
// 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++) {
|
for (var i = 0; i < this.block.list.length; i++) {
|
||||||
if (this.block.list[i].hash('hex') === hash) {
|
if (this.block.list[i].hash('hex') === hash) {
|
||||||
// NOTE: we return right after the statement - so `block` should be
|
// 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))
|
if (this.request.add(hash, cb))
|
||||||
|
false;
|
||||||
this.emit('missing', hash, null, null);
|
this.emit('missing', hash, null, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -344,7 +350,21 @@ Chain.prototype.hashesInRange = function hashesInRange(start, end, cb) {
|
|||||||
start--;
|
start--;
|
||||||
end = utils.binaryInsert(ts, end, compareTs, true);
|
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) {
|
Chain.prototype.getLast = function getLast(cb) {
|
||||||
|
|||||||
@ -62,6 +62,7 @@ function Pool(options) {
|
|||||||
// getTX map
|
// getTX map
|
||||||
map: {}
|
map: {}
|
||||||
};
|
};
|
||||||
|
this.searching = false;
|
||||||
|
|
||||||
// Currently broadcasted TXs
|
// Currently broadcasted TXs
|
||||||
this.tx = {
|
this.tx = {
|
||||||
@ -355,7 +356,18 @@ Pool.prototype.unwatch = function unwatch(id) {
|
|||||||
this.peers.block[i].updateWatch();
|
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
|
// Optional id argument
|
||||||
if (typeof id === 'object' && !Array.isArray(id) ||
|
if (typeof id === 'object' && !Array.isArray(id) ||
|
||||||
typeof id === 'number') {
|
typeof id === 'number') {
|
||||||
@ -378,33 +390,52 @@ Pool.prototype.search = function search(id, range) {
|
|||||||
range.start = +new Date() / 1000 - 432000;
|
range.start = +new Date() / 1000 - 432000;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var e = new EventEmitter();
|
this.chain.hashesInRange(range.start, range.end, function(hashes, count) {
|
||||||
this.chain.hashesInRange(range.start, range.end, function(hashes) {
|
var waiting = count;
|
||||||
var waiting = hashes.length;
|
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
self.watch(id);
|
self.watch(id);
|
||||||
|
|
||||||
self._loadRange(hashes, true);
|
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
|
// 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
|
// Get block's prev and request it and all of it's parents up to
|
||||||
// the next known block hash
|
// the next known block hash
|
||||||
self.chain.get(block.prevBlock, function() {
|
self.chain.get(block.prevBlock, block.prevBlock !== stop, function(prev) {
|
||||||
waiting--;
|
done();
|
||||||
e.emit('progress', hashes.length - waiting, hashes.length);
|
|
||||||
if (waiting === 0) {
|
// First hash loaded
|
||||||
if (id)
|
if (!stop)
|
||||||
self.unwatch(id);
|
return;
|
||||||
e.emit('end');
|
|
||||||
}
|
// 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
|
// Empty search
|
||||||
if (hashes.length === 0) {
|
if (hashes.length === 0) {
|
||||||
bcoin.utils.nextTick(function() {
|
bcoin.utils.nextTick(function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user