Skip to content

Commit

Permalink
introduced parallel find mode
Browse files Browse the repository at this point in the history
  • Loading branch information
dvv committed Dec 18, 2011
1 parent 40e0296 commit f2a1c3f
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 30 deletions.
19 changes: 1 addition & 18 deletions README.md
Expand Up @@ -31,21 +31,4 @@ Usage
License
-------

Copyright (c) 2011 Vladimir Dronnikov <dronnikov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Check [here](license.txt).
44 changes: 32 additions & 12 deletions init.lua
Expand Up @@ -46,6 +46,7 @@ local function find(path, options, callback)
options = options or {}
match_fn = options.match_fn or function(path, stat, depth, cb) cb() end
dir_fn = options.dir_fn or function(path, stat, depth, cb) cb() end
serial = options.serial or false

-- cache highly used functions
local normalize = Path.normalize
Expand Down Expand Up @@ -82,18 +83,34 @@ local function find(path, options, callback)
readdir(path, function(err, files)
if err then cb(err) ; return end
-- recursively iterate thru files
-- cache `files` length
local len = #files
local i = 1
local function _w()
if i > len then
-- set starting index
-- N.B. for serial execution iterations start by calling
-- `collect`, hence it's called one time more,
-- hence lesser starting index
local collected = serial and 0 or 1
local function collect()
collected = collected + 1
if collected > len then
-- notify of directory is processed
dir_fn(path, st, depth, cb)
else
walk(join(path, files[i]), depth + 1, _w)
i = i + 1
-- if we iterate sequentially, start new iteration
elseif serial then
walk(join(path, files[collected]), depth + 1, collect)
end
end
-- parallel execution and no files? fire callback
-- sequential execution? start the first iteration
if len == 0 or serial then
collect()
-- parallel execution? spawn concurrent walkers
else
local file
for _, file in ipairs(files) do
walk(join(path, file), depth + 1, collect)
end
end
_w()
end)
end)
end)
Expand Down Expand Up @@ -211,14 +228,17 @@ local function cp_a(src, dst, callback)
end

--
-- mimick ln -s
-- mimick ln -sf
--
local function ln_s(target, path, callback)
local function ln_sf(target, path, callback)
path = Path.resolve(process.cwd(), path)
Fs.mkdir_p(Path.dirname(path), '0755', function(err)
if err then callback(err) ; return end
-- FIXME: should we mimick -f -- rm_rf basename(path) before this?
Fs.symlink(target, path, 'r', callback)
-- N.B. we mimick -f -- rm_rf(path) before symlinking
rm_fr(path, function(err)
if err then callback(err) ; return end
Fs.symlink(target, path, 'r', callback)
end)
end)
end

Expand All @@ -228,5 +248,5 @@ return setmetatable({
find = find,
rm_rf = rm_rf,
cp_a = cp_a,
ln_s = ln_s,
ln_sf = ln_sf,
}, { __index = Fs })
18 changes: 18 additions & 0 deletions license.txt
@@ -0,0 +1,18 @@
Copyright (c) 2011 Vladimir Dronnikov <dronnikov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
95 changes: 95 additions & 0 deletions test/test
@@ -0,0 +1,95 @@
#!/usr/bin/env luvit

local Fs = require('../')
local Path = require('path')
local Process = require('process')

local function run(cmd, callback)
local child = Process.spawn('/bin/sh', {'-c', cmd}, {})
local stdout = ''
child.stdout:on('data', function(data)
stdout = stdout .. data
end)
child.stderr:on('data', function(data)
stderr = stderr .. data
end)
child:on('exit', function (exit_status, term_signal)
if callback then callback(exit_status ~= 0, stdout, stderr) end
end)
return child
end

--
-- find all .js files with system `find` and `Fs.find`
--

local jscount, total = 0, 0;
Fs.find(process.env.HOME, {
--follow = true,
--serial = true,
match_fn = function (path, stat, depth, cb)
-- print(path)
total = total + 1
if path:sub(-3) == '.js' then
jscount = jscount + 1
end
cb()
end
}, function (err)
if err then
print('ERR', err)
end
print('find()', jscount, 'of', total)
run('find ' .. process.env.HOME .. ' | wc -l', function (err, findtotal)
findtotal = tonumber((findtotal or '0'))
run('find ' .. process.env.HOME .. ' -name \\*.js | wc -l', function (err, findjscount)
findjscount = tonumber((findjscount or '0'))
print('find ~ -name \\*.js | wc -l', findjscount, 'of', findtotal)
assert(jscount == findjscount)
assert(total == findtotal)
end)
end)
end)

--[[
--
-- mkdir_p ./HZ/foo./bar
--

Fs.mkdir_p('HZ/foo./bar', '0771', function (err)
if err then
print('mkdir_p ERROR', err)
end
assert(not err)
assert(Path.exists_sync('HZ'))
Fs.rm_rf('HZ', function (err)
if err then
print('rm_fr ERROR', err)
end
assert(not err)
assert(not Path.exists_sync('HZ/foo./bar'))
assert(not Path.exists_sync('HZ/foo.'))
assert(not Path.exists_sync('HZ'))
end)
end)

//
// ln_sf './ZH/foo./b ar'
//

Fs.ln_sf('/etc/passwd', 'ZH/foo./b ar', function (err) {
if (err) {
console.log('ln_sf ERROR', err)
}
Assert.ok(!err)
Assert.ok(Path.existsSync('ZH/foo.'))
Fs.rm_rf('ZH', function (err) {
if (err) {
console.log('rm_fr ERROR', err)
}
Assert.ok(!err)
Assert.ok(!Path.existsSync('HZ'))
})
})

]]--

0 comments on commit f2a1c3f

Please sign in to comment.