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

Daniel Burrows dburrows at costa.debian.org
Wed Sep 14 21:16:06 UTC 2005


Author: dburrows
Date: Wed Sep 14 21:16:02 2005
New Revision: 4085

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/resolver_manager.cc
   branches/aptitude-0.3/aptitude/src/generic/resolver_manager.h
Log:
Make the resolver manager interface more flexible.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Wed Sep 14 21:16:02 2005
@@ -1,5 +1,12 @@
 2005-09-14  Daniel Burrows  <dburrows at debian.org>
 
+	* src/resolver_manager.cc, src/resolver_manager.h:
+
+	  Instead of providing a limited interface to just step around and
+	  get the current solution, allow steps to be taken without
+	  implicitly calculating a new solution, and allow any solution to
+	  be queried (possibly generating a bunch in the process).
+
 	* src/ui.cc:
 
 	  When accessing resman in contexts where the apt cache might not

Modified: branches/aptitude-0.3/aptitude/src/generic/resolver_manager.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/resolver_manager.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/resolver_manager.cc	Wed Sep 14 21:16:02 2005
@@ -143,20 +143,47 @@
     return selected_solution == 0;
 }
 
+const aptitude_resolver::solution &resolver_manager::get_solution(unsigned int solution_num)
+{
+  while(solution_num >= solutions.size())
+    {
+      try
+	{
+	  solutions.push_back(new aptitude_resolver::solution(resolver->find_next_solution(aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000))));
+	  out_of_time = false;
+	}
+      catch(NoMoreTime)
+	{
+	  out_of_time = true;
+	  throw NoMoreTime();
+	}
+      catch(NoMoreSolutions)
+	{
+	  selected_solution_changed();
+	  throw NoMoreSolutions();
+	}
+    }
+
+  return *solutions[solution_num];
+}
+
 const aptitude_resolver::solution &resolver_manager::get_current_solution()
 {
   assert(resolver);
 
   if(out_of_time)
     throw NoMoreTime();
-  else if(!solutions.empty())
-    return *solutions[selected_solution];
   else
-    return next_solution();
+    {
+      unsigned int start_size = solutions.size();
+      const aptitude_resolver::solution &rval = get_solution(selected_solution);
+      if(start_size != solutions.size())
+	selected_solution_changed();
+
+      return rval;
+    }
 }
 
-// At the moment the undo argument is ignored; it's there for future
-// use.
 void resolver_manager::reject_version(const aptitude_resolver_version &ver)
 {
   assert(resolver);
@@ -249,62 +276,31 @@
   return resolver->is_forced_broken(dep);
 }
 
+void resolver_manager::select_next_solution()
+{
+  ++selected_solution;
+  selected_solution_changed();
+}
 
-const aptitude_resolver::solution &resolver_manager::next_solution()
+void resolver_manager::select_previous_solution()
 {
-  if(solutions.empty())
-    {
-      try
-	{
-	  solutions.push_back(new aptitude_resolver::solution(resolver->find_next_solution(aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000))));
-	  selected_solution=0;
-	  out_of_time=false;
-	  selected_solution_changed();
-	  return *solutions.back();
-	}
-      catch(NoMoreTime) {
-	out_of_time=true;
-	throw NoMoreTime();
-      }
-      catch(NoMoreSolutions) {
-	selected_solution_changed();
-	throw NoMoreSolutions();
-      }
-    }
-  else if(selected_solution<solutions.size()-1)
-    {
-      ++selected_solution;
-      selected_solution_changed();
-      return *solutions[selected_solution];
-    }
+  if(selected_solution == 0)
+    throw NoMoreSolutions();
   else
-    {
-      // otherwise weirdness is happening.
-      assert(!out_of_time);
+    --selected_solution;
+  selected_solution_changed();
+}
 
-      try
-	{
-	  solutions.push_back(new aptitude_resolver::solution(resolver->find_next_solution(aptcfg->FindI(PACKAGE "::ProblemResolver::StepLimit", 5000))));
-	}
-      catch(NoMoreSolutions)
-	{
-	  selected_solution_changed();
-	  throw NoMoreSolutions();
-	}
-      ++selected_solution;
-      selected_solution_changed();
-      return *solutions.back();
-    }
+const aptitude_resolver::solution &resolver_manager::next_solution()
+{
+  select_next_solution();
+  return get_current_solution();
 }
 
 const aptitude_resolver::solution &resolver_manager::previous_solution()
 {
-  if(solutions.empty() || selected_solution == 0)
-    throw NoMoreSolutions();
-
-  --selected_solution;
-  selected_solution_changed();
-  return *solutions[selected_solution];
+  select_previous_solution();
+  return get_current_solution();
 }
 
 void resolver_manager::tweak_score(const pkgCache::PkgIterator &pkg,

Modified: branches/aptitude-0.3/aptitude/src/generic/resolver_manager.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/resolver_manager.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/resolver_manager.h	Wed Sep 14 21:16:02 2005
@@ -40,6 +40,24 @@
 template<typename PackageUniverse> class generic_solution;
 class aptitude_resolver;
 
+namespace threads
+{
+  class thread;
+};
+
+/** Manages a resolver for a single cache object.  When broken
+ *  packages arise, a new resolver is created; whenever the state of a
+ *  package changes, the resolver is deleted and reset.  While a
+ *  resolver is active, users of this class can "select" a particular
+ *  solution, then "generate" it.  Generating a solution is a
+ *  potentially slow operation and support for pushing that action
+ *  into a background thread will be provided in the future.
+ *
+ *  Note: of course it would also be possible to simply query the
+ *  manager for the Nth solution; however, using a selection pointer
+ *  makes it easy for different UI modules to share information about
+ *  the currently selected solution.
+ */
 class resolver_manager : public sigc::trackable
 {
   /** The cache file on which this manager operates. */
@@ -48,6 +66,7 @@
   /** The active resolver, or \b NULL if none is active. */
   aptitude_resolver *resolver;
 
+
   /** The solutions generated by this manager since the last change to
    *  the cache.
    */
@@ -98,6 +117,27 @@
    */
   unsigned int get_selected_solution() const {return selected_solution;}
 
+  /** Requires that resolver_exists() is \b true.  Return the solution
+   *  in the given position, generating it if it is past the end of
+   *  the list; will continue a search even if it ran out of time
+   *  previously.
+   *
+   *  \throw NoMoreSolutions if the list of solutions is exhausted
+   *  \throw NoMoreTime if time is exhausted while searching for
+   *                    the solution (time here is counted separately
+   *                    at each step).
+   */
+  const generic_solution<aptitude_universe> &get_solution(unsigned int solution_num);
+
+  /** Requires the resolver_exists() is \b true.  Return the currently
+   *  selected solution, perhaps generating it; however, will not
+   *  continue to search if the last search ran out of time.
+   *
+   *  \throw NoMoreSolutions if the list of solutions is exhausted
+   *  \throw NoMoreTime if time is exhausted while searching for the solution.
+   */
+  const generic_solution<aptitude_universe> &get_current_solution();
+
 
   /** If \b true, all solutions have been generated. */
   bool solution_generation_complete() const;
@@ -113,33 +153,11 @@
    */
   bool solutions_at_start() const;
 
-  // NB: the reason for returning references below is because
-  // otherwise you have circular dependencies between code and nothing
-  // compiles :(
-
-  /** Requires that resolver_exists() is \b true.  If no solutions
-   *  have been calculated yet, will calculate and return the first
-   *  solution.
-   *
-   *  \return the currently selected solution.  This reference is not
-   *  guaranteed to persist if any other operation is performed on the
-   *  cache; a stack variable should be instantiated from it.
-   *
-   *  \throws NoMoreSolutions if there are no solutions and the search
-   *  is exhausted.
-   *
-   *  \throws NoMoreTime if there are no solutions and the last effort
-   *  ran out of time.
-   */
-  const generic_solution<aptitude_universe> &get_current_solution();
-
 
   /** Requires that resolver_exists() is \b true.  Temporarily rejects
    *  any solutions generated by the currently active installer that
-   *  involve installing the given version.  This is distinct from our
-   *  own version forbidding mechanism in that it completely prevents
-   *  the generation of solutions containing this version, but it
-   *  doesn't outlast a single resolution session.
+   *  involve installing the given version; the rejection will be
+   *  discarded when the resolver is.
    */
   void reject_version(const aptitude_resolver_version &ver);
 
@@ -192,6 +210,18 @@
 
 
 
+  /** Move the selection pointer to the next solution, without
+   *  generating it.
+   */
+  void select_next_solution();
+
+  /** Move the selection pointer to the previous solution, without
+   *  generating it.
+   *
+   *  \throws NoMoreSolutions if solutions_at_start()
+   */
+  void select_previous_solution();
+
   /** Advance to the next solution.
    *
    *  \return the next solution.  This reference is not guaranteed to
@@ -210,7 +240,7 @@
    *  to persist if any other operation is performed on the cache; a
    *  stack variable should be instantiated from it.
    *
-   *  \throws NoMoreSolutions if solutions_at_start()==0
+   *  \throws NoMoreSolutions if solutions_at_start()
    */
   const generic_solution<aptitude_universe> &previous_solution();
 



More information about the Aptitude-svn-commit mailing list