From 4df55b7ced07ceddcd3ea3624dc751858c05d1ff Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 3 Feb 2011 23:31:25 -0700 Subject: [PATCH] tested several variations --- lib/node-type-emitter.js | 88 +++++++++++++ lib/walk-jqueue-2.js | 79 ++++++++++++ lib/walk-jqueue-3.js | 86 +++++++++++++ lib/walk-queue.js | 165 ++++++++++++++++++++++++ lib/walk-recurse.js | 165 ++++++++++++++++++++++++ lib/walk.js | 227 +++++++++++----------------------- profile/walk-jqueue-2-test.js | 42 +++++++ profile/walk-jqueue-3-test.js | 123 ++++++++++++++++++ profile/walkq-test.js | 33 +++++ 9 files changed, 855 insertions(+), 153 deletions(-) create mode 100644 lib/node-type-emitter.js create mode 100644 lib/walk-jqueue-2.js create mode 100644 lib/walk-jqueue-3.js create mode 100644 lib/walk-queue.js create mode 100644 lib/walk-recurse.js create mode 100755 profile/walk-jqueue-2-test.js create mode 100755 profile/walk-jqueue-3-test.js create mode 100755 profile/walkq-test.js diff --git a/lib/node-type-emitter.js b/lib/node-type-emitter.js new file mode 100644 index 0000000..2c28de1 --- /dev/null +++ b/lib/node-type-emitter.js @@ -0,0 +1,88 @@ +(function () { + "use strict"; + + // "FIFO" isn't easy to convert to camelCase and back reliably + var isFnodeTypes = [ + "isFile", "isDirectory", "isSymbolicLink", "isBlockDevice", "isCharacterDevice", "isFIFO", "isSocket" + ], + fnodeTypes = [ + "file", "directory", "symbolicLink", "blockDevice", "characterDevice", "FIFO", "socket" + ], + fnodeTypesPlural = [ + "files", "directories", "symbolicLinks", "blockDevices", "characterDevices", "FIFOs", "sockets" + ]; + + + // + function createNodeGroups() { + var nodeGroups = {}; + fnodeTypesPlural.concat("nodes", "errors").forEach(function (fnodeTypePlural) { + nodeGroups[fnodeTypePlural] = []; + }); + return nodeGroups; + } + + + // Determine each file node's type + // + function sortFnodesByType(stat, fnodes) { + var i, isType; + + for (i = 0; i < isFnodeTypes.length; i += 1) { + isType = isFnodeTypes[i]; + if (stat[isType]()) { + stat.type = fnodeTypes[i]; + fnodes[fnodeTypesPlural[i]].push(stat); + return; + } + } + } + + + // Get the current number of listeners (which may change) + // Emit events to each listener + // Wait for all listeners to `next()` before continueing + // (in theory this may avoid disk thrashing) + function emitSingleEvents(emitter, path, stats, next) { + var num = 1 + emitter.listeners(stats.type).length + emitter.listeners("node").length; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + emitter.emit(stats.type, path, stats, nextWhenReady); + emitter.emit("node", path, stats, nextWhenReady); + nextWhenReady(); + } + + + // Since the risk for disk thrashing among anything + // other than files is relatively low, all types are + // emitted at once, but all must complete before advancing + function emitPluralEvents(emitter, path, nodes, next) { + var num = 1; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + fnodeTypesPlural.concat(["nodes", "errors"]).forEach(function (fnodeType) { + if (0 === nodes[fnodeType].length) { return; } + num += emitter.listeners(fnodeType).length; + emitter.emit(fnodeType, path, nodes[fnodeType], nextWhenReady); + }); + nextWhenReady(); + } + + module.exports = { + emitNodeType: emitSingleEvents, + emitNodeTypeGroups: emitPluralEvents, + isFnodeTypes: isFnodeTypes, + fnodeTypes: fnodeTypes, + fnodeTypesPlural: fnodeTypesPlural, + sortFnodesByType: sortFnodesByType, + createNodeGroups: createNodeGroups + }; +}()); diff --git a/lib/walk-jqueue-2.js b/lib/walk-jqueue-2.js new file mode 100644 index 0000000..00de986 --- /dev/null +++ b/lib/walk-jqueue-2.js @@ -0,0 +1,79 @@ +(function () { + "use strict" + + // Array.prototype.forEachAsync(next, item, i, collection) + require('futures/forEachAsync'); + + var fs = require('fs'), + EventEmitter = require('events').EventEmitter; + + // 2010-11-25 jorge@jorgechamorro.com + function create(pathname, cb) { + var emitter = new EventEmitter(), + q = [], + queue = [q], + curpath; + + function walk() { + fs.readdir(curpath, function(err, files) { + if (err) { + emitter.emit('error', curpath, err); + } + // XXX bug was here. next() was omitted + if (!files || 0 == files.length) { + return next(); + } + var stats = []; + emitter.emit('names', curpath, files, stats); + files.forEachAsync(function (cont, file) { + emitter.emit('name', curpath, file); + fs.lstat(curpath + '/' + file, function (err, stat) { + if (err) { + emitter.emit('error', curpath, err); + } + if (stat) { + stat.name = file; + stats.push(stat); + emitter.emit('stat', curpath, file, stat); + } + cont(); + }); + }).then(function () { + var dirs = [] + emitter.emit('stats', curpath, files, stats); + stats.forEach(function (stat) { + if (stat.isDirectory()) { + dirs.push(stat.name); + } + }); + dirs.forEach(fullPath); + queue.push(q = dirs); + next(); + }); + }); + } + + function next() { + if (q.length) { + curpath = q.pop(); + return walk(); + } + if (queue.length -= 1) { + q = queue[queue.length-1]; + return next(); + } + emitter.emit('end'); + } + + function fullPath(v,i,o) { + o[i]= [curpath, '/', v].join(''); + } + + curpath = pathname; + walk(); + + return emitter; + } + + module.exports = create; +}()); diff --git a/lib/walk-jqueue-3.js b/lib/walk-jqueue-3.js new file mode 100644 index 0000000..4903c7f --- /dev/null +++ b/lib/walk-jqueue-3.js @@ -0,0 +1,86 @@ +(function () { + "use strict" + + // Array.prototype.forEachAsync(next, item, i, collection) + require('futures/forEachAsync'); + + var fs = require('fs'), + EventEmitter = require('events').EventEmitter, + TypeEmitter = require('./node-type-emitter'); + + // 2010-11-25 jorge@jorgechamorro.com + function create(pathname, cb) { + var emitter = new EventEmitter(), + q = [], + queue = [q], + curpath; + + function walk() { + fs.readdir(curpath, function(err, files) { + if (err) { + emitter.emit('error', curpath, err); + } + // XXX bug was here. next() was omitted + if (!files || 0 == files.length) { + return next(); + } + var stats = [], + fnodeGroups = TypeEmitter.createNodeGroups(); + + // TODO could allow user to selectively stat + // and don't stat if there are no stat listeners + emitter.emit('names', curpath, files); + files.forEachAsync(function (cont, file) { + emitter.emit('name', curpath, file); + fs.lstat(curpath + '/' + file, function (err, stat) { + if (err) { + emitter.emit('error', curpath, err); + } + if (!stat) { + cont(); + } + stat.name = file; + stats.push(stat); + //emitter.emit('stat', curpath, file, stat); + TypeEmitter.sortFnodesByType(stat, fnodeGroups); + TypeEmitter.emitNodeType(emitter, curpath, stat, cont); + }); + }).then(function () { + var dirs = [] + //emitter.emit('stats', curpath, files, stats); + TypeEmitter.emitNodeTypeGroups(emitter, curpath, fnodeGroups, function () { + fnodeGroups.directories.forEach(function (stat) { + dirs.push(stat.name); + }); + dirs.forEach(fullPath); + queue.push(q = dirs); + next(); + }); + }); + }); + } + + function next() { + if (q.length) { + curpath = q.pop(); + return walk(); + } + if (queue.length -= 1) { + q = queue[queue.length-1]; + return next(); + } + emitter.emit('end'); + } + + function fullPath(v,i,o) { + o[i]= [curpath, '/', v].join(''); + } + + curpath = pathname; + walk(); + + return emitter; + } + + module.exports = create; +}()); diff --git a/lib/walk-queue.js b/lib/walk-queue.js new file mode 100644 index 0000000..a403066 --- /dev/null +++ b/lib/walk-queue.js @@ -0,0 +1,165 @@ +(function () { + "use strict"; + + var fs = require('fs'), + fstat = fs.lstat, + Futures = require('futures'), + EventEmitter = require('events').EventEmitter, + upath = require('path'), + // "FIFO" isn't easy to convert to camelCase and back reliably + isFnodeTypes = [ + "isFile", "isDirectory", "isBlockDevice", "isCharacterDevice", "isSymbolicLink", "isFIFO", "isSocket" + ], + fnodeTypes = [ + "file", "directory", "blockDevice", "characterDevice", "symbolicLink", "FIFO", "socket" + ], + fnodeTypesPlural = [ + "files", "directories", "blockDevices", "characterDevices", "symbolicLinks", "FIFOs", "sockets" + ]; + + // Get the current number of listeners (which may change) + // Emit events to each listener + // Wait for all listeners to `next()` before continueing + // (in theory this may avoid disk thrashing) + function emitSingleEvents(emitter, path, stats, next) { + var num = 1 + emitter.listeners(stats.type).length + emitter.listeners("node").length; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + emitter.emit(stats.type, path, stats, nextWhenReady); + emitter.emit("node", path, stats, nextWhenReady); + nextWhenReady(); + } + + + // Since the risk for disk thrashing among anything + // other than files is relatively low, all types are + // emitted at once, but all must complete before advancing + function emitPluralEvents(emitter, path, nodes, next) { + var num = 1; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + fnodeTypesPlural.concat(["nodes", "errors"]).forEach(function (fnodeType) { + if (0 === nodes[fnodeType].length) { return; } + num += emitter.listeners(fnodeType).length; + emitter.emit(fnodeType, path, nodes[fnodeType], nextWhenReady); + }); + nextWhenReady(); + } + + + // Determine each file node's type + // + function sortFnodesByType(stats, fnodes) { + isFnodeTypes.forEach(function (isType, i) { + if (stats[isType]()) { + if (stats.type) { throw new Error("is_" + type + " and " + isType); } + stats.type = fnodeTypes[i]; + fnodes[fnodeTypesPlural[i]].push(stats); + //console.log(isType, fnodeTypesPlural[i], stats.name); + // TODO throw to break; + } + }); + /* + // Won't really ever happen + if (!stats.type) { + stats.error = new Error(upath.join(path, stats.name) + ' isAnUndefinedType'); + } + */ + } + + function create(path) { + var emitter = new EventEmitter(), + paths = [], + path; + + function next() { + // path could be local if dirHandler were anonymous + //console.log('LEN: '+ paths.length); + if (0 == paths.length) { + emitter.emit('end'); + return; + } + path = paths.pop(); + //console.log("POP: " + path); + fs.readdir(path, dirHandler); + } + + function nodesHandler(nodes, args) { + //console.log('USE: ' + path); + var statses = []; + + var nodeGroups = {}; + fnodeTypesPlural.concat("nodes", "errors").forEach(function (fnodeTypePlural) { + nodeGroups[fnodeTypePlural] = []; + }); + + args.forEach(function (arg, i) { + var file = nodes[i], + err = arg[0], + stats = arg[1]; + + if (err) { + stats = { error: err, name: file }; + emitter.emit('error', err, path, stats); + } + if (stats) { + stats.name = file; + sortFnodesByType(stats, nodeGroups); + emitter.emit('stat', path, stats); + } + }); + emitter.emit('stats', path, statses); + nodeGroups['directories'].forEach(function (stat) { + paths.push(path + '/' + stat.name); + //console.log('PUSH: ' + path + '/' + stat.name); + }); + /* + //console.log('USE: ' + path); + next(); + */ + emitPluralEvents(emitter, path, nodeGroups, next); + } + + function dirHandler(err, nodes) { + //console.log("HANDLE: " + path); + var join = Futures.join(), + i; + + if (err) { + emitter.emit('error', err, path); + } + if (!nodes || 0 == nodes.length) { + //console.log('EMPTY: ' + path); + return next(); + } + // TODO don't duplicate efforts + emitter.emit('nodes', path, nodes); + + for (i = 0; i < nodes.length; i += 1) { + fstat(path + '/' + nodes[i], join.deliverer()); + } + + join.when(function () { + var args = Array.prototype.slice.call(arguments); + nodesHandler(nodes, args); + }); + } + + //paths.push([path]); + paths.push(path); + + + next(); + return emitter; + } + + module.exports = create; +}()); diff --git a/lib/walk-recurse.js b/lib/walk-recurse.js new file mode 100644 index 0000000..be3bd5f --- /dev/null +++ b/lib/walk-recurse.js @@ -0,0 +1,165 @@ +// TODO +// * add types by listener dynamically +// * unroll loops for better readability? +// * should emitted errors wait for `next()`? +(function (undefined) { + var fs = require('fs'), + upath = require('path'), + util = require('util'), + Futures = require('futures'), + events = require('events'), + noop = function () {}, + // "FIFO" isn't easy to convert to camelCame and back reliably + isFnodeTypes = [ + "isFile", "isDirectory", "isBlockDevice", "isCharacterDevice", "isSymbolicLink", "isFIFO", "isSocket" + ], + fnodeTypes = [ + "file", "directory", "blockDevice", "characterDevice", "symbolicLink", "FIFO", "socket" + ], + fnodeTypesPlural = [ + "files", "directories", "blockDevices", "characterDevices", "symbolicLinks", "FIFOs", "sockets" + ]; + + function newVersion() { + throw new Error("New Version. Please see API on github.com/coolaj86/node-walk"); + } + + // Create a new walk instance + function create(path, options, cb) { + if (cb) { + newVersion(); + } + + var emitter = new events.EventEmitter(), + fstat = (options||{}).followLinks ? fs.stat : fs.lstat; + + + // Get the current number of listeners (which may change) + // Emit events to each listener + // Wait for all listeners to `next()` before continueing + // (in theory this may avoid disk thrashing) + function emitSingleEvents(path, stats, next) { + var num = 1 + emitter.listeners(stats.type).length + emitter.listeners("node").length; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + emitter.emit(stats.type, path, stats, nextWhenReady); + emitter.emit("node", path, stats, nextWhenReady); + nextWhenReady(); + } + + + // Since the risk for disk thrashing among anything + // other than files is relatively low, all types are + // emitted at once, but all must complete before advancing + function emitPluralEvents(path, nodes, next) { + var num = 1; + + function nextWhenReady() { + num -= 1; + if (0 === num) { next(); } + } + + fnodeTypesPlural.concat(["nodes", "errors"]).forEach(function (fnodeType) { + if (0 === nodes[fnodeType].length) { return; } + num += emitter.listeners(fnodeType).length; + emitter.emit(fnodeType, path, nodes[fnodeType], nextWhenReady); + }); + nextWhenReady(); + } + + + // Determine each file node's type + // + function sortFnodesByType(path, stats, fnodes, nextFile) { + isFnodeTypes.forEach(function (isType, i) { + if (stats[isType]()) { + if (stats.type) { throw new Error("is_" + type + " and " + isType); } + stats.type = fnodeTypes[i]; + fnodes[fnodeTypesPlural[i]].push(stats); + // TODO throw to break; + } + }); + if (!stats.type) { throw new Error(upath.join(path, stats.name) + ' isAnUndefinedType'); } + emitSingleEvents(path, stats, nextFile); + } + + + // Asynchronously get the stats + // + function getStats(path, files, walkDirs) { + var nodeGroups = {}; + + fnodeTypesPlural.concat("nodes", "errors").forEach(function (fnodeTypePlural) { + nodeGroups[fnodeTypePlural] = []; + }); + + function nextFile() { + var file = files.pop(), dirs = [], fnames = []; + + if (undefined === file) { + emitPluralEvents(path, nodeGroups, function () { + nodeGroups.directories.forEach(function (dir) { + dirs.push(dir.name); + }); + walkDirs(dirs); + }); + return; + } + + fstat(upath.join(path, file), function (err, stats) { + stats = stats || {}; + stats.name = file; + nodeGroups.nodes.push(stats); + if (err) { + stats.error = err; + stats.type = 'error'; + nodeGroups.errors.push(stats); + //emitter.emit('fileError', path, stats, noop); + return nextFile(); + } + sortFnodesByType(path, stats, nodeGroups, nextFile); + }); + } + nextFile(); + } + + function walk(path, next) { + fs.readdir(path, function (err, nodes) { + if (err) { + emitter.emit('directoryError', path, { error: err, name: path }, noop); + return next(); /*TODO*/ throw err; + } + getStats(path, nodes, function (dirs) { + walkDirs(path, dirs, next); + }); + }); + } + + function walkDirs(path, dirs, cb) { + function nextDir() { + var dir = dirs.pop(); + if (undefined === dir) { + delete dirs; + return cb(); + } + walk(upath.join(path, dir), nextDir); + } + nextDir(); + } + + walk(upath.normalize(path), function () { + emitter.emit('end'); + }); + emitter.walk = newVersion; + emitter.whenever = newVersion; + return emitter; + } + module.exports = create; + module.exports.isFnodeTypes = isFnodeTypes; + module.exports.fnodeTypes = fnodeTypes; + module.exports.fnodeTypesPlural = fnodeTypesPlural; +}()); diff --git a/lib/walk.js b/lib/walk.js index be3bd5f..4903c7f 100644 --- a/lib/walk.js +++ b/lib/walk.js @@ -1,165 +1,86 @@ -// TODO -// * add types by listener dynamically -// * unroll loops for better readability? -// * should emitted errors wait for `next()`? -(function (undefined) { +(function () { + "use strict" + + // Array.prototype.forEachAsync(next, item, i, collection) + require('futures/forEachAsync'); + var fs = require('fs'), - upath = require('path'), - util = require('util'), - Futures = require('futures'), - events = require('events'), - noop = function () {}, - // "FIFO" isn't easy to convert to camelCame and back reliably - isFnodeTypes = [ - "isFile", "isDirectory", "isBlockDevice", "isCharacterDevice", "isSymbolicLink", "isFIFO", "isSocket" - ], - fnodeTypes = [ - "file", "directory", "blockDevice", "characterDevice", "symbolicLink", "FIFO", "socket" - ], - fnodeTypesPlural = [ - "files", "directories", "blockDevices", "characterDevices", "symbolicLinks", "FIFOs", "sockets" - ]; + EventEmitter = require('events').EventEmitter, + TypeEmitter = require('./node-type-emitter'); - function newVersion() { - throw new Error("New Version. Please see API on github.com/coolaj86/node-walk"); - } + // 2010-11-25 jorge@jorgechamorro.com + function create(pathname, cb) { + var emitter = new EventEmitter(), + q = [], + queue = [q], + curpath; - // Create a new walk instance - function create(path, options, cb) { - if (cb) { - newVersion(); + function walk() { + fs.readdir(curpath, function(err, files) { + if (err) { + emitter.emit('error', curpath, err); + } + // XXX bug was here. next() was omitted + if (!files || 0 == files.length) { + return next(); + } + var stats = [], + fnodeGroups = TypeEmitter.createNodeGroups(); + + // TODO could allow user to selectively stat + // and don't stat if there are no stat listeners + emitter.emit('names', curpath, files); + files.forEachAsync(function (cont, file) { + emitter.emit('name', curpath, file); + fs.lstat(curpath + '/' + file, function (err, stat) { + if (err) { + emitter.emit('error', curpath, err); + } + if (!stat) { + cont(); + } + stat.name = file; + stats.push(stat); + //emitter.emit('stat', curpath, file, stat); + TypeEmitter.sortFnodesByType(stat, fnodeGroups); + TypeEmitter.emitNodeType(emitter, curpath, stat, cont); + }); + }).then(function () { + var dirs = [] + //emitter.emit('stats', curpath, files, stats); + TypeEmitter.emitNodeTypeGroups(emitter, curpath, fnodeGroups, function () { + fnodeGroups.directories.forEach(function (stat) { + dirs.push(stat.name); + }); + dirs.forEach(fullPath); + queue.push(q = dirs); + next(); + }); + }); + }); } - var emitter = new events.EventEmitter(), - fstat = (options||{}).followLinks ? fs.stat : fs.lstat; - - - // Get the current number of listeners (which may change) - // Emit events to each listener - // Wait for all listeners to `next()` before continueing - // (in theory this may avoid disk thrashing) - function emitSingleEvents(path, stats, next) { - var num = 1 + emitter.listeners(stats.type).length + emitter.listeners("node").length; - - function nextWhenReady() { - num -= 1; - if (0 === num) { next(); } + function next() { + if (q.length) { + curpath = q.pop(); + return walk(); } - - emitter.emit(stats.type, path, stats, nextWhenReady); - emitter.emit("node", path, stats, nextWhenReady); - nextWhenReady(); - } - - - // Since the risk for disk thrashing among anything - // other than files is relatively low, all types are - // emitted at once, but all must complete before advancing - function emitPluralEvents(path, nodes, next) { - var num = 1; - - function nextWhenReady() { - num -= 1; - if (0 === num) { next(); } + if (queue.length -= 1) { + q = queue[queue.length-1]; + return next(); } - - fnodeTypesPlural.concat(["nodes", "errors"]).forEach(function (fnodeType) { - if (0 === nodes[fnodeType].length) { return; } - num += emitter.listeners(fnodeType).length; - emitter.emit(fnodeType, path, nodes[fnodeType], nextWhenReady); - }); - nextWhenReady(); - } - - - // Determine each file node's type - // - function sortFnodesByType(path, stats, fnodes, nextFile) { - isFnodeTypes.forEach(function (isType, i) { - if (stats[isType]()) { - if (stats.type) { throw new Error("is_" + type + " and " + isType); } - stats.type = fnodeTypes[i]; - fnodes[fnodeTypesPlural[i]].push(stats); - // TODO throw to break; - } - }); - if (!stats.type) { throw new Error(upath.join(path, stats.name) + ' isAnUndefinedType'); } - emitSingleEvents(path, stats, nextFile); - } - - - // Asynchronously get the stats - // - function getStats(path, files, walkDirs) { - var nodeGroups = {}; - - fnodeTypesPlural.concat("nodes", "errors").forEach(function (fnodeTypePlural) { - nodeGroups[fnodeTypePlural] = []; - }); - - function nextFile() { - var file = files.pop(), dirs = [], fnames = []; - - if (undefined === file) { - emitPluralEvents(path, nodeGroups, function () { - nodeGroups.directories.forEach(function (dir) { - dirs.push(dir.name); - }); - walkDirs(dirs); - }); - return; - } - - fstat(upath.join(path, file), function (err, stats) { - stats = stats || {}; - stats.name = file; - nodeGroups.nodes.push(stats); - if (err) { - stats.error = err; - stats.type = 'error'; - nodeGroups.errors.push(stats); - //emitter.emit('fileError', path, stats, noop); - return nextFile(); - } - sortFnodesByType(path, stats, nodeGroups, nextFile); - }); - } - nextFile(); - } - - function walk(path, next) { - fs.readdir(path, function (err, nodes) { - if (err) { - emitter.emit('directoryError', path, { error: err, name: path }, noop); - return next(); /*TODO*/ throw err; - } - getStats(path, nodes, function (dirs) { - walkDirs(path, dirs, next); - }); - }); - } - - function walkDirs(path, dirs, cb) { - function nextDir() { - var dir = dirs.pop(); - if (undefined === dir) { - delete dirs; - return cb(); - } - walk(upath.join(path, dir), nextDir); - } - nextDir(); - } - - walk(upath.normalize(path), function () { emitter.emit('end'); - }); - emitter.walk = newVersion; - emitter.whenever = newVersion; + } + + function fullPath(v,i,o) { + o[i]= [curpath, '/', v].join(''); + } + + curpath = pathname; + walk(); + return emitter; } + module.exports = create; - module.exports.isFnodeTypes = isFnodeTypes; - module.exports.fnodeTypes = fnodeTypes; - module.exports.fnodeTypesPlural = fnodeTypesPlural; }()); diff --git a/profile/walk-jqueue-2-test.js b/profile/walk-jqueue-2-test.js new file mode 100755 index 0000000..8fabaa8 --- /dev/null +++ b/profile/walk-jqueue-2-test.js @@ -0,0 +1,42 @@ +#!/usr/bin/env node +(function () { + "use strict"; + + var walk = require('../lib/walk-jqueue-2'), + count = 0; + + function sort(a,b) { + a= a.toLowerCase(); + b= b.toLowerCase(); + if (a > b) return -1; + if (a < b) return 1; + else return 0; + } + + process.argv.forEach(function(val, index, array) { + if (index > 1) { + emitter = walk(val); + emitter.on('name', function (path, file, stat) { + count += 1; + console.log( ["[", count, "] ", path, '/', file].join('') ) + }); + emitter.on('names', function (path, files, stats) { + files.sort(sort); + //console.log('sort: ' + files.join(' ; ')); + }); + emitter.on('error', function () { + // ignore + }); + emitter.on('stat', function (path, file, stat) { + //console.log('stat: ' + file); + }); + emitter.on('stats', function (path, files, stats) { + //console.log('stats: ' + files.join(' ; ')); + }); + emitter.on('end', function () { + console.log("The eagle has landed."); + }); + } + }); + +}()); diff --git a/profile/walk-jqueue-3-test.js b/profile/walk-jqueue-3-test.js new file mode 100755 index 0000000..965dd05 --- /dev/null +++ b/profile/walk-jqueue-3-test.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node +(function () { + "use strict"; + + var walk = require('../lib/walk-jqueue-3'), + count = 0; + + function sort(a,b) { + a= a.toLowerCase(); + b= b.toLowerCase(); + if (a > b) return -1; + if (a < b) return 1; + else return 0; + } + + process.argv.forEach(function(startpath, index) { + if (index > 1) { + emitter = walk(startpath); + + // Non-`stat`ed Nodes + /* + emitter.on('name', function (path, file, stat) { + count += 1; + //console.log( ["[", count, "] ", path, '/', file].join('') ) + console.log( [path, '/', file].join('') ) + }); + emitter.on('names', function (path, files, stats) { + files.sort(sort); + //console.log('sort: ' + files.join(' ; ')); + }); + */ + + + // Single `stat`ed Nodes + emitter.on('error', function (path, err, next) { + // ignore + }); + emitter.on('directoryError', function (path, stats, next) { + next(); + }); + /* + emitter.on('node', function (path, stat, next) { + count += 1; + console.log( [path, '/', stat.name].join('') ) + //console.log( ["[", count, "] ", path, '/', stat.name].join('') ) + next(); + }); + */ + emitter.on('file', function (path, stat, next) { + count += 1; + console.log( [path, '/', stat.name].join('') ) + //console.log( ["[", count, "] ", path, '/', stat.name].join('') ) + next(); + }); + emitter.on('directory', function (path, stat, next) { + count += 1; + console.log( [path, '/', stat.name].join('') ) + next(); + }); + emitter.on('symbolicLink', function (path, stat, next) { + count += 1; + console.log( [path, '/', stat.name].join('') ) + next(); + }); + /* + */ + /* + emitter.on('blockDevice', function (path, stat, next) { + next(); + }); + emitter.on('characterDevice', function (path, stat, next) { + next(); + }); + emitter.on('FIFO', function (path, stat, next) { + next(); + }); + emitter.on('socket', function (path, stat, next) { + next(); + }); + */ + + // Grouped `stat`ed Nodes + emitter.on('errors', function (path, stats, next) { + next(); + }); + /* + emitter.on('nodes', function (path, stats, next) { + next(); + }); + */ + emitter.on('files', function (path, stats, next) { + next(); + }); + emitter.on('directories', function (path, stats, next) { + //delete stats[1]; + next(); + }); + emitter.on('symbolicLinks', function (path, stats, next) { + next(); + }); + /* + emitter.on('blockDevices', function (path, stats, next) { + next(); + }); + emitter.on('characterDevices', function (path, stats, next) { + next(); + }); + emitter.on('FIFOs', function (path, stats, next) { + next(); + }); + emitter.on('sockets', function (path, stats, next) { + next(); + }); + */ + + // The end of all things + emitter.on('end', function () { + console.log("The eagle has landed."); + }); + } + }); + +}()); diff --git a/profile/walkq-test.js b/profile/walkq-test.js new file mode 100755 index 0000000..2fbc91c --- /dev/null +++ b/profile/walkq-test.js @@ -0,0 +1,33 @@ +#!/usr/bin/env node +(function () { + var walk = require('../lib/walk-queue'), + emitter = walk(process.argv[2] || '.'), + _ = require('underscore'), + count = 0; + + emitter.on('error', function (err, path, files) { + console.log(err); + }); + emitter.on('nodes', function (path, files, next) { + //next(); + var filenames = _.map(files, function (file) { + return path + '/' + file; + }) + filenames.forEach(function (name) { + count += 1; + console.log('[' + count + '] ' + name) + }); + //filenames.forEach(console.log); + //console.log(_.pluck(files, 'name')); + }); + emitter.on('directories', function (path, files, next) { + next(); + }); + emitter.on('directory', function (path, stat, next) { + //console.log(stat.name); + next(); + }); + emitter.on('end', function () { + console.log("The eagle has landed"); + }); +}());