[Aptitude-svn-commit] r3794 - in branches/aptitude-0.3/aptitude: .
src/generic/problemresolver
Daniel Burrows
dburrows at costa.debian.org
Tue Aug 9 23:21:41 UTC 2005
Author: dburrows
Date: Tue Aug 9 23:21:38 2005
New Revision: 3794
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
Log:
Add framework for forbidding individual versions.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Tue Aug 9 23:21:38 2005
@@ -1,5 +1,9 @@
2005-08-09 Daniel Burrows <dburrows at debian.org>
+ * src/generic/problemresolver/problemresolver.h:
+
+ Add initial support for user-forbidden versions.
+
* src/solution_screen.cc:
Fix item highlighting.
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 Tue Aug 9 23:21:38 2005
@@ -504,6 +504,13 @@
* dependency is satisfied by one and not the other, it appears in
* the revdeps list of at least one of the versions. (this allows
* apt's conflicts to be handled efficiently)
+ *
+ * The client can request that particular package versions not appear
+ * in generated solutions, or cancel such requests, by using the
+ * "forbid_version" and "unforbid_version" methods. Solutions that
+ * are held up by a "forbid_version" invocation will be returned to
+ * the search queue when a corresponding "unforbid_version" is
+ * issued.
*/
@@ -602,6 +609,11 @@
/** If \b true, we have exhausted the list of solutions. */
bool finished:1;
+ /** If \b true, it is possible that some deferred solutions are
+ * no longer forbidden.
+ */
+ bool forbiddings_dirty:1;
+
bool debug:1;
/** The working queue: */
@@ -610,9 +622,80 @@
/** Stores already-seen solutions: */
std::set<solution, solution_contents_compare> closed;
+ /** Stores solutions that were ignored because of user constraints
+ * (but could be reinstated later). Disjoint with closed.
+ */
+ std::set<solution, solution_contents_compare> deferred;
+
+ /** Stores versions that have been forbidden by the user; distinct
+ * from the per-solution forbid sets that track changes on a single
+ * inference path.
+ */
+ std::set<version> user_forbidden;
+
/** Stores generated solutions: */
std::vector<solution> generated_solutions;
+ /** Calculate whether the solution is forbidden based on
+ * user_forbidden by testing whether the intersection of the
+ * solution and the forbidden set is nonempty.
+ */
+ bool is_forbidden(const solution &s)
+ {
+ typename std::set<version>::const_iterator uf_iter
+ = user_forbidden.begin();
+
+ typename std::map<package, action>::const_iterator s_iter
+ = s.get_actions().begin();
+
+ while(uf_iter != user_forbidden.end() &&
+ s_iter != s.get_actions().end())
+ {
+ if(*uf_iter == s_iter->second.ver)
+ return true;
+ else if(*uf_iter < s_iter->second.ver)
+ ++uf_iter;
+ else
+ ++s_iter;
+ }
+
+ return false;
+ }
+
+ /** Place any solutions that were deferred and are no longer
+ * forbidden back on the open queue.
+ */
+ void reexamine_deferred()
+ {
+ // NB: the STL guarantees that erasing elements from a set does
+ // not invalidate existing iterators. Hence this very careful
+ // iteration:
+
+ typename std::set<solution, solution_contents_compare>::const_iterator
+ i = deferred.begin(), j = i;
+
+ while(i != deferred.end())
+ {
+ ++j;
+
+ if(!is_forbidden(*i))
+ {
+ open.push(*i);
+ deferred.erase(i);
+ }
+
+ i = j;
+ }
+
+ // Note that we might have to rescind the "finished" state: the
+ // actions above can actually cause new solutions to be available
+ // for processing!
+ if(finished && !open.empty())
+ finished = false;
+
+ forbiddings_dirty = false;
+ }
+
/** Represents a possible successor to the given solution, created
* by installing a single 'new' version.
*/
@@ -796,29 +879,41 @@
{
solution s2=do_install(s, abegin, aend, forbidden_iter);
- if(!irrelevant(s2))
+ if(irrelevant(s2))
{
if(debug)
{
- std::cout << "Enqueuing ";
+ std::cout << "Dropping irrelevant solution ";
s2.dump(std::cout);
std::cout << std::endl;
}
- open.push(s2);
+ return false;
+ }
+ else if(is_forbidden(s2))
+ {
+ if(debug)
+ {
+ std::cout << "Deferring forbidden solution ";
+ s2.dump(std::cout);
+ std::cout << std::endl;
+ }
- return true;
+ deferred.insert(s2);
+ return false;
}
else
{
if(debug)
{
- std::cout << "Dropping irrelevant solution ";
+ std::cout << "Enqueuing ";
s2.dump(std::cout);
std::cout << std::endl;
}
- return false;
+ open.push(s2);
+
+ return true;
}
}
@@ -1094,7 +1189,7 @@
:step_score(_step_score), broken_score(_broken_score),
minimum_score(-infinity), max_successors(_max_successors),
full_solution_score(_full_solution_score),
- universe(_universe), finished(false), debug(false)
+ universe(_universe), finished(false), forbiddings_dirty(false), debug(false)
{
version_scores=new int[universe.get_version_count()];
for(size_t i=0; i<universe.get_version_count(); ++i)
@@ -1180,6 +1275,30 @@
return version_scores[ver.get_id()];
}
+ /** Forbid this resolver from generating solutions containing the
+ * given version.
+ */
+ void forbid_version(const version &ver)
+ {
+ user_forbidden.insert(ver);
+ }
+
+ /** Cancel any forbidding of ver, allowing the resolver to once
+ * again generate solutions containing it.
+ */
+ void unforbid_version(const version &ver)
+ {
+ user_forbidden.erase(ver);
+
+ forbiddings_dirty = true;
+ }
+
+ /** Query whether the given version is forbidden. */
+ bool is_forbidden(const version &ver) const
+ {
+ return user_forbidden.find(ver) != user_forbidden.end();
+ }
+
/** Try to find the "next" solution: remove partial solutions from
* the open queue and place them in the closed queue until one of
* the following occurs:
@@ -1205,6 +1324,9 @@
*/
solution find_next_solution(int max_steps)
{
+ if(forbiddings_dirty)
+ reexamine_deferred();
+
if(finished)
throw NoMoreSolutions();
@@ -1240,6 +1362,19 @@
continue;
}
+ if(is_forbidden(s))
+ {
+ if(debug)
+ {
+ std::cout << "Deferring forbidden solution ";
+ s.dump(std::cout);
+ std::cout << std::endl;
+ }
+
+ deferred.insert(s);
+ continue;
+ }
+
closed.insert(s);
if(debug)
More information about the Aptitude-svn-commit
mailing list