WARNING: the mechanism of taking timestamps of directories in order to find out if the content has changed doesn't work reliably across all kinds of filesystems
# File lib/rgen/util/cached_glob.rb, line 10 def initialize(dir_glob, file_glob) @dir_glob = dir_glob @file_glob = file_glob @root_dirs = [] @dirs = {} @files = {} @timestamps = {} end
returns all files contained in directories matched by dir_glob
which match file_glob
. file_glob
must be relative
to dir_glob
. dir_glob “ a” with file_glob “** .txt” is
basically equivalent with Dir.glob(“ a /*.txt”) the idea is that the
file glob will only be re-eavluated when the content of one of the
directories matched by dir_glob has changed. this will only be faster than
a normal Dir.glob if the number of dirs matched by dir_glob is relatively
large and changes in files affect only a few of them at a time.
# File lib/rgen/util/cached_glob.rb, line 26 def glob root_dirs = Dir.glob(@dir_glob) (@root_dirs - root_dirs).each do |d| remove_root_dir(d) end (@root_dirs & root_dirs).each do |d| update_root_dir(d) if dir_changed?(d) end (root_dirs - @root_dirs).each do |d| update_root_dir(d) end @root_dirs = root_dirs @root_dirs.sort.collect{|d| @files[d]}.flatten end
# File lib/rgen/util/cached_glob.rb, line 43 def dir_changed?(dir) @dirs[dir].any?{|d| File.mtime(d) != @timestamps[dir][d]} end
# File lib/rgen/util/cached_glob.rb, line 56 def remove_root_dir(dir) @dirs.delete(dir) @files.delete(dir) @timestamps.delete(dir) end
# File lib/rgen/util/cached_glob.rb, line 47 def update_root_dir(dir) @dirs[dir] = Dir.glob(dir+"/**/") @files[dir] = Dir.glob(dir+"/"+@file_glob) @timestamps[dir] = {} @dirs[dir].each do |d| @timestamps[dir][d] = File.mtime(d) end end