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

Daniel Burrows dburrows at costa.debian.org
Sat Aug 20 17:29:54 UTC 2005


Author: dburrows
Date: Sat Aug 20 17:29:51 2005
New Revision: 3935

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
Log:
Factor out the individual steps of will_conflict into separate and reasonably generic routines.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Sat Aug 20 17:29:51 2005
@@ -2,6 +2,10 @@
 
 	* src/generic/problemresolver/problemresolver.h:
 
+	  Split the monstrosity of will_conflict into four routines.
+
+	* src/generic/problemresolver/problemresolver.h:
+
 	  Get everything compiling and sort of working.  Probably all
 	  sorts of stuff needs to be fixed up, though :-/.
 

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	Sat Aug 20 17:29:51 2005
@@ -410,6 +410,65 @@
   std::ostream &dump(std::ostream &out, const std::map<package, act_conflict> &act) const;
   std::ostream &dump(std::ostream &out, const act_conflict &act) const;
 
+  /** Populate a 'partial conflict map' from a solution. */
+  static void populate_partial_conflict(const solution &s,
+					typename std::map<package, act_conflict> &pc)
+  {
+    for(typename std::map<package, action>::const_iterator si
+	  = s.get_actions().begin(); si != s.get_actions().end(); ++si)
+      pc[si->first] = act_conflict(si->second.ver);
+
+    for(typename std::map<version, dep>::const_iterator fi
+	  = s.get_forbidden_versions().begin();
+	fi != s.get_forbidden_versions().end(); ++fi)
+      pc[fi->first.get_package()] = act_conflict(fi->first, fi->second);
+  }
+
+  /** \return \b true if each element of pc2 is subsumed by an element
+   *  in pc1.
+   */
+  static bool partial_conflict_subsumes(const typename std::map<package, act_conflict> &pc1,
+					const typename std::map<package, act_conflict> &pc2)
+  {
+    typename std::map<package, act_conflict>::const_iterator pc1i = pc1.begin();
+    typename std::map<package, act_conflict>::const_iterator pc2i = pc2.begin();
+
+    while(pc1i != pc1.end() &&
+	  pc2i != pc2.end())
+      {
+	if(pc1i->first < pc2i->first)
+	  ++pc1i;
+	else if(pc2i->first < pc1i->first)
+	  return false;
+	else if(!(pc1i->second.subsumes(pc2i->second)))
+	  return false;
+	else
+	  {
+	    ++pc1i;
+	    ++pc2i;
+	  }
+      }
+
+    return (pc2i == pc2.end());
+  }
+
+  /** Test whether the given partial conflict subsumes an existing
+   *  conflict.
+   *
+   *  \return a conflict subsumed by m, or conflicts.end() if no such
+   *  conflict exists.
+   */
+  typename std::set<std::map<package, act_conflict> >::const_iterator
+  subsumes_any_conflict(const std::map<package, act_conflict> &m) const
+  {
+    for(typename std::set<std::map<package, act_conflict> >::const_iterator ci = conflicts.begin();
+	ci != conflicts.end(); ++ci)
+	if(partial_conflict_subsumes(m, *ci))
+	  return ci;
+
+    return conflicts.end();
+  }
+
   /** Test whether the given solution contains a conflict when the
    *  given action is taken.
    *
@@ -424,16 +483,9 @@
     // this code is important.
     std::map<package, act_conflict> m;
 
-    package p = a.ver.get_package();
-
-    for(typename std::map<package, action>::const_iterator si
-	  = s.get_actions().begin(); si != s.get_actions().end(); ++si)
-      m[si->first] = act_conflict(si->second.ver);
+    populate_partial_conflict(s, m);
 
-    for(typename std::map<version, dep>::const_iterator fi
-	  = s.get_forbidden_versions().begin();
-	fi != s.get_forbidden_versions().end(); ++fi)
-      m[fi->first.get_package()] = act_conflict(fi->first, fi->second);
+    package p = a.ver.get_package();
 
     m[p] = a;
 
@@ -444,61 +496,24 @@
 	std::cout << std::endl;
       }
 
-    for(typename std::set<std::map<package, act_conflict> >::const_iterator ci = conflicts.begin();
-	ci != conflicts.end(); ++ci)
-      {
-	typename std::map<package, act_conflict>::const_iterator cj = ci->begin();
-	typename std::map<package, act_conflict>::const_iterator mi = m.begin();
 
-	bool is_subset = true;
+    typename std::set<std::map<package, act_conflict> >::const_iterator
+      result = subsumes_any_conflict(m);
 
-	while(cj != ci->end() &&
-	      mi != m.end())
-	  {
-	    if(mi->first < cj->first)
-	      ++mi;
-	    else if(cj->first < mi->first)
-	      {
-		is_subset = false;
-		break;
-	      }
-	    else if(!(mi->second.subsumes(cj->second)))
-	      {
-		is_subset = false;
-		break;
-	      }
-	    else
-	      {
-		++mi;
-		++cj;
-	      }
-	  }
-
-	// If we didn't consume the entire conflict, it clearly isn't
-	// a subset of this proposed solution.
-	if(cj != ci->end())
-	  is_subset = false;
-
-	if(is_subset)
-	  {
-	    if(debug)
-	      {
-		std::cout << "Adding " << p.get_name() << " "
-			  << a.ver.get_name();
-
-		if(a.from_dep_source)
-		  std::cout << " due to " << a.d;
+    if(debug && result != conflicts.end())
+      {
+	std::cout << "Adding " << p.get_name() << " "
+		  << a.ver.get_name();
 
-		std::cout << " will trigger conflict ";
-		dump(std::cout, *ci);
-		std::cout << std::endl;
-	      }
+	if(a.from_dep_source)
+	  std::cout << " due to " << a.d;
 
-	    return ci;
-	  }
+	std::cout << " will trigger conflict ";
+	dump(std::cout, *result);
+	std::cout << std::endl;
       }
 
-    return conflicts.end();
+    return result;
   }
 
   /** Generate a table listing the "stupid" pairs of actions in a



More information about the Aptitude-svn-commit mailing list