You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					96 lines
				
				2.2 KiB
			
		
		
			
		
	
	
					96 lines
				
				2.2 KiB
			| 
											3 years ago
										 | 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)) | ||
|  | } |