summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--urpm/args.pm1
-rw-r--r--urpm/xml_info.pm12
-rwxr-xr-xurpmf46
4 files changed, 53 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 3c010fba..03b525e6 100644
--- a/NEWS
+++ b/NEWS
@@ -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";
diff --git a/urpmf b/urpmf
index 68f5581e..edadcedd 100755
--- a/urpmf
+++ b/urpmf
@@ -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,
+ );
+ }
}
}