[debhelper-devel] [debhelper] 03/03: dh_install: Optimize some calls with xargs

Niels Thykier nthykier at moszumanska.debian.org
Mon Jun 26 14:44:31 UTC 2017


This is an automated email from the git hooks/post-receive script.

nthykier pushed a commit to branch master
in repository debhelper.

commit e15f79892cb999d95db88d160d5c5d0778037bf2
Author: Niels Thykier <niels at thykier.net>
Date:   Mon Jun 26 14:30:37 2017 +0000

    dh_install: Optimize some calls with xargs
    
    The following are common pattern seen in install files:
    
      """
      some/path/*
    
      some/path/*.foo*
      """
    
    These patterns all cause dh_install to issue one "cp" per file matched
    in "some/path" (the first one matching all files in the directory).
    For patterns with many matches, this triggers a considerable overhead
    by the number of fork+exec calls.
    
    This patch makes dh_install bulk "cp" calls provided that:
    
     * The matched files all end in the same destination directory.
       (which might not be the case for e.g. "foo/*/bar" )
    
     * There are no "--exclude" in play (as that triggers a vastly more
       complicated case).
    
    Signed-off-by: Niels Thykier <niels at thykier.net>
---
 debian/changelog |  3 +++
 dh_install       | 45 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 9c192de..329e4f9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,9 @@ debhelper (10.5.1) UNRELEASED; urgency=medium
   * dh_installman: When re-encoding manpages, use the actual manpages as
     tasks to split rather than packages.  This provides a much better
     performance if the manpages are unevenly split between the packages.
+  * dh_install: Optimize some patterns into bulked "cp" calls.  This
+    optimization is only applicable in some cases (notably, it is always
+    disabled by --exclude).
 
  -- Niels Thykier <niels at thykier.net>  Sun, 25 Jun 2017 18:02:30 +0000
 
diff --git a/dh_install b/dh_install
index 9b0eb0a..62ed9c8 100755
--- a/dh_install
+++ b/dh_install
@@ -178,13 +178,12 @@ foreach my $package (getpackages()) {
 	@install = map { [$_] } map { @$_ } @install if $dh{AUTODEST};
 
 	foreach my $set (@install) {
-		my $dest;
-		
+		my ($dest, @filelist);
+
 		if (@$set > 1) {
 			$dest=pop @$set;
 		}
 
-		my @filelist;
 		foreach my $glob (@$set) {
 			my @found = glob "$srcdir/$glob";
 			my $matched = 0;
@@ -226,15 +225,37 @@ foreach my $package (getpackages()) {
 		# ... because then we can short-curcit here.
 		next if $skip_install or $missing_files;
 
+		if (not $exclude) {
+			# Without $exclude and if everything is installed in the same directory, it is trivial
+			# to bulk them cp calls via xargs.
+			if (not $dest and @filelist > 1) {
+				my $same = 1;
+				my $common_dest;
+				for my $src (@filelist) {
+					my $target_dest = compute_dest($src);
+					if (not defined($common_dest)) {
+						$common_dest = $target_dest;
+					} elsif ($common_dest ne $target_dest) {
+						$same = 0;
+						last;
+					}
+				}
+				$dest = $common_dest if ($same and $common_dest);
+			}
+			if ($dest and @filelist > 1) {
+				# Make sure the destination directory exists.
+				install_dir("$tmp/$dest");
+				xargs(\@filelist, "cp", '--reflink=auto', "-a", XARGS_INSERT_PARAMS_HERE, "$tmp/$dest/");
+				next;
+			}
+		}
+
 		foreach my $src (@filelist) {
 
 			my $target_dest = $dest;
 			if (! defined $target_dest) {
 				# Guess at destination directory.
-				$target_dest = $src;
-				$target_dest =~ s/^(.*\/)?\Q$srcdir\E\///;
-				$target_dest =~ s/^(.*\/)?debian\/tmp\///;
-				$target_dest = dirname("/".$target_dest);
+				$target_dest = compute_dest($src);
 			}
 
 			# Make sure the destination directory exists.
@@ -279,6 +300,16 @@ if ($dh{LIST_MISSING} || $dh{FAIL_MISSING}) {
 	doit("dh_missing", @options);
 }
 
+sub compute_dest {
+	my ($dest) = @_;
+
+	$dest =~ s/^(.*\/)?\Q$srcdir\E\///;
+	$dest =~ s/^(.*\/)?debian\/tmp\///;
+	$dest = dirname("/".$dest);
+
+	return $dest;
+}
+
 =head1 LIMITATIONS
 
 B<dh_install> cannot rename files or directories, it can only install them

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debhelper/debhelper.git




More information about the debhelper-devel mailing list