var pager = require('memory-pager') module.exports = Bitfield function Bitfield (opts) { if (!(this instanceof Bitfield)) return new Bitfield(opts) if (!opts) opts = {} if (Buffer.isBuffer(opts)) opts = {buffer: opts} this.pageOffset = opts.pageOffset || 0 this.pageSize = opts.pageSize || 1024 this.pages = opts.pages || pager(this.pageSize) this.byteLength = this.pages.length * this.pageSize this.length = 8 * this.byteLength if (!powerOfTwo(this.pageSize)) throw new Error('The page size should be a power of two') this._trackUpdates = !!opts.trackUpdates this._pageMask = this.pageSize - 1 if (opts.buffer) { for (var i = 0; i < opts.buffer.length; i += this.pageSize) { this.pages.set(i / this.pageSize, opts.buffer.slice(i, i + this.pageSize)) } this.byteLength = opts.buffer.length this.length = 8 * this.byteLength } } Bitfield.prototype.get = function (i) { var o = i & 7 var j = (i - o) / 8 return !!(this.getByte(j) & (128 >> o)) } Bitfield.prototype.getByte = function (i) { var o = i & this._pageMask var j = (i - o) / this.pageSize var page = this.pages.get(j, true) return page ? page.buffer[o + this.pageOffset] : 0 } Bitfield.prototype.set = function (i, v) { var o = i & 7 var j = (i - o) / 8 var b = this.getByte(j) return this.setByte(j, v ? b | (128 >> o) : b & (255 ^ (128 >> o))) } Bitfield.prototype.toBuffer = function () { var all = alloc(this.pages.length * this.pageSize) for (var i = 0; i < this.pages.length; i++) { var next = this.pages.get(i, true) var allOffset = i * this.pageSize if (next) next.buffer.copy(all, allOffset, this.pageOffset, this.pageOffset + this.pageSize) } return all } Bitfield.prototype.setByte = function (i, b) { var o = i & this._pageMask var j = (i - o) / this.pageSize var page = this.pages.get(j, false) o += this.pageOffset if (page.buffer[o] === b) return false page.buffer[o] = b if (i >= this.byteLength) { this.byteLength = i + 1 this.length = this.byteLength * 8 } if (this._trackUpdates) this.pages.updated(page) return true } function alloc (n) { if (Buffer.alloc) return Buffer.alloc(n) var b = new Buffer(n) b.fill(0) return b } function powerOfTwo (x) { return !(x & (x - 1)) }