index.js
2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module.exports = Pager
function Pager (pageSize) {
if (!(this instanceof Pager)) return new Pager(pageSize)
this.length = 0
this.updates = []
this.pages = new Array(16)
this.pageSize = pageSize || 1024
}
Pager.prototype.updated = function (page) {
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.get = function (i, noAllocate) {
if (i >= this.pages.length) {
if (noAllocate) return
this.pages = grow(this.pages, i, this.length)
}
var page = this.pages[i]
if (!page && !noAllocate) {
page = this.pages[i] = new Page(i, alloc(this.pageSize))
if (i >= this.length) this.length = i + 1
}
return page
}
Pager.prototype.set = function (i, buf) {
if (i >= this.pages.length) this.pages = grow(this.pages, i, this.length)
if (i >= this.length) this.length = i + 1
if (!buf) {
this.pages[i] = undefined
return
}
var page = this.pages[i]
var b = truncate(buf, this.pageSize)
if (page) page.buffer = b
else this.pages[i] = new Page(i, b)
}
Pager.prototype.toBuffer = function () {
var list = new Array(this.length)
var empty = alloc(this.pageSize)
for (var i = 0; i < list.length; i++) {
list[i] = this.pages[i] ? this.pages[i].buffer : empty
}
return Buffer.concat(list)
}
function grow (list, index, len) {
var nlen = list.length * 2
while (nlen <= index) nlen *= 2
var twice = new Array(nlen)
for (var i = 0; i < len; i++) twice[i] = list[i]
return twice
}
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 Page (i, buf) {
this.offset = i * buf.length
this.buffer = buf
this.updated = false
}