Skip to content

Commit

Permalink
more progress on cache, main thing now is to share chains for dirents…
Browse files Browse the repository at this point in the history
… AFAICT
  • Loading branch information
natevw committed Jun 13, 2014
1 parent 47f1952 commit b0afc4a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
10 changes: 10 additions & 0 deletions cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exports.wrapDriver = function (volume, opts) {
}, opts);

var cache = {},
advice = 'NORMAL',
secSize = volume.sectorSize;

function _freezeBuffer(b) {
Expand All @@ -15,6 +16,7 @@ exports.wrapDriver = function (volume, opts) {
}

function addToCache(i, data) {
if (advice === 'SEQUENTIAL' || advice === 'NOREUSE') return;
data = _freezeBuffer(data);
cache[i] = data;
//if (data.length > secSize) addToCache(i+1, data.slice(secSize));
Expand All @@ -32,12 +34,20 @@ exports.wrapDriver = function (volume, opts) {
return {
sectorSize: volume.sectorSize,
numSectors: volume.numSectors,
advice: function (val) {
if (!arguments) return adviceSource;
else advice = val;
if (advice === 'SEQUENTIAL' || advice === 'NOREUSE') cache = {};
return this;
},
readSectors: function (i, dest, cb) {
// TODO: handle having partial parts of dest!
if (i in cache && dest.length === secSize) {
//console.log("-in cache-", i);
cache[i].copy(dest);
setImmediate(cb);
} else volume.readSectors(i, dest, function (e) {
//console.log("HAD TO READ", i, advice, dest.toString(), Error().stack);
if (e) cb(e);
else addToCache(i, dest), cb();
});
Expand Down
13 changes: 8 additions & 5 deletions chains.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ var S = require("./structs.js"),
function _baseChain(vol) {
var chain = {};

chain.cacheAdvice = 'NORMAL';
chain.sectorSize = vol._sectorSize;

function posFromOffset(off) {
Expand All @@ -14,10 +13,14 @@ function _baseChain(vol) {
return {sector:sector, offset:offset};
}

var sectorCache = Object.create(null);
// TODO: manage sectorCache according to cacheAdvice
chain._vol_readSectors = vol._readSectors.bind(vol);
chain._vol_writeSectors = vol._writeSectors.bind(vol);
var sectorCache = vol._makeCache();
Object.defineProperty(chain, 'cacheAdvice', {
enumerable: true,
get: function () { return sectorCache.advice(); },
set: function (v) { sectorCache.advice(v); }
});
chain._vol_readSectors = vol._readSectors.bind(vol, sectorCache);
chain._vol_writeSectors = vol._writeSectors.bind(vol, sectorCache);

chain.readFromPosition = function (targetPos, buffer, cb) {
if (typeof targetPos === 'number') targetPos = posFromOffset(targetPos);
Expand Down
6 changes: 5 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ exports.createFileSystem = function (volume, opts, cb) {
fs._releaseEntry = function (entry) {
if (!entry._k) throw Error("Can't release entry not obtained via _sharedEntryForPath!");
var d = entriesByPath[entry._k];
if (!--d.s) delete entriesByPath[entry._k];
d.s -= 1;
setTimeout(function () {
if (!d.s) delete entriesByPath[entry._k];
});
};

fs._updateEntry = dir.updateEntry.bind(dir, vol);
Expand Down Expand Up @@ -117,6 +120,7 @@ exports.createFileSystem = function (volume, opts, cb) {
_fd.entry = fileEntry;
_fd.chain = fileChain;
if (f.append) _fd.pos = _fd.entry._size;
if (f._openDir) _fd.chain.cacheAdvice = 'WILLNEED';
if (f.truncate && _fd.entry._size) fs.ftruncate(fd, 0, function (e) {
cb(e, fd);
}, '_nested_');
Expand Down
12 changes: 7 additions & 5 deletions vol.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,26 @@ exports.init = function (volume, opts, bootSector) {
return firstDataSector + (n-2)*vol._sectorsPerCluster;
};

volume = $.wrapDriver(volume);
vol._makeCache = function () {
return $.wrapDriver(volume);
};

vol._readSectors = function (secNum, dest, cb) {
vol._readSectors = function (cache, secNum, dest, cb) {
if (typeof dest === 'function') {
cb = dest;
dest = new Buffer(vol._sectorSize);
}
_.log(_.log.DBG, "vol._readSectors", secNum, dest.length);
if (secNum < volume.numSectors) volume.readSectors(secNum, dest, function (e) { cb(e, dest); });
if (secNum < volume.numSectors) cache.readSectors(secNum, dest, function (e) { cb(e, dest); });
else throw Error("Invalid sector number!");
};

vol._writeSectors = function (secNum, data, cb) {
vol._writeSectors = function (cache, secNum, data, cb) {
_.log(_.log.DBG, "vol._writeSector", secNum, data.length);
// NOTE: these are internal assertions, public API will get proper `S.err`s
if (data.length % volume.sectorSize) throw Error("Buffer length not a multiple of sector size");
else if (opts.ro) throw Error("Read-only filesystem");
else if (secNum < volume.numSectors) volume.writeSectors(secNum, data, cb);
else if (secNum < volume.numSectors) cache.writeSectors(secNum, data, cb);
else throw Error("Invalid sector number!");
};

Expand Down

0 comments on commit b0afc4a

Please sign in to comment.