OpenPKG CVS Repository
  http://cvs.openpkg.org/
  ____________________________________________________________________________

  Server: cvs.openpkg.org                  Name:   Ralf S. Engelschall
  Root:   /v/openpkg/cvs                   Email:  [EMAIL PROTECTED]
  Module: openpkg-tools                    Date:   20-Jul-2006 09:46:44
  Branch: HEAD                             Handle: 2006072008464100

  Modified files:
    openpkg-tools/cmd       build.pl

  Log:
    "openpkg build" run-time BOOOOOOOOSTING by reducing the run-time by
    95%(!!). This achieved by performing a larger "all-by-one" query for
    "openpkg rpm -qa --provides" and "openpkg rpm -qa -i" and caching the
    results instead of running the two commands individually for each(!)
    installed package. On rm0.openpkg.net:/openpkg-dev with 295 installed
    packages, a "openpkg build -Ua" call now takes just about 5s(!) instead
    of 81s.

  Summary:
    Revision    Changes     Path
    1.31        +57 -13     openpkg-tools/cmd/build.pl
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openpkg-tools/cmd/build.pl
  ============================================================================
  $ cvs diff -u -r1.30 -r1.31 build.pl
  --- openpkg-tools/cmd/build.pl        19 Jul 2006 18:12:57 -0000      1.30
  +++ openpkg-tools/cmd/build.pl        20 Jul 2006 07:46:41 -0000      1.31
  @@ -38,8 +38,6 @@
       $opt_L $opt_W $opt_K $opt_e $opt_b $opt_B $opt_g
   };
   
  -$| = 1; # autoflush STDOUT
  -
   #   global context variables
   my $prg = "openpkg build";
   my %env = ('' => {});
  @@ -91,7 +89,7 @@
           " -q                ignore all reverse dependencies\n" .
           " -s                generate status map instead of shell script\n" .
           " -S                generate status map instead of shell script 
(including new)\n" .
  -        " -X                ignore installed Perl XML parser module and use 
internal one\n" .
  +        " -X                use external XML/RDF parser instead of internal 
one\n" .
           " -M                generate short dependency map instead of shell 
script\n" .
           " -L                generate list of packages in repository 
depending on target\n" .
           " -W                include dependencies as if all build options are 
enabled\n" .
  @@ -829,7 +827,7 @@
   #   fetch XML/RDF index from file or URL
   #   (recursively fetches sub-indexes, too)
   sub get_index ($$$$$) {
  -    my ($url, $fn, $noxml, $pfmatch, $installed) = @_;
  +    my ($url, $fn, $xml, $pfmatch, $installed) = @_;
       my (%map, $include);
       my ($fetch, $bzip2, $path);
       my ($parser);
  @@ -858,14 +856,14 @@
           die "openpkg:build:FATAL: cannot open '$fetch' ($!)\n";
   
       #   if XML parser can be used, try to lazy-load it
  -    if (not $noxml) {
  +    if ($xml) {
           eval { require XML::Simple; };
  -        $noxml = 1 if $@;
  +        $xml = 0 if ($@);
       }
   
       #   determine and run XML parser
       #   (returns contained index includes)
  -    $parser = ($noxml ? \&simple_text_parser : \&xml_parser);
  +    $parser = ($xml ? \&xml_parser : \&simple_text_parser);
       $include = $parser->(\*RFH, $url, \%map, $pfmatch, $installed);
   
       #   close index
  @@ -878,7 +876,7 @@
       foreach (@$include) {
           my ($submap);
           my ($suburl, $subfn) = relurl($url, $fn, $_);
  -        $submap = get_index($suburl, $subfn, $noxml, $pfmatch, $installed); 
# RECURSION
  +        $submap = get_index($suburl, $subfn, $xml, $pfmatch, $installed); # 
RECURSION
           while (my ($name, $vmap) = each(%$submap)) {
               while (my ($vs, $recs) = each(%$vmap)) {
                   push(@{$map{$name}->{$vs}}, @$recs);
  @@ -1378,6 +1376,7 @@
   }
   
   #   pull in OPTIONS for a package or an RPM file
  +my $get_with_cache = {};
   sub get_with ($;$) {
       my ($t, $fn) = @_;
       my (@l, %with);
  @@ -1389,14 +1388,47 @@
           if (defined($fn)) {
               @l = run($config->{"rpm"} . " -q --provides -p $fn");
           } else {
  -            @l = run($config->{"rpm"} . " -q --provides $t->{name}");
  +            if (not exists($get_with_cache->{-provides})) {
  +                #   pre-cache the "provides" query for all(!) packages at 
once for speedup
  +                my @c = run($config->{"rpm"} . " -q -a --qf " .
  +                    '\'[%{NAME} %{PROVIDENAME} 
%|PROVIDEFLAGS?{%{PROVIDEFLAGS:depflags} %{PROVIDEVERSION}}:{}|\n]\'');
  +                $get_with_cache->{-provides} = {};
  +                foreach my $c (@c) {
  +                    if (m/^(\S+)\s+(.+)$/s) {
  +                        $get_with_cache->{-provides}->{$1} = [] if (not 
exists($get_with_cache->{-provides}->{$1}));
  +                        push(@{$get_with_cache->{-provides}->{$1}}, $2);
  +                    }
  +                }
  +            }
  +            @l = $get_with_cache->{-provides}->{$t->{name}};
  +            if (not @l) {
  +                #   (should not happen in practice, but anyway)
  +                @l = run($config->{"rpm"} . " -q --provides $t->{name}");
  +                $get_with_cache->{-provides}->{$t->{name}} = [ @l ];
  +            }
           }
           $opt = parse_provideslist([EMAIL PROTECTED]);
           if (scalar(keys(%$opt)) == 0) {
               if (defined($fn)) {
                   @l = run($config->{"rpm"} . " -qi -p $fn");
               } else {
  -                @l = run($config->{"rpm"} . " -qi $t->{name}");
  +                if (not exists($get_with_cache->{-infos})) {
  +                    #   pre-cache the "infos" query for all(!) packages at 
once for speedup
  +                    my @c = run($config->{"rpm"} . " -qi -a");
  +                    my $p = "";
  +                    $get_with_cache->{-infos} = {};
  +                    foreach my $c (@c) {
  +                        $p = $1 if ($c =~ m/^Name:\s+(\S+)/s);
  +                        $get_with_cache->{-infos}->{$p} = [] if (not 
exists($get_with_cache->{-infos}->{$p}));
  +                        push(@{$get_with_cache->{-infos}->{$p}}, $c);
  +                    }
  +                }
  +                @l = $get_with_cache->{-infos}->{$t->{name}};
  +                if (not @l) {
  +                    #   (should not happen in practice, but anyway)
  +                    @l = run($config->{"rpm"} . " -qi $t->{name}");
  +                    $get_with_cache->{-infos}->{$t->{name}} = [ @l ];
  +                }
               }
               $opt = parse_options([EMAIL PROTECTED]);
           }
  @@ -2265,7 +2297,19 @@
   }
   sub priv  ($) { cmd($opt_P, $_[0]); }
   sub npriv ($) { cmd($opt_N, $_[0]); }
  -sub run   ($) { my ($c) = cmd($opt_N, $_[0]); `$c` }
  +
  +#   execute a command
  +my $run_cache = {};
  +sub run ($) {
  +    my $cmd = cmd($opt_N, $_[0]);
  +    my $out = $run_cache->{$cmd};
  +    if (not defined($out)) {
  +        my @out = `$cmd`;
  +        $out = [ @out ];
  +        $run_cache->{$cmd} = $out;
  +    }
  +    return (wantarray ? @{$out} : join(//, @{$out}));
  +}
   
   #   print dependency list
   sub print_deps ($) {
  @@ -2727,8 +2771,8 @@
   
   =item B<-X>
   
  -Ignore an installed Perl XML parser module and use the internal
  -simple XML/RDF parser instead.
  +Use the slower but more robust external Perl XML parser module
  +XML::Simple instead of the simple internal XML/RDF parser.
   
   =item B<-K>
   
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     [email protected]

Reply via email to