summaryrefslogtreecommitdiffstats
path: root/node_modules/memory-pager/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/memory-pager/index.js')
-rw-r--r--node_modules/memory-pager/index.js160
1 files changed, 160 insertions, 0 deletions
diff --git a/node_modules/memory-pager/index.js b/node_modules/memory-pager/index.js
new file mode 100644
index 0000000..687f346
--- /dev/null
+++ b/node_modules/memory-pager/index.js
@@ -0,0 +1,160 @@
+module.exports = Pager
+
+function 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
+}