blockdb improvements.

This commit is contained in:
Christopher Jeffrey 2016-03-10 14:39:37 -08:00
parent 419ba83058
commit f09a4dc8f7

View File

@ -76,9 +76,9 @@ BlockDB.prototype.close = function close(callback) {
};
BlockDB.prototype.migrate = function migrate(blockSize, compression, callback) {
var options, db, pending, stream, total, done;
var options, db, iter, total;
callback = utils.once(callback);
callback = utils.ensure(callback);
options = utils.merge({}, this.db.options);
if (blockSize != null)
@ -89,43 +89,48 @@ BlockDB.prototype.migrate = function migrate(blockSize, compression, callback) {
options.maxOpenFiles = 60000;
utils.print('Migrating DB with options:');
utils.print(options);
utils.debug('Migrating DB with options:');
utils.debug(options);
db = levelup(this.file + '.migrated', options);
db = new levelup(this.file + '.migrated', options);
stream = this.db.createReadStream();
pending = 0;
total = 0;
function onPut(err) {
if (err)
return callback(err);
if (++total % 10000 === 0)
utils.print('%d written.', total);
pending--;
if (done && !pending)
callback();
}
stream.on('data', function(data) {
pending++;
db.put(data.key, data.value, onPut);
iter = this.db.db.iterator({
keys: true,
values: true,
fillCache: false,
keyAsBuffer: false,
valueAsBuffer: true
});
stream.on('error', function(err) {
callback(err);
});
(function next() {
iter.next(function(err, key, value) {
var height;
stream.on('end', function() {
done = true;
if (!pending)
callback();
});
if (err) {
return iter.end(function() {
callback(err);
});
}
if (key === undefined)
return iter.end(callback);
db.put(key, value, function(err) {
if (err) {
return iter.end(function() {
callback(err);
});
}
if (++total % 10000 === 0)
utils.print('%d written.', total);
next();
});
});
})();
};
BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
@ -169,6 +174,8 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch) {
var self = this;
this._getCoinBlock(block, function(err, block) {
var height;
if (err)
return callback(err);
@ -182,6 +189,10 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch) {
batch.put('b/h/' + pad32(block.height), block.hash());
height = new Buffer(4);
utils.writeU32(height, block.height, 0);
batch.put('b/t', height);
block.txs.forEach(function(tx, i) {
var hash = tx.hash('hex');
var uniq = {};
@ -262,6 +273,7 @@ BlockDB.prototype.disconnectBlock = function disconnectBlock(hash, callback, bat
if (typeof hash === 'string')
assert(block.hash('hex') === hash);
batch.del('b/t');
batch.del('b/h/' + pad32(block.height));
block.txs.forEach(function(tx, i) {
@ -937,43 +949,36 @@ BlockDB.prototype.isSpent = function isSpent(hash, index, callback) {
BlockDB.prototype.getHeight = function getHeight(callback) {
var self = this;
var maxHeight = -1;
var iter;
iter = this.db.db.iterator({
gte: 'b/h',
lte: 'b/h~',
keys: true,
values: false,
fillCache: false,
keyAsBuffer: false
return this.db.get('b/t', function(err, height) {
if (err && err.type !== 'NotFoundError')
return callback(err);
if (!height)
return callback(null, -1);
return callback(null, utils.readU32(height, 0));
});
};
(function next() {
iter.next(function(err, key, value) {
var height;
BlockDB.prototype.getTipHash = function getTipHash(callback) {
return this.getHeight(function(err, height) {
if (err)
return callback(err);
if (err) {
return iter.end(function() {
callback(err);
});
}
if (height === -1)
return callback();
if (key === undefined) {
return iter.end(function(err) {
if (err)
return callback(err);
callback(null, maxHeight);
});
}
return self.db.get('b/h/' + pad32(height), function(err, hash) {
if (err && err.type !== 'NotFoundError')
return callback(err);
height = +key.split('/')[2];
if (height > maxHeight)
maxHeight = height;
if (!hash)
return callback();
next();
return callback(null, utils.toHex(hash));
});
})();
});
};
BlockDB.prototype.reset = function reset(height, callback, emit) {