module FastFind
A Find workalike optimized for multithreaded operation on supporting Rubies
Constants
- FS_ENCODING
- VERSION
Attributes
default_executor[RW]
Public Class Methods
find(*paths, ignore_error: true, executor: default_executor, &block)
click to toggle source
# File lib/fast_find.rb, line 18 def find(*paths, ignore_error: true, executor: default_executor, &block) block or return enum_for(__method__, *paths, ignore_error: ignore_error, executor: executor) results = SizedQueue.new(1024) pending = Set.new paths.map!(&:dup).each do |path| path = path.to_path if path.respond_to? :to_path results << [path, safe_stat(path)] end results << %i[initial finished] pending << path_signature(:initial) while (result = results.deq) path, stat = result if stat == :finished break if pending.delete(path_signature(path)).empty? next end catch(:prune) do yield_entry(result, block) if path.is_a? String if stat.is_a?(File::Stat) && stat.directory? && pending.add?(path_signature(path)) executor.post(path, results) do |path_, results_| walk(path_, results_) end end end raise stat if stat.is_a?(Exception) && !ignore_error end ensure results.close if results end
prune()
click to toggle source
# File lib/fast_find.rb, line 14 def prune throw :prune end
Private Class Methods
error(e)
click to toggle source
# File lib/fast_find.rb, line 84 def error(e) [:exception, e] end
finish(path)
click to toggle source
# File lib/fast_find.rb, line 80 def finish(path) [path, :finished] end
path_signature(path)
click to toggle source
# File lib/fast_find.rb, line 88 def path_signature(path) [path, path.encoding] end
safe_stat(path)
click to toggle source
# File lib/fast_find.rb, line 100 def safe_stat(path) File.lstat(path) rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG => e e end
stat(entry)
click to toggle source
# File lib/fast_find.rb, line 76 def stat(entry) [entry, safe_stat(entry)] end
walk(path, results)
click to toggle source
# File lib/fast_find.rb, line 60 def walk(path, results) enc = path.encoding == Encoding::US_ASCII ? FS_ENCODING : path.encoding # This benchmarks as about 10% faster than Dirs.foreach Dir.entries(path, encoding: enc).each do |entry| next if (entry == '.') || (entry == '..') results << stat(File.join(path, entry)) end rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG => e results << error(e) ensure results << finish(path) end
yield_entry(entry, block)
click to toggle source
# File lib/fast_find.rb, line 92 def yield_entry(entry, block) if block.arity == 2 block.call(entry[0].dup, entry[1]) else block.call entry[0].dup end end