| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | module.exports = Pagerfunction Pager (pageSize, opts) {  if (!(this instanceof Pager)) return new Pager(pageSize, opts)  this.length = 0  this.updates = []  this.path = new Uint16Array(4)  this.pages = new Array(32768)  this.maxPages = this.pages.length  this.level = 0  this.pageSize = pageSize || 1024  this.deduplicate = opts ? opts.deduplicate : null  this.zeros = this.deduplicate ? alloc(this.deduplicate.length) : null}Pager.prototype.updated = function (page) {  while (this.deduplicate && page.buffer[page.deduplicate] === this.deduplicate[page.deduplicate]) {    page.deduplicate++    if (page.deduplicate === this.deduplicate.length) {      page.deduplicate = 0      if (page.buffer.equals && page.buffer.equals(this.deduplicate)) page.buffer = this.deduplicate      break    }  }  if (page.updated || !this.updates) return  page.updated = true  this.updates.push(page)}Pager.prototype.lastUpdate = function () {  if (!this.updates || !this.updates.length) return null  var page = this.updates.pop()  page.updated = false  return page}Pager.prototype._array = function (i, noAllocate) {  if (i >= this.maxPages) {    if (noAllocate) return    grow(this, i)  }  factor(i, this.path)  var arr = this.pages  for (var j = this.level; j > 0; j--) {    var p = this.path[j]    var next = arr[p]    if (!next) {      if (noAllocate) return      next = arr[p] = new Array(32768)    }    arr = next  }  return arr}Pager.prototype.get = function (i, noAllocate) {  var arr = this._array(i, noAllocate)  var first = this.path[0]  var page = arr && arr[first]  if (!page && !noAllocate) {    page = arr[first] = new Page(i, alloc(this.pageSize))    if (i >= this.length) this.length = i + 1  }  if (page && page.buffer === this.deduplicate && this.deduplicate && !noAllocate) {    page.buffer = copy(page.buffer)    page.deduplicate = 0  }  return page}Pager.prototype.set = function (i, buf) {  var arr = this._array(i, false)  var first = this.path[0]  if (i >= this.length) this.length = i + 1  if (!buf || (this.zeros && buf.equals && buf.equals(this.zeros))) {    arr[first] = undefined    return  }  if (this.deduplicate && buf.equals && buf.equals(this.deduplicate)) {    buf = this.deduplicate  }  var page = arr[first]  var b = truncate(buf, this.pageSize)  if (page) page.buffer = b  else arr[first] = new Page(i, b)}Pager.prototype.toBuffer = function () {  var list = new Array(this.length)  var empty = alloc(this.pageSize)  var ptr = 0  while (ptr < list.length) {    var arr = this._array(ptr, true)    for (var i = 0; i < 32768 && ptr < list.length; i++) {      list[ptr++] = (arr && arr[i]) ? arr[i].buffer : empty    }  }  return Buffer.concat(list)}function grow (pager, index) {  while (pager.maxPages < index) {    var old = pager.pages    pager.pages = new Array(32768)    pager.pages[0] = old    pager.level++    pager.maxPages *= 32768  }}function truncate (buf, len) {  if (buf.length === len) return buf  if (buf.length > len) return buf.slice(0, len)  var cpy = alloc(len)  buf.copy(cpy)  return cpy}function alloc (size) {  if (Buffer.alloc) return Buffer.alloc(size)  var buf = new Buffer(size)  buf.fill(0)  return buf}function copy (buf) {  var cpy = Buffer.allocUnsafe ? Buffer.allocUnsafe(buf.length) : new Buffer(buf.length)  buf.copy(cpy)  return cpy}function Page (i, buf) {  this.offset = i * buf.length  this.buffer = buf  this.updated = false  this.deduplicate = 0}function factor (n, out) {  n = (n - (out[0] = (n & 32767))) / 32768  n = (n - (out[1] = (n & 32767))) / 32768  out[3] = ((n - (out[2] = (n & 32767))) / 32768) & 32767}
 |