diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 65ec53a6..0317ab97 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -720,7 +720,7 @@ function ChainDB(chain, options) { this._queue = []; this._cache = {}; - this._bufferPool = {}; + this._bufferPool = { used: {} }; this._nullBlock = new Buffer(BLOCK_SIZE); this._nullBlock.fill(0); this.tip = -1; @@ -764,16 +764,25 @@ ChainDB.prototype._init = function _init() { this.fd = fs.openSync(this.file, 'r+'); }; -ChainDB.prototype.getBuffer = function(size) { +ChainDB.prototype._malloc = function(size) { if (!this._bufferPool[size]) this._bufferPool[size] = new Buffer(size); - // if (this._bufferPool[size].__used) - // return new Buffer(size); + if (this._bufferPool.used[size] === this._bufferPool[size]) + return new Buffer(size); + + this._bufferPool.used[size] = this._bufferPool[size]; return this._bufferPool[size]; }; +ChainDB.prototype._free = function(buf) { + if (this._bufferPool.used[buf.length] === buf) { + assert(this._bufferPool[buf.length] === buf); + delete this._bufferPool.used[buf.length]; + } +}; + ChainDB.prototype.exists = function exists() { try { fs.statSync(this.file); @@ -982,46 +991,56 @@ ChainDB.prototype.isNull = function isNull(height) { }; ChainDB.prototype._read = function _read(size, offset) { - var data = this.getBuffer(size); var index = 0; - var bytes; + var data, bytes; if (offset < 0 || offset == null) return; + data = this._malloc(size); + try { while (bytes = fs.readSync(this.fd, data, index, size, offset)) { index += bytes; size -= bytes; offset += bytes; - if (index === data.length) + if (index === data.length) { + this._free(data); return data; + } } } catch (e) { - return; + ; } + + this._free(data); }; ChainDB.prototype._readAsync = function _read(size, offset, callback) { var self = this; - var data = new Buffer(size); var index = 0; - var bytes; + var data, bytes; if (offset < 0 || offset == null) return false; + data = this._malloc(size); + (function callee() { fs.read(self.fd, data, index, size, offset, function(err, bytes) { - if (err) + if (err) { + self._free(data); return callback(err); + } index += bytes; size -= bytes; offset += bytes; - if (index === data.length) + if (index === data.length) { + self._free(data); return callback(null, data); + } callee(); });