use global ldb cache.
This commit is contained in:
parent
ef3519761c
commit
4f0289f5ab
@ -83,6 +83,7 @@ bcoin.output = require('./bcoin/output');
|
|||||||
bcoin.coin = require('./bcoin/coin');
|
bcoin.coin = require('./bcoin/coin');
|
||||||
bcoin.tx = require('./bcoin/tx');
|
bcoin.tx = require('./bcoin/tx');
|
||||||
bcoin.mtx = require('./bcoin/mtx');
|
bcoin.mtx = require('./bcoin/mtx');
|
||||||
|
bcoin.ldb = require('./bcoin/ldb');
|
||||||
bcoin.txpool = require('./bcoin/tx-pool');
|
bcoin.txpool = require('./bcoin/tx-pool');
|
||||||
bcoin.txdb = require('./bcoin/txdb');
|
bcoin.txdb = require('./bcoin/txdb');
|
||||||
bcoin.abstractblock = require('./bcoin/abstractblock');
|
bcoin.abstractblock = require('./bcoin/abstractblock');
|
||||||
|
|||||||
@ -18,48 +18,23 @@ var pad32 = utils.pad32;
|
|||||||
|
|
||||||
function BlockDB(node, options) {
|
function BlockDB(node, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var levelup;
|
|
||||||
|
|
||||||
if (!(this instanceof BlockDB))
|
if (!(this instanceof BlockDB))
|
||||||
return new BlockDB(node, options);
|
return new BlockDB(node, options);
|
||||||
|
|
||||||
// Some lazy loading
|
|
||||||
levelup = require('levelup');
|
|
||||||
|
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
options = {};
|
options = {};
|
||||||
|
|
||||||
this.file = options.indexFile;
|
|
||||||
|
|
||||||
bcoin.ensurePrefix();
|
|
||||||
|
|
||||||
if (!this.file)
|
|
||||||
this.file = bcoin.prefix + '/block-' + network.type + '.db';
|
|
||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.fsync = !!options.fsync;
|
this.fsync = !!options.fsync;
|
||||||
|
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
|
||||||
this.cache = {
|
this.db = bcoin.ldb('block', {
|
||||||
unspent: new bcoin.lru(200000),
|
|
||||||
tx: new bcoin.lru(50000)
|
|
||||||
};
|
|
||||||
|
|
||||||
this.db = new levelup(this.file, {
|
|
||||||
keyEncoding: 'ascii',
|
|
||||||
valueEncoding: 'binary',
|
|
||||||
createIfMissing: true,
|
|
||||||
errorIfExists: false,
|
|
||||||
compression: true,
|
|
||||||
cacheSize: 16 * 1024 * 1024,
|
cacheSize: 16 * 1024 * 1024,
|
||||||
writeBufferSize: 8 * 1024 * 1024,
|
writeBufferSize: 8 * 1024 * 1024
|
||||||
maxOpenFiles: 8192,
|
|
||||||
db: bcoin.isBrowser
|
|
||||||
? require('level-js')
|
|
||||||
: require('level' + 'down')
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,64 +50,6 @@ BlockDB.prototype.close = function close(callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockDB.prototype.migrate = function migrate(blockSize, compression, callback) {
|
|
||||||
var options, db, iter, total;
|
|
||||||
|
|
||||||
callback = utils.ensure(callback);
|
|
||||||
options = utils.merge({}, this.db.options);
|
|
||||||
|
|
||||||
if (blockSize != null)
|
|
||||||
options.blockSize = blockSize;
|
|
||||||
|
|
||||||
if (compression != null)
|
|
||||||
options.compression = compression;
|
|
||||||
|
|
||||||
options.maxOpenFiles = 60000;
|
|
||||||
|
|
||||||
utils.debug('Migrating DB with options:');
|
|
||||||
utils.debug(options);
|
|
||||||
|
|
||||||
db = new levelup(this.file + '.migrated', options);
|
|
||||||
|
|
||||||
total = 0;
|
|
||||||
|
|
||||||
iter = this.db.db.iterator({
|
|
||||||
keys: true,
|
|
||||||
values: true,
|
|
||||||
fillCache: false,
|
|
||||||
keyAsBuffer: false,
|
|
||||||
valueAsBuffer: true
|
|
||||||
});
|
|
||||||
|
|
||||||
(function next() {
|
|
||||||
iter.next(function(err, key, value) {
|
|
||||||
var height;
|
|
||||||
|
|
||||||
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) {
|
BlockDB.prototype.saveBlock = function saveBlock(block, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var batch = this.batch();
|
var batch = this.batch();
|
||||||
@ -222,9 +139,6 @@ BlockDB.prototype.connectBlock = function connectBlock(block, callback, batch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
batch.del('u/t/' + input.prevout.hash + '/' + input.prevout.index);
|
batch.del('u/t/' + input.prevout.hash + '/' + input.prevout.index);
|
||||||
|
|
||||||
if (self.options.cache)
|
|
||||||
self.cache.unspent.remove(input.prevout.hash + '/' + input.prevout.index);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tx.outputs.forEach(function(output, i) {
|
tx.outputs.forEach(function(output, i) {
|
||||||
@ -280,9 +194,6 @@ BlockDB.prototype.disconnectBlock = function disconnectBlock(hash, callback, bat
|
|||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var uniq = {};
|
var uniq = {};
|
||||||
|
|
||||||
if (self.options.cache)
|
|
||||||
self.cache.tx.remove(hash);
|
|
||||||
|
|
||||||
tx.inputs.forEach(function(input) {
|
tx.inputs.forEach(function(input) {
|
||||||
var coin, address;
|
var coin, address;
|
||||||
|
|
||||||
@ -329,9 +240,6 @@ BlockDB.prototype.disconnectBlock = function disconnectBlock(hash, callback, bat
|
|||||||
}
|
}
|
||||||
|
|
||||||
batch.del('u/t/' + hash + '/' + i);
|
batch.del('u/t/' + hash + '/' + i);
|
||||||
|
|
||||||
if (self.options.cache)
|
|
||||||
self.cache.unspent.remove(hash + '/' + i);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -487,9 +395,6 @@ BlockDB.prototype.getCoinsByAddress = function getCoinsByAddress(addresses, opti
|
|||||||
if (!coin)
|
if (!coin)
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
if (self.options.cache)
|
|
||||||
self.cache.unspent.set(id, coin);
|
|
||||||
|
|
||||||
coins.push(coin);
|
coins.push(coin);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -577,11 +482,6 @@ BlockDB.prototype.getTXByAddress = function getTXByAddress(addresses, options, c
|
|||||||
have[hash] = true;
|
have[hash] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.options.cache && self.cache.tx.has(hash)) {
|
|
||||||
txs.push(self.cache.tx.get(hash));
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
hashes.push(hash);
|
hashes.push(hash);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@ -31,15 +31,6 @@ function ChainDB(node, chain, options) {
|
|||||||
this.node = node;
|
this.node = node;
|
||||||
this.network = node.network;
|
this.network = node.network;
|
||||||
this.chain = chain;
|
this.chain = chain;
|
||||||
this.file = options.file;
|
|
||||||
|
|
||||||
if (!this.file) {
|
|
||||||
this.file = bcoin.prefix
|
|
||||||
+ '/chain-'
|
|
||||||
+ (options.spv ? 'spv-' : '')
|
|
||||||
+ network.type
|
|
||||||
+ '.db';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.queue = {};
|
this.queue = {};
|
||||||
this.queueSize = 0;
|
this.queueSize = 0;
|
||||||
@ -74,22 +65,10 @@ function ChainDB(node, chain, options) {
|
|||||||
utils.inherits(ChainDB, EventEmitter);
|
utils.inherits(ChainDB, EventEmitter);
|
||||||
|
|
||||||
ChainDB.prototype._init = function _init() {
|
ChainDB.prototype._init = function _init() {
|
||||||
var levelup = require('levelup');
|
this.db = bcoin.ldb((this.options.spv ? 'spv' : '') + 'chain', {
|
||||||
|
|
||||||
bcoin.ensurePrefix();
|
|
||||||
|
|
||||||
this.db = new levelup(this.file, {
|
|
||||||
keyEncoding: 'ascii',
|
|
||||||
valueEncoding: 'binary',
|
|
||||||
createIfMissing: true,
|
|
||||||
errorIfExists: false,
|
|
||||||
compression: false,
|
compression: false,
|
||||||
cacheSize: 16 * 1024 * 1024,
|
cacheSize: 16 * 1024 * 1024,
|
||||||
writeBufferSize: 8 * 1024 * 1024,
|
writeBufferSize: 8 * 1024 * 1024
|
||||||
maxOpenFiles: 8192,
|
|
||||||
db: bcoin.isBrowser
|
|
||||||
? require('level-js')
|
|
||||||
: require('level' + 'down')
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
36
lib/bcoin/ldb.js
Normal file
36
lib/bcoin/ldb.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* ldb.js - global ldb tracker
|
||||||
|
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||||
|
* https://github.com/indutny/bcoin
|
||||||
|
*/
|
||||||
|
|
||||||
|
var bcoin = require('../bcoin');
|
||||||
|
var network = bcoin.protocol.network;
|
||||||
|
var db = {};
|
||||||
|
|
||||||
|
module.exports = function ldb(name, options) {
|
||||||
|
var levelup = require('levelup');
|
||||||
|
var file = bcoin.prefix + '/' + name + '-' + network.type + '.db';
|
||||||
|
var cacheSize = options.cacheSize || 8 * 1024 * 1024;
|
||||||
|
var writeBufferSize = options.writeBufferSize || (cacheSize / 2 | 0);
|
||||||
|
|
||||||
|
bcoin.ensurePrefix();
|
||||||
|
|
||||||
|
if (!db[file]) {
|
||||||
|
db[file] = new levelup(file, {
|
||||||
|
keyEncoding: 'ascii',
|
||||||
|
valueEncoding: 'binary',
|
||||||
|
createIfMissing: true,
|
||||||
|
errorIfExists: false,
|
||||||
|
compression: options.compression !== false,
|
||||||
|
cacheSize: cacheSize,
|
||||||
|
writeBufferSize: writeBufferSize,
|
||||||
|
maxOpenFiles: options.maxOpenFiles || 8192,
|
||||||
|
db: bcoin.isBrowser
|
||||||
|
? require('level-js')
|
||||||
|
: require('level' + 'down')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return db[file];
|
||||||
|
};
|
||||||
@ -7,7 +7,6 @@
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
var bcoin = require('../bcoin');
|
var bcoin = require('../bcoin');
|
||||||
var levelup = require('levelup');
|
|
||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
var constants = bcoin.protocol.constants;
|
var constants = bcoin.protocol.constants;
|
||||||
var network = bcoin.protocol.network;
|
var network = bcoin.protocol.network;
|
||||||
@ -36,12 +35,6 @@ function WalletDB(node, options) {
|
|||||||
|
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.file = options.file;
|
|
||||||
|
|
||||||
bcoin.ensurePrefix();
|
|
||||||
|
|
||||||
if (!this.file)
|
|
||||||
this.file = bcoin.prefix + '/wallet-' + network.type + '.db';
|
|
||||||
|
|
||||||
WalletDB.global = this;
|
WalletDB.global = this;
|
||||||
|
|
||||||
@ -93,27 +86,11 @@ WalletDB.prototype.dump = function dump(callback) {
|
|||||||
|
|
||||||
WalletDB.prototype._init = function _init() {
|
WalletDB.prototype._init = function _init() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var levelup;
|
|
||||||
|
|
||||||
if (!WalletDB._db[this.file]) {
|
this.db = bcoin.ldb('wallet', {
|
||||||
// Some lazy loading
|
cacheSize: 4 * 1024 * 1024,
|
||||||
levelup = require('levelup');
|
writeBufferSize: 4 * 1024 * 1024
|
||||||
WalletDB._db[this.file] = new levelup(this.file, {
|
});
|
||||||
keyEncoding: 'ascii',
|
|
||||||
valueEncoding: 'binary',
|
|
||||||
createIfMissing: true,
|
|
||||||
errorIfExists: false,
|
|
||||||
compression: true,
|
|
||||||
cacheSize: 4 * 1024 * 1024,
|
|
||||||
writeBufferSize: 4 * 1024 * 1024,
|
|
||||||
maxOpenFiles: 1024,
|
|
||||||
db: bcoin.isBrowser
|
|
||||||
? require('level-js')
|
|
||||||
: require('level' + 'down')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.db = WalletDB._db[this.file];
|
|
||||||
|
|
||||||
this.tx = new bcoin.txdb('w', this.db, {
|
this.tx = new bcoin.txdb('w', this.db, {
|
||||||
ids: true
|
ids: true
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user