App-FileCleanerByDiskUage
view release on metacpan or search on metacpan
lib/App/FileCleanerByDiskUage.pm view on Meta::CPAN
my $ignore_re = defined( $opts{ignore} ) ? qr/$opts{ignore}/ : undef;
# Recursively find regular files under the requested paths, statting each
# one inline during the traversal. Doing the stat here means a single stat
# syscall per file (the traversal and the mtime lookup share it) and avoids
# building a separate array of path strings alongside the file info.
my @files_info;
File::Find::find(
sub {
# $_ is the basename (we are chdir'd into the containing dir),
# $File::Find::name is the full path. stat($_) populates the "_"
# handle so the -f test below reuses it rather than statting again.
my @stat = stat($_);
return unless @stat; # skip on stat failure (races, broken symlinks)
return unless -f _; # regular files only, matching the old ->file rule
return if defined($ignore_re) && $_ =~ $ignore_re; # ignore by basename
# blocks ($stat[12], 512-byte units) is the space actually freed by
# unlinking, used by the removal loop to estimate disk usage between
# df() calls. apparent size would over-count sparse/small files.
push( @files_info, { name => $File::Find::name, mtime => $stat[9], blocks => $stat[12] } );
},
@paths
);
t/removal_loop.t view on Meta::CPAN
}
# make a mock df over $dir whose capacity is fixed at $capacity bytes. Usage is
# the summed allocated size of the files still present, so per == percent of the
# original files remaining. Counts its own calls via $$calls_ref.
sub mock_df_for {
my ( $dir, $capacity, $calls_ref ) = @_;
return sub {
$$calls_ref++;
my $used = 0;
File::Find::find( sub { $used += ( ( stat($_) )[12] || 0 ) * 512 if -f _ }, $dir );
my $bavail = $capacity - $used;
$bavail = 0 if $bavail < 0;
return {
per => int( 100 * $used / $capacity + 0.5 ),
used => $used,
bavail => $bavail,
};
};
}
# capacity = allocated size of all files, so a full directory reads as 100%.
sub capacity_of {
my ($dir) = @_;
my $cap = 0;
File::Find::find( sub { $cap += ( ( stat($_) )[12] || 0 ) * 512 if -f _ }, $dir );
return $cap;
}
# -------------------------------------------------------------------------
# stops right below the threshold, and does so with far fewer df() calls than
# files removed
# -------------------------------------------------------------------------
{
my ( $dir, $files ) = build(100);
my $cap = capacity_of($dir);
( run in 0.878 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )