[Aptitude-svn-commit] r3870 - in branches/aptitude-0.3/aptitude: .
src/generic
Daniel Burrows
dburrows at costa.debian.org
Tue Aug 16 20:41:31 UTC 2005
Author: dburrows
Date: Tue Aug 16 20:41:28 2005
New Revision: 3870
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc
Log:
Introduce restrictions on which recommendations are considered 'interesting'.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Tue Aug 16 20:41:28 2005
@@ -1,5 +1,12 @@
2005-08-16 Daniel Burrows <dburrows at debian.org>
+ * src/generic/aptitude_resolver_universe.cc:
+
+ Redefine is_interesting_dep in terms of "subsumption": a
+ recommendation is now considered "interesting" iff it covers
+ neither a subset nor a superset of the version space covered by
+ a recommendation of the current version.
+
* src/generic/aptitude_resolver_universe.cc, src/generic/aptitude_resolver_universe.h:
Make the is_interesting_dep function really be a static member
Modified: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc (original)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc Tue Aug 16 20:41:28 2005
@@ -6,12 +6,193 @@
using namespace std;
+/** \return \b true if d1 subsumes d2; that is, if one of the
+ * following holds:
+ *
+ * (a) d1 and d2 target the same package and are unversioned.
+ *
+ * (b) d1 and d2 are unversioned and some version of d2's target
+ * provides the target package of d1.
+ *
+ * (c) d1 and d2 target the same package, d1 is unversioned, and d2
+ * is versioned.
+ *
+ * (c) d1 and d2 target the same package and are versioned
+ * (with op1 ver1 and op2 ver2 being the operations and versions)
+ * and:
+ *
+ * - op1 is >=, op2 is >>, >=, or =, and ver1 <= ver2; or
+ * - op1 is <=, op2 is <<, <=, or =, and ver1 >= ver2; or
+ * - op1 is >>, op2 is >>, and ver1 <= ver2; or
+ * - op1 is >>, op2 is =, and ver1 < ver2; or
+ * - op1 is <<, op2 is <<, and ver1 >= ver2; or
+ * - op1 is <<, op2 is =, and ver1 > ver2; or
+ * - op1 is =, op2 is =, and ver1 = ver2; or
+ * - op1 is !=, op2 is !=, and ver1 = ver2.
+ */
+static bool subsumes(const pkgCache::DepIterator &d1,
+ const pkgCache::DepIterator &d2)
+{
+ pkgCache::PkgIterator target1 = const_cast<pkgCache::DepIterator &>(d1).TargetPkg();
+ pkgCache::PkgIterator target2 = const_cast<pkgCache::DepIterator &>(d2).TargetPkg();
+
+ if(!d1.TargetVer())
+ {
+ if(target1 == target2)
+ return true;
+
+ if(d2.TargetVer())
+ return false;
+
+ for(pkgCache::PrvIterator p = target1.ProvidesList();
+ !p.end(); ++p)
+ if(p.OwnerPkg() == target2)
+ return true;
+
+ return false;
+ }
+ else
+ {
+ if(target1 != target2)
+ return false;
+
+ if(!d2.TargetVer())
+ return false;
+
+ pkgCache::Dep::DepCompareOp t1 = (pkgCache::Dep::DepCompareOp) (d1->CompareOp &~ pkgCache::Dep::Or);
+ pkgCache::Dep::DepCompareOp t2 = (pkgCache::Dep::DepCompareOp) (d2->CompareOp &~ pkgCache::Dep::Or);
+
+ int cmpresult = _system->VS->DoCmpVersion(d1.TargetVer(), d1.TargetVer()+strlen(d1.TargetVer()),
+ d2.TargetVer(), d2.TargetVer()+strlen(d2.TargetVer()));
+
+ switch(t1)
+ {
+ case pkgCache::Dep::LessEq:
+ return
+ (t2 == pkgCache::Dep::Less ||
+ t2 == pkgCache::Dep::LessEq ||
+ t2 == pkgCache::Dep::Equals) &&
+ cmpresult >= 0;
+ case pkgCache::Dep::GreaterEq:
+ return
+ (t2 == pkgCache::Dep::Greater ||
+ t2 == pkgCache::Dep::LessEq ||
+ t2 == pkgCache::Dep::Equals) &&
+ cmpresult <= 0;
+ case pkgCache::Dep::Less:
+ return
+ (t2 == pkgCache::Dep::Less && cmpresult >= 0) ||
+ (t2 == pkgCache::Dep::Equals && cmpresult > 0);
+ case pkgCache::Dep::Greater:
+ return
+ (t2 == pkgCache::Dep::Greater && cmpresult <= 0) ||
+ (t2 == pkgCache::Dep::Equals && cmpresult < 0);
+ case pkgCache::Dep::Equals:
+ return
+ (t2 == pkgCache::Dep::Equals && cmpresult == 0);
+ case pkgCache::Dep::NotEquals:
+ return
+ (t2 == pkgCache::Dep::NotEquals && cmpresult == 0);
+
+ // These shouldn't happen:
+ case pkgCache::Dep::NoOp:
+ default:
+ abort();
+ }
+ }
+}
+
+/** \return \b true if the OR group of d1 subsumes the OR group of d2:
+ * that is, if every member of the OR group containing d2 has a
+ * subsuming element in the OR group containing d1.
+ */
+static bool or_group_subsumes(const pkgCache::DepIterator &d1,
+ const pkgCache::DepIterator &d2)
+{
+ pkgCache::DepIterator start1, end1, start2, end2;
+
+ surrounding_or(d1, start1, end1);
+ surrounding_or(d2, start2, end2);
+
+ for(pkgCache::DepIterator i = d1; i != end1; ++i)
+ {
+ bool found = false;
+
+ for(pkgCache::DepIterator j = d2; j != end2; ++j)
+ if(subsumes(i, j))
+ {
+ found = true;
+ break;
+ }
+
+ if(!found)
+ return false;
+ }
+
+ return true;
+}
+
// This should be a static member of the universe object, but it's
// rather awkward to put it there right now.
+//
+// Interesting deps are:
+//
+// - All critical deps
+// - All recommendations that are currently satisfied
+// - All recommendations that are unrelated under subsumption to
+// each recommendation of the current package version.
inline bool aptitude_universe::is_interesting_dep(const pkgCache::DepIterator &d)
{
- return const_cast<pkgCache::DepIterator &>(d).IsCritical() ||
- d->Type == pkgCache::Dep::Recommends;
+ if(const_cast<pkgCache::DepIterator &>(d).IsCritical())
+ return true;
+ else if(d->Type != pkgCache::Dep::Recommends)
+ return false;
+ else
+ {
+ pkgCache::DepIterator dtmp = d;
+ while(!dtmp.end() && dtmp->CompareOp & pkgCache::Dep::Or)
+ ++dtmp;
+ if((*apt_cache_file)[d] & pkgDepCache::DepGNow)
+ return true;
+
+ pkgCache::VerIterator currver = const_cast<pkgCache::DepIterator &>(d).ParentPkg().CurrentVer();
+ pkgCache::VerIterator parver = const_cast<pkgCache::DepIterator &>(d).ParentVer();
+
+ if(currver == parver)
+ return false;
+ else if(currver.end())
+ return true;
+ else
+ // Check whether the current version of this package has a dep
+ // that either subsumes _or is subsumed by_ this
+ // recommendation. (for mathematical "correctness" we'd only
+ // check the first direction, but the goal is to not annoy the
+ // user unnecessarily; losing a few new recommendations is OK)
+ //
+ // NB: full correctness without annoyance means actually
+ // TRIMMING DOWN the target set of a recommendation by
+ // subtracting elements that are in the current version's
+ // recommendation list. Needless to say, I'm ignoring this
+ // for now.
+ {
+ pkgCache::DepIterator d2 = currver.DependsList();
+
+ while(!d2.end())
+ {
+ if(d2->Type == pkgCache::Dep::Recommends &&
+ or_group_subsumes(d2, d) || or_group_subsumes(d, d2))
+ return false;
+
+ while(!d2.end() && ((d2->CompareOp & pkgCache::Dep::Or) != 0))
+ ++d2;
+
+ if(!d2.end())
+ ++d2;
+ }
+
+ return true;
+ }
+ }
}
string aptitude_resolver_version::get_name() const
More information about the Aptitude-svn-commit
mailing list