diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | urpm/args.pm | 1 | ||||
-rw-r--r-- | urpm/xml_info.pm | 12 | ||||
-rwxr-xr-x | urpmf | 46 |
4 files changed, 53 insertions, 9 deletions
@@ -2,6 +2,9 @@ o deprecate --curl and --wget in favor of --downloader curl and --downloader --wget o fix displaying error message when failing to lock (regression in 5.1) +- urpmf: + o add special code for --files simple case, it makes urpmf 3x faster for + this often used case - urpmq: o add --provides diff --git a/urpm/args.pm b/urpm/args.pm index 42422de8..14cfe887 100644 --- a/urpm/args.pm +++ b/urpm/args.pm @@ -213,6 +213,7 @@ my %options_spec = ( if ($::literal) { $p = quotemeta $p; } else { + push @::raw_non_literals, $p; # quote "+" chars for packages with + in their names $p =~ s/\+/\\+/g; } diff --git a/urpm/xml_info.pm b/urpm/xml_info.pm index 24d1d101..bd3bed4e 100644 --- a/urpm/xml_info.pm +++ b/urpm/xml_info.pm @@ -19,13 +19,19 @@ sub do_something_with_nodes { } -################################################################################ -sub _open_xml_reader { +sub open_lzma { my ($xml_info_file) = @_; $xml_info_file =~ s/'/\'/g; open(my $F, "lzma -dc '$xml_info_file' |"); - my $reader = new XML::LibXML::Reader(IO => $F) or die "cannot read $xml_info_file\n"; + $F; +} + +################################################################################ +sub _open_xml_reader { + my ($xml_info_file) = @_; + + my $reader = new XML::LibXML::Reader(IO => open_lzma($xml_info_file)) or die "cannot read $xml_info_file\n"; $reader->read; $reader->name eq 'media_info' or die "global <media_info> tag not found\n"; @@ -168,6 +168,19 @@ if ($full) { $qf =~ s/%name\b/%fullname/ } $urpm->{info} = sub { print STDERR "$_[0]\n" }; $urpm->{log} = sub { print STDERR "$_[0]\n" } if $options{verbose} > 0; +my $only_simple_files_search; +if ($qf eq '%name:%files') { + if ($::literal) { + $only_simple_files_search = $expr !~ /:/; + } elsif (@::raw_non_literals == 1) { + my $s = $::raw_non_literals[0]; + $s =~ s!/.*!!; # things after "/" won't match pkg name for sure + $only_simple_files_search = $s !~ m![:.*?\[\]]!; + } + $only_simple_files_search and $urpm->{log}("using fast algorithm"); +} + + my $multitag = ''; my %multitags = map { $_ => 1 } qw(conffiles conflicts files obsoletes provides requires suggests); my %usedtags; @@ -223,7 +236,7 @@ my $callback = join("\n", '0;'), "}"); -$urpm->{debug}("qf:[$qf]\ncallback:\n$callback") if $urpm->{debug}; +$urpm->{debug}("qf:[$qf]\ncallback:\n$callback") if $urpm->{debug} && !$only_simple_files_search; our $medium; $callback = eval $callback; if ($@) { @@ -304,10 +317,31 @@ if ($needed_media_info{hdlist}) { $callback->($urpm, urpm::xml_info_pkg->new($node, undef)); }; $urpm->{log}("getting information from $xml_info_file"); - urpm::xml_info::do_something_with_nodes( - $xml_info, - $xml_info_file, - $cooked_callback, - ); + if ($only_simple_files_search) { + # special version for speed (3x faster), hopefully fully compatible + my $code = sprintf(<<'EOF', $expr); + my $F = urpm::xml_info::open_lzma($xml_info_file); + my $fn; + local $_; + while (<$F>) { + if (m!^<!) { + ($fn) = /fn="(.*)"/; + } elsif (%s) { + $fn or $urpm->{fatal}("fast algorithm is broken, please report a bug"); + my $pkg = urpm::xml_info_pkg->new({ fn => $fn }); + print $pkg->name, ':', $_; + } + } +EOF + $urpm->{debug} and $urpm->{debug}($code); + eval $code; + $@ and $urpm->{fatal}(1, "$@"); + } else { + urpm::xml_info::do_something_with_nodes( + $xml_info, + $xml_info_file, + $cooked_callback, + ); + } } } |