/
fsreadcache.js
63 lines (46 loc) · 1.55 KB
/
fsreadcache.js
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
var fs = require('fs')
, AsyncCache = require('async-cache')
, setImmediate = global.setImmediate || process.nextTick
module.exports = function (options) {
options = options || {}
cacheSize = options.cacheSize || 100 * 1024 * 1024
var cache = new AsyncCache({
max: cacheSize
, length: function (n) { return n.length }
, load: function (fd, callback) {
fd = parseInt(fd, 10)
fs.fstat(fd, function (err, stat) {
if (err) return callback(err)
data = new Buffer(stat.size)
fs.read(fd, data, 0, data.length, 0, function (err) {
if (err)
return callback(err)
callback(null, data)
})
})
}
})
, read = function (fd, buffer, offset, length, position, callback) {
cache.get(fd, function (err, data) {
if (err) return callback(err)
data.copy(buffer, offset, position, position + length)
setImmediate(callback)
})
}
, write = function (fd, buffer, offset, length, position, callback) {
fs.write(fd, buffer, offset, length, position, function (err) {
var value
if (err) return callback(err)
if (position !== null || !(value = cache.peek(fd))) {
cache.del(fd)
} else {
cache.set(fd, Buffer.concat([ value, buffer.slice(offset, offset + length) ]))
}
callback(null)
})
}
return {
read: read
, write: write
}
}