[Aptitude-svn-commit] r3977 - in branches/aptitude-0.3/aptitude: . src/generic

Daniel Burrows dburrows at costa.debian.org
Mon Aug 29 04:53:58 UTC 2005


Author: dburrows
Date: Mon Aug 29 04:53:55 2005
New Revision: 3977

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/apt.cc
Log:
Memoize surrounding_or to greatly increase its speed, due to a fact
turned up by the magic of profiling: surrounding_or was eating 25%
of the runtime of a typical problem resolving session.

Note, however, that surrounding_or still eats a lot of time, due
primarily to the fact that it's invoked over ten million times.
Probably it would be a good idea to find out who's invoking it and target
those routines as well.


Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Aug 29 04:53:55 2005
@@ -1,5 +1,14 @@
 2005-08-28  Daniel Burrows  <dburrows at debian.org>
 
+	* src/generic/apt.cc:
+
+	  Memoize surrounding_or: somewhat surprisingly, gprof reports
+	  that aptitude's resolver is now (since the recent changes -- and
+	  I suspect that the ones which caused this were *required* for
+	  correctness' sake) spending 25% of its time in this routine!
+	  The current change just memoizes the start of the OR group,
+	  calculating the group's end directly from the start.
+
 	* src/generic/immset.h:
 
 	  Correct the corresponding thinko in the double left rotate.

Modified: branches/aptitude-0.3/aptitude/src/generic/apt.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/apt.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/apt.cc	Mon Aug 29 04:53:55 2005
@@ -51,6 +51,10 @@
 enum interesting_state {uncached = 0, uninteresting, interesting};
 static interesting_state *cached_deps_interesting = NULL;
 
+// Memoization of surrounding_or.  To save space, the low bit of each
+// pointer in the following table is set to 1 when a result is cached:
+static pkgCache::Dependency **cached_surrounding_or = NULL;
+
 aptitudeCacheFile *apt_cache_file=NULL;
 signalling_config *aptcfg=NULL;
 pkgRecords *apt_package_records=NULL;
@@ -74,6 +78,12 @@
   cached_deps_interesting = NULL;
 }
 
+static void reset_surrounding_or_memoization()
+{
+  delete cached_surrounding_or;
+  cached_surrounding_or = NULL;
+}
+
 static void reload_user_pkg_hier()
 {
   delete user_pkg_hier;
@@ -127,6 +137,8 @@
 
   cache_closed.connect(sigc::ptr_fun(&reset_interesting_dep_memoization));
 
+  cache_closed.connect(sigc::ptr_fun(&reset_surrounding_or_memoization));
+
   apt_dumpcfg("Aptitude");
 
   apt_undos=new undo_list;
@@ -362,13 +374,13 @@
 
 // This does not assume that the dependency is the first elements of
 // its OR group.
-void surrounding_or(pkgCache::DepIterator dep,
-		    pkgCache::DepIterator &start,
-		    pkgCache::DepIterator &end)
+static void surrounding_or_internal(const pkgCache::DepIterator &dep,
+				    pkgCache::DepIterator &start,
+				    pkgCache::DepIterator &end)
 {
   bool found=false;
 
-  start=dep.ParentVer().DependsList();
+  start=const_cast<pkgCache::DepIterator &>(dep).ParentVer().DependsList();
   end=start;
 
   while(!end.end() && !found)
@@ -393,6 +405,42 @@
   assert(found);
 }
 
+void surrounding_or(pkgCache::DepIterator dep,
+		    pkgCache::DepIterator &start,
+		    pkgCache::DepIterator &end)
+{
+  if(cached_surrounding_or == NULL)
+    {
+      cached_surrounding_or = new pkgCache::Dependency *[(*apt_cache_file)->Head().DependsCount];
+      for(unsigned long i = 0; i<(*apt_cache_file)->Head().DependsCount; ++i)
+	cached_surrounding_or[i] = 0;
+    }
+
+  pkgCache::Dependency *s = cached_surrounding_or[dep->ID];
+
+  // Use the old trick of stuffing values into the low bits of a
+  // pointer.
+  if(((unsigned long) s & 0x1) != 0)
+    {
+      pkgCache::Dependency *unmunged
+	= (pkgCache::Dependency *) (((unsigned long) s) & ~0x1UL);
+
+      start = pkgCache::DepIterator(*apt_cache_file, unmunged);
+      end = start;
+
+      while(end->CompareOp & pkgCache::Dep::Or)
+	++end;
+
+      ++end;
+    }
+  else
+    {
+      surrounding_or_internal(dep, start, end);
+
+      cached_surrounding_or[dep->ID] = (pkgCache::Dependency *) ((unsigned long) ((pkgCache::Dependency *) start) | 0x1UL);
+    }
+}
+
 bool package_suggested(const pkgCache::PkgIterator &pkg)
 {
   pkgDepCache::StateCache &state=(*apt_cache_file)[pkg];



More information about the Aptitude-svn-commit mailing list