msiebuhr / slint

Lint-tool for web projects
BSD 3-Clause "New" or "Revised" License
7 stars 1 forks source link

Use LRU caching for avoiding disk I/O when doing directory traversal + file reading. #3

Closed msiebuhr closed 11 years ago

papandreou commented 11 years ago

May I humbly suggest accomplishing that using https://github.com/papandreou/node-memoizeasync wrapped around fs.readdir and fs.readFile?

If the LRU part is important, I can add that as a supported expiration scheme.

msiebuhr commented 11 years ago

Does sound good. A slim wrapper around stat() with IsFile() and IsDirectory() shortcuts would be nice as well.

papandreou commented 11 years ago

memoizeAsync@0.3.0 uses lru-cache to do the actual caching and exposes its options, so that should be possible using something like this:

var memoizeAsync = require('memoizeasync'),
    fs = require('fs'),
    memoizedFs = {
        readdir: memoizeAsync(fs.readdir, {
            max: 10000,
            length: function (err, results) {
                return results ? results.length : 5; // Arbitrarily count memoized errors as equivalent to 5 items
            }
        }),
        readFile: memoizeAsync(fs.readFile, {
            max: 40 * 1024 * 1024,
            length: function (err, body) {
                if (Buffer.isBuffer(body) || typeof body === 'string') {
                    // Should actually be Buffer.byteLength(body) for strings, but that would need to plow through the entire thing
                    return body.length;
                }
                return 512; // Arbitrarily count memoized errors as equivalent to half a kilobyte
            })
        }),
        stat: memoizeAsync(fs.stat, {max: 10000})
    };

Next up would be figuring out how to make glob use memoizedFs.

papandreou commented 11 years ago
memoizedFs.isFile = function (fileName, cb) {
    memoizedFs.stat(fileName, function (err, stats) {
        cb(null, !err && stats.isFile());
    });
});