[Aptitude-devel] r3252 - in branches/aptitude-0.3/aptitude: . src/generic src/generic/problemresolver

Daniel Burrows dburrows@costa.debian.org
Mon, 02 May 2005 01:39:02 +0000


Author: dburrows
Date: Mon May  2 01:38:58 2005
New Revision: 3252

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
Log:
Make sure to iterate over the dependencies of a version when marking it for
installation.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon May  2 01:38:58 2005
@@ -1,5 +1,11 @@
 2005-05-01  Daniel Burrows  <dburrows@debian.org>
 
+	* src/generic/aptitude_resolver.h, src/generic/problemresolver/problemresolver.h, src/generic/problemresolver/test.cc:
+
+	Fix a mistake in how successors are generated -- of course we have
+	to test the dependencies of the new version being installed as
+	well!
+
 	* src/solution_fragment.cc:
 
 	Fix a silly thinko that caused segfaults when trying to display

Modified: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h	Mon May  2 01:38:58 2005
@@ -216,8 +216,10 @@
   }
 
   class revdep_iterator;
+  class dep_iterator;
 
   revdep_iterator revdeps_begin() const;
+  dep_iterator deps_begin() const;
 };
 
 inline aptitude_resolver_version aptitude_resolver_package::current_version() const
@@ -518,11 +520,145 @@
   }
 };
 
+/** Iterates over the distinct dependencies of a version.  These
+ *  include its direct/indirect dependencies (separated into OR
+ *  groups) and its direct/indirect conflicts (one apiece).
+ */
+class aptitude_resolver_version::dep_iterator
+{
+  pkgDepCache *cache;
+  pkgCache::DepIterator dep;
+  pkgCache::PrvIterator prv;
+  /** If \b true, then dep is a Conflicts and we are iterating over
+   *  the packages providing its target.
+   */
+  bool prv_open;
+
+  void normalize()
+  {
+    if(prv_open)
+      {
+	assert(!dep.end());
+	assert(dep->Type == pkgCache::Dep::Conflicts);
+
+	while(!prv.end() && prv.OwnerPkg()==dep.ParentPkg())
+	  ++prv;
+
+	if(prv.end())
+	  {
+	    prv_open=false;
+	    ++dep;
+	  }
+	else
+	  return;
+      }
+
+    assert(!prv_open);
+
+
+    // Skip non-critical and self dependencies.  Need to do this here
+    // as well as below in case dep already points to such a
+    // dependency.
+    while(!dep.end() &&
+	  (dep.ParentPkg() == dep.TargetPkg() ||
+	   !dep.IsCritical()))
+      ++dep;
+
+    // If we ran out of deps, we're done!
+  }
+
+public:
+  dep_iterator(pkgDepCache *_cache)
+    :cache(_cache),
+     prv(*_cache, 0, (pkgCache::Package *) 0),
+     prv_open(false)
+  {
+  }
+
+
+  dep_iterator(const pkgCache::DepIterator &start,
+	       pkgDepCache *_cache)
+    :cache(_cache),
+     dep(start),
+     prv(*_cache, 0, (pkgCache::Package *) 0),
+     prv_open(false)
+  {
+    normalize();
+  }
+
+  dep_iterator &operator=(const dep_iterator &other)
+  {
+    cache=other.cache;
+    dep=other.dep;
+    prv=other.prv;
+    prv_open=other.prv_open;
+
+    return *this;
+  }
+
+  aptitude_resolver_dep operator*() const
+  {
+    return aptitude_resolver_dep(dep, prv, cache);
+  }
+
+  bool end() const
+  {
+    return dep.end();
+  }
+
+  dep_iterator &operator++()
+  {
+    assert(!dep.end());
+
+    // If the Provides list is nonempty, advance it.
+    if(!prv.end())
+      ++prv;
+    // If we weren't trying to iterate over a Provides list *and* the
+    // current dep is a non-versioned Conflicts, start such an
+    // iteration.
+    else if(!prv_open && dep->Type == pkgCache::Dep::Conflicts &&
+	    !dep.TargetVer())
+      {
+	prv_open=true;
+	prv=dep.TargetPkg().ProvidesList();
+      }
+    // Otherwise push on to the next top-level dep.
+    else
+      {
+	if(!dep.end() && dep->Type == pkgCache::Dep::Conflicts)
+	  ++dep;
+	else
+	  {
+	    // If it's not a conflict, skip a whole OR group.
+	    while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
+	      ++dep;
+
+	    // Now we're on the last element of the OR group, push
+	    // forward.
+	    if(!dep.end())
+	      ++dep;
+	  }
+      }
+
+    normalize();
+
+    return *this;
+  }
+};
+
 inline aptitude_resolver_version::revdep_iterator aptitude_resolver_version::revdeps_begin() const
 {
   return revdep_iterator(ver, cache);
 }
 
+inline aptitude_resolver_version::dep_iterator aptitude_resolver_version::deps_begin() const
+{
+  if(ver.end())
+    return dep_iterator(cache);
+  else
+    return dep_iterator(ver.DependsList(), cache);
+}
+
 /** This class uses a technique similar to rev_dep_lst.  It assumes
  *  that the dependency is critical (noncritical deps are weeded out
  *  by the universe's broken_dep_iterator and hidden from the
@@ -926,57 +1062,21 @@
   {
     pkgDepCache *cache;
 
-    class pkgCache::PkgIterator pkg;
-    class pkgCache::VerIterator ver;
-    class pkgCache::DepIterator dep;
-    class pkgCache::PrvIterator prv;
-    bool prv_open;
+    pkgCache::PkgIterator pkg;
+    pkgCache::VerIterator ver;
+    aptitude_resolver_version::dep_iterator dep;
 
     // Advance to the next valid dep (inclusive of dep).
     void normalize()
     {
-      // If prv_open, we are iterating over the Provides of something
-      // upon which a package depends.  This is a good situation
-      // *unless* we ran out of Provides or we have an indirect
-      // self-conflict.
-      if(prv_open)
-	{
-	  assert(!dep.end());
-	  assert(dep->Type == pkgCache::Dep::Conflicts);
-
-	  while(!prv.end() && prv.OwnerPkg()==dep.ParentPkg())
-	    ++prv;
-
-	  if(prv.end())
-	    {
-	      prv_open=false;
-	      ++dep;
-	    }
-	  else
-	    return;
-	}
-
-      assert(!prv_open);
-
-      // Skip any dependencies that shouldn't show up in the output.
-      // Need to do this here as well as below in case dep already
-      // points to such a dependency.
-      while(!dep.end() &&
-	    (dep.ParentPkg() == dep.TargetPkg() ||
-	     !dep.IsCritical()))
-	++dep;
-
-      // Now, if we ran our of deps, try to find another one.
       while(dep.end() && !pkg.end())
 	{
 	  while(dep.end() && !ver.end())
 	    {
-	      // Since dep is an end iterator, advance at least
-	      // to the next version.
 	      ++ver;
-
 	      if(!ver.end())
-		dep=ver.DependsList();
+		dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+							    cache);
 	    }
 
 	  if(dep.end())
@@ -986,80 +1086,41 @@
 		{
 		  ver=pkg.VersionList();
 		  if(!ver.end())
-		    dep=ver.DependsList();
+		    dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+								cache);
 		}
 	    }
-
-	  // Avoid direct self-deps and non-critical
-	  // deps. (self-conflicts in particular, but a non-conflict
-	  // self-dep is pointless)
-	  while(!dep.end() &&
-		(dep.ParentPkg() == dep.TargetPkg() ||
-		 !dep.IsCritical()))
-	    ++dep;
 	}
     }
   public:
-#if 0
-    dep_iterator()
-      :cache(0)
-    {
-    }
-#endif
-
     // Start from the given package (typically Head() or End()).
     dep_iterator(const pkgCache::PkgIterator &_pkg,
 		 pkgDepCache *_cache)
       :cache(_cache),
-       pkg(_pkg), prv(*_cache, 0, (pkgCache::Package *) 0),
-       prv_open(false)
+       pkg(_pkg),
+       ver(_pkg.VersionList()),
+       dep(_cache)
     {
       if(!pkg.end())
 	ver=pkg.VersionList();
       if(!ver.end())
-	dep=ver.DependsList();
+	dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+						    _cache);
 
       normalize();
     }
 
     aptitude_universe::dep operator*() const
     {
-      return aptitude_universe::dep(dep, prv, cache);
+      return *dep;
     }
 
     dep_iterator &operator++()
     {
       assert(!dep.end());
 
-      // If the Provides list is open, advance it.
-      if(!prv.end())
-	++prv;
-      // otherwise, if we aren't trying to iterate over a Provides
-      // list and the current dep is a Conflicts, start such an
-      // iteration.
-      else if(!prv_open && dep->Type == pkgCache::Dep::Conflicts)
-	{
-	  prv_open=true;
-	  prv=dep.TargetPkg().ProvidesList();
-	}
-      // Otherwise just advance blindly.
-      else
-	{
-	  if(!dep.end() && dep->Type == pkgCache::Dep::Conflicts)
-	    ++dep;
-	  else
-	    {
-	      // Advance to the end of the OR...
-	      while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
-		++dep;
-
-	      // ...and beyond!
-	      if(!dep.end())
-		++dep;
-	    }
-	}
+      ++dep;
 
-      // Look for a valid dep.
       normalize();
 
       return *this;

Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h	Mon May  2 01:38:58 2005
@@ -754,6 +754,13 @@
 	    !rd.end(); ++rd)
 	  if((*rd).broken_under(tmpsol))
 	    new_broken.insert(*rd);
+
+	// Remember: the dependencies of the *new versions being
+	// installed* might also be broken!
+	for(typename version::dep_iterator di=v.deps_begin();
+	    !di.end(); ++di)
+	  if((*di).broken_under(tmpsol))
+	    new_broken.insert(*di);
       }
 
     const std::set<dep> &old_broken=s.get_broken();

Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc	Mon May  2 01:38:58 2005
@@ -177,6 +177,7 @@
   const dummy_package *package;
 
   vector<dummy_dep *> revdeps;
+  vector<dummy_dep *> deps;
 
   /** The numerical ID of this version. */
   int ID;
@@ -184,6 +185,7 @@
   dummy_version(const dummy_version &other);
 public:
   typedef vector<dummy_dep *>::const_iterator revdep_iterator;
+  typedef vector<dummy_dep *>::const_iterator dep_iterator;
 
   dummy_version(string _name, const dummy_package *_package,
 		unsigned int id)
@@ -214,10 +216,18 @@
     revdeps.push_back(dep);
   }
 
+  void add_dep(dummy_dep *dep)
+  {
+    deps.push_back(dep);
+  }
+
   const dummy_package &get_package() const {return *package;}
 
   revdep_iterator revdeps_begin() const {return revdeps.begin();}
   revdep_iterator revdeps_end() const {return revdeps.end();}
+
+  dep_iterator deps_begin() const {return deps.begin();}
+  dep_iterator deps_end() const {return deps.end();}
 };
 
 dummy_package::dummy_package(string _name, unsigned int id)
@@ -245,7 +255,7 @@
  */
 class dummy_dep
 {
-  const dummy_version *source;
+  dummy_version *source;
   vector<dummy_version *> target_set;
 
   dummy_dep(const dummy_dep &other);
@@ -254,7 +264,7 @@
 public:
   typedef vector<dummy_version *>::const_iterator solver_iterator;
 
-  dummy_dep(const dummy_version *_source,
+  dummy_dep(dummy_version *_source,
 	    const vector<dummy_version *> &_target_set,
 	    unsigned int _ID)
     :source(_source), target_set(_target_set), ID(_ID)
@@ -276,7 +286,7 @@
     return ID<other.ID;
   }
 
-  const dummy_version &get_source() const {return *source;}
+  dummy_version &get_source() const {return *source;}
 
   solver_iterator solvers_begin() const
   {
@@ -371,6 +381,7 @@
     const dummy_version *real_version;
   public:
     typedef wrap_ptr_iter<dummy_dep, dep> revdep_iterator;
+    typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
 
     version():real_version(0) {}
     version(const dummy_version *_real_version)
@@ -413,6 +424,12 @@
       return wrap_ptr_iter<dummy_dep, dep>(real_version->revdeps_begin(),
 					   real_version->revdeps_end());
     }
+
+    wrap_ptr_iter<dummy_dep, dep> deps_begin() const
+    {
+      return wrap_ptr_iter<dummy_dep, dep>(real_version->deps_begin(),
+					   real_version->deps_end());
+    }
   };
 
 
@@ -651,6 +668,8 @@
 
     dummy_dep *newdep=deps.back();
 
+    newdep->get_source().add_dep(newdep);
+
     for(dummy_dep::solver_iterator i=newdep->solvers_begin();
 	i!=newdep->solvers_end(); ++i)
       (*i)->add_revdep(newdep);