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 1.240 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )