From 4f0289f5abaa0d9940c64a2da9672f2d3a5db30f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 10 Mar 2016 18:22:02 -0800 Subject: [PATCH] use global ldb cache. --- lib/bcoin.js | 1 + lib/bcoin/blockdb.js | 104 +----------------------------------------- lib/bcoin/chaindb.js | 25 +--------- lib/bcoin/ldb.js | 36 +++++++++++++++ lib/bcoin/walletdb.js | 31 ++----------- 5 files changed, 45 insertions(+), 152 deletions(-) create mode 100644 lib/bcoin/ldb.js diff --git a/lib/bcoin.js b/lib/bcoin.js index 4f053328..7c8b34dd 100644 --- a/lib/bcoin.js +++ b/lib/bcoin.js @@ -83,6 +83,7 @@ bcoin.output = require('./bcoin/output'); bcoin.coin = require('./bcoin/coin'); bcoin.tx = require('./bcoin/tx'); bcoin.mtx = require('./bcoin/mtx'); +bcoin.ldb = require('./bcoin/ldb'); bcoin.txpool = require('./bcoin/tx-pool'); bcoin.txdb = require('./bcoin/txdb'); bcoin.abstractblock = require('./bcoin/abstractblock'); diff --git a/lib/bcoin/blockdb.js b/lib/bcoin/blockdb.js index 7b530160..a8e7c7af 100644 --- a/lib/bcoin/blockdb.js +++ b/lib/bcoin/blockdb.js @@ -18,48 +18,23 @@ var pad32 = utils.pad32; function BlockDB(node, options) { var self = this; - var levelup; if (!(this instanceof BlockDB)) return new BlockDB(node, options); - // Some lazy loading - levelup = require('levelup'); - EventEmitter.call(this); if (!options) options = {}; - this.file = options.indexFile; - - bcoin.ensurePrefix(); - - if (!this.file) - this.file = bcoin.prefix + '/block-' + network.type + '.db'; - this.options = options; this.fsync = !!options.fsync; this.node = node; - this.cache = { - 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, + this.db = bcoin.ldb('block', { cacheSize: 16 * 1024 * 1024, - writeBufferSize: 8 * 1024 * 1024, - maxOpenFiles: 8192, - db: bcoin.isBrowser - ? require('level-js') - : require('level' + 'down') + writeBufferSize: 8 * 1024 * 1024 }); } @@ -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) { var self = this; 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); - - if (self.options.cache) - self.cache.unspent.remove(input.prevout.hash + '/' + input.prevout.index); }); tx.outputs.forEach(function(output, i) { @@ -280,9 +194,6 @@ BlockDB.prototype.disconnectBlock = function disconnectBlock(hash, callback, bat var hash = tx.hash('hex'); var uniq = {}; - if (self.options.cache) - self.cache.tx.remove(hash); - tx.inputs.forEach(function(input) { var coin, address; @@ -329,9 +240,6 @@ BlockDB.prototype.disconnectBlock = function disconnectBlock(hash, callback, bat } 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) return next(); - if (self.options.cache) - self.cache.unspent.set(id, coin); - coins.push(coin); next(); }); @@ -577,11 +482,6 @@ BlockDB.prototype.getTXByAddress = function getTXByAddress(addresses, options, c have[hash] = true; } - if (self.options.cache && self.cache.tx.has(hash)) { - txs.push(self.cache.tx.get(hash)); - return next(); - } - hashes.push(hash); }); })(); diff --git a/lib/bcoin/chaindb.js b/lib/bcoin/chaindb.js index 9c53305f..9f2cf590 100644 --- a/lib/bcoin/chaindb.js +++ b/lib/bcoin/chaindb.js @@ -31,15 +31,6 @@ function ChainDB(node, chain, options) { this.node = node; this.network = node.network; this.chain = chain; - this.file = options.file; - - if (!this.file) { - this.file = bcoin.prefix - + '/chain-' - + (options.spv ? 'spv-' : '') - + network.type - + '.db'; - } this.queue = {}; this.queueSize = 0; @@ -74,22 +65,10 @@ function ChainDB(node, chain, options) { utils.inherits(ChainDB, EventEmitter); ChainDB.prototype._init = function _init() { - var levelup = require('levelup'); - - bcoin.ensurePrefix(); - - this.db = new levelup(this.file, { - keyEncoding: 'ascii', - valueEncoding: 'binary', - createIfMissing: true, - errorIfExists: false, + this.db = bcoin.ldb((this.options.spv ? 'spv' : '') + 'chain', { compression: false, cacheSize: 16 * 1024 * 1024, - writeBufferSize: 8 * 1024 * 1024, - maxOpenFiles: 8192, - db: bcoin.isBrowser - ? require('level-js') - : require('level' + 'down') + writeBufferSize: 8 * 1024 * 1024 }); }; diff --git a/lib/bcoin/ldb.js b/lib/bcoin/ldb.js new file mode 100644 index 00000000..25af3787 --- /dev/null +++ b/lib/bcoin/ldb.js @@ -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]; +}; diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index fdc2422b..bc73e000 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -7,7 +7,6 @@ var EventEmitter = require('events').EventEmitter; var bcoin = require('../bcoin'); -var levelup = require('levelup'); var bn = require('bn.js'); var constants = bcoin.protocol.constants; var network = bcoin.protocol.network; @@ -36,12 +35,6 @@ function WalletDB(node, options) { this.node = node; this.options = options; - this.file = options.file; - - bcoin.ensurePrefix(); - - if (!this.file) - this.file = bcoin.prefix + '/wallet-' + network.type + '.db'; WalletDB.global = this; @@ -93,27 +86,11 @@ WalletDB.prototype.dump = function dump(callback) { WalletDB.prototype._init = function _init() { var self = this; - var levelup; - if (!WalletDB._db[this.file]) { - // Some lazy loading - levelup = require('levelup'); - 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.db = bcoin.ldb('wallet', { + cacheSize: 4 * 1024 * 1024, + writeBufferSize: 4 * 1024 * 1024 + }); this.tx = new bcoin.txdb('w', this.db, { ids: true