Sfoglia il codice sorgente

Dpkg::Shlibs::SymbolFile: cache the minimum version for a particular soname

Afer profiling, I discovered that dpkg-shlibdeps spent a large part
of his time in the get_smallest_version() version. This patch improves
the performance by caching the resulting value.
Jiri Palecek 17 anni fa
parent
commit
75cd1fb8b0
2 ha cambiato i file con 16 aggiunte e 3 eliminazioni
  1. 3 0
      debian/changelog
  2. 13 3
      scripts/Dpkg/Shlibs/SymbolFile.pm

+ 3 - 0
debian/changelog

@@ -80,6 +80,9 @@ dpkg (1.15.4) UNRELEASED; urgency=low
     Closes: #531307
     Closes: #531307
   * Split overly long Binary: field values over multiple lines. This is
   * Split overly long Binary: field values over multiple lines. This is
     allowed since policy 3.8.3. Closes: #494714
     allowed since policy 3.8.3. Closes: #494714
+  * Improve performance of dpkg-shlibdeps by caching minimal version
+    associated to each library in Dpkg::Shlib::SymbolFile. Thanks to
+    Jiří Paleček <jpalecek@web.de> for the patch.
 
 
   [ Modestas Vainius ]
   [ Modestas Vainius ]
   * Provide a meaningful label for dpkg-gensymbols diff.
   * Provide a meaningful label for dpkg-gensymbols diff.

+ 13 - 3
scripts/Dpkg/Shlibs/SymbolFile.pm

@@ -113,6 +113,8 @@ sub add_symbol {
 	$object->{wildcards}{$ver} = $symbol;
 	$object->{wildcards}{$ver} = $symbol;
 	return 'wildcards';
 	return 'wildcards';
     } else {
     } else {
+	# invalidate the minimum version cache
+        $object->{minver_cache} = [];
 	$object->{syms}{$symbol->get_symbolname()} = $symbol;
 	$object->{syms}{$symbol->get_symbolname()} = $symbol;
 	return 'syms';
 	return 'syms';
     }
     }
@@ -275,8 +277,12 @@ sub merge_symbols {
 	$self->create_object($soname, '');
 	$self->create_object($soname, '');
     }
     }
     # Scan all symbols provided by the objects
     # Scan all symbols provided by the objects
+    my $obj = $self->{objects}{$soname};
+    # invalidate the minimum version cache - it is not sufficient to
+    # invalidate in add_symbol, since we might change a minimum
+    # version for a particular symbol without adding it
+    $obj->{minver_cache} = [];
     foreach my $name (keys %dynsyms) {
     foreach my $name (keys %dynsyms) {
-	my $obj = $self->{objects}{$soname};
         my $sym;
         my $sym;
 	if (exists $obj->{syms}{$name}) {
 	if (exists $obj->{syms}{$name}) {
 	    # If the symbol is already listed in the file
 	    # If the symbol is already listed in the file
@@ -358,7 +364,8 @@ sub create_object {
 	syms => {},
 	syms => {},
 	fields => {},
 	fields => {},
 	wildcards => {},
 	wildcards => {},
-	deps => [ @deps ]
+	deps => [ @deps ],
+        minver_cache => []
     };
     };
 }
 }
 
 
@@ -371,14 +378,17 @@ sub get_dependency {
 sub get_smallest_version {
 sub get_smallest_version {
     my ($self, $soname, $dep_id) = @_;
     my ($self, $soname, $dep_id) = @_;
     $dep_id = 0 unless defined($dep_id);
     $dep_id = 0 unless defined($dep_id);
+    my $so_object = $self->{objects}{$soname};
+    return $so_object->{minver_cache}[$dep_id] if(defined($so_object->{minver_cache}[$dep_id]));
     my $minver;
     my $minver;
-    foreach my $sym (values %{$self->{objects}{$soname}{syms}}) {
+    foreach my $sym (values %{$so_object->{syms}}) {
         next if $dep_id != $sym->{dep_id};
         next if $dep_id != $sym->{dep_id};
         $minver = $sym->{minver} unless defined($minver);
         $minver = $sym->{minver} unless defined($minver);
         if (vercmp($minver, $sym->{minver}) > 0) {
         if (vercmp($minver, $sym->{minver}) > 0) {
             $minver = $sym->{minver};
             $minver = $sym->{minver};
         }
         }
     }
     }
+    $so_object->{minver_cache}[$dep_id] = $minver;
     return $minver;
     return $minver;
 }
 }