rename packages works for update now
authorStefan Schubert <schubi@suse.de>
Thu, 14 Feb 2008 17:10:55 +0000 (17:10 +0000)
committerStefan Schubert <schubi@suse.de>
Thu, 14 Feb 2008 17:10:55 +0000 (17:10 +0000)
zypp/sat/SATResolver.cc
zypp/sat/SATResolver.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/ResolverUpgrade.cc

index c2009ae..6ec2319 100644 (file)
@@ -227,6 +227,48 @@ SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::Tra
     return;
 }
 
+
+//----------------------------------------------------------------------------
+// helper functions for distupgrade
+//----------------------------------------------------------------------------
+
+PoolItemList SATResolver::whoProvides(Capability cap) {
+    PoolItemList itemList;
+    Id p, *pp;
+    Repo *installedRepo = sat::Pool::instance().systemRepo().get();
+    for (pp = pool_whatprovides(_SATPool, cap.id()) ; (p = *pp++) != 0; ) {
+       Solvable *solvable = _SATPool->solvables + p;
+       PoolItem item = _pool.find (sat::Solvable(p));
+       if (item &&
+           (!installedRepo || solvable->repo != installedRepo) ) {
+           itemList.push_back (item);
+           MIL << item << " provides " << cap << endl;
+       }
+    }
+    return itemList;
+}
+
+bool SATResolver::doesObsoleteItem (PoolItem candidate, PoolItem installed) {
+  Solvable *sCandidate = _SATPool->solvables + candidate.satSolvable().id();
+  Repo *installedRepo = sat::Pool::instance().systemRepo().get();
+  
+  Id p, *pp, obsolete, *obsoleteIt;
+  
+  if ((!installedRepo || sCandidate->repo != installedRepo) && sCandidate->obsoletes) {
+      obsoleteIt = sCandidate->repo->idarraydata + sCandidate->obsoletes;
+      while ((obsolete = *obsoleteIt++) != 0)
+      {
+         for (pp = pool_whatprovides(_SATPool, obsolete) ; (p = *pp++) != 0; ) {
+             if (p > 0 &&  installed.satSolvable().id() == (sat::detail::SolvableIdType)p) {
+                 MIL << candidate << " obsoletes " << installed << endl;
+                 return true;
+             }
+         }
+      }
+  }
+  return false;
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 // resolvePool
index c127657..83abbe0 100644 (file)
@@ -136,6 +136,9 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     
     bool dosplitprovides () const {return _dosplitprovides;}
     void setDosplitprovides ( const bool dosplitprovides) { _dosplitprovides = dosplitprovides;}
+
+    PoolItemList whoProvides(Capability cap);
+    bool doesObsoleteItem (PoolItem candidate, PoolItem installed);
 };
 
 ///////////////////////////////////////////////////////////////////
index 3cf05ec..7114d62 100644 (file)
@@ -72,7 +72,10 @@ Resolver::Resolver (const ResPool & pool)
     , _verifying(false)
 
 {
-
+    Testcase testcase("/var/log/YaST2/autoTestcase");    
+    sat::Pool satPool( sat::Pool::instance() );
+    _satResolver = new SATResolver(_pool, satPool.get());
+    testcase.createTestcase (*this, true, false); // create pool, do not solver
 }
 
 
@@ -249,13 +252,8 @@ Resolver::resolvePool()
     // Solving with the satsolver
        MIL << "-------------- Calling SAT Solver -------------------" << endl;
        Testcase testcase("/var/log/YaST2/autoTestcase");
-       if ( !_satResolver ) {
-           sat::Pool satPool( sat::Pool::instance() );
-           _satResolver = new SATResolver(_pool, satPool.get());
-           testcase.createTestcase (*this, true, false); // create pool, do not solver
-       } else {
-           testcase.createTestcase (*this, false, false); // write control file only
-       }
+       testcase.createTestcase (*this, false, false); // write control file only
+
 #if 0
        MIL << "------SAT-Pool------" << endl;
        for (sat::Pool::SolvableIterator i = satPool.solvablesBegin();
index ba5dd9e..36fc5a4 100644 (file)
@@ -56,6 +56,7 @@
 #include "zypp/solver/detail/Resolver.h"
 #include "zypp/solver/detail/Testcase.h"
 #include "zypp/Target.h"
+#include "zypp/sat/SATResolver.h"
 
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -140,113 +141,14 @@ downgrade_allowed( PoolItem installed, PoolItem candidate, bool silent_downgrade
 }
 
 
-
-struct FindObsoletes
-{
-    bool obsoletes;
-
-    FindObsoletes ()
-       : obsoletes (false)
-    { }
-
-    bool operator()( const CapAndItem & cai )
-    {
-       obsoletes = true;                               // we have a match
-       return false;                                   // stop looping here
-    }
-};
-
-
-// does the candidate obsolete the capability ?
-
-bool
-Resolver::doesObsoleteCapability (PoolItem candidate, const Capability & cap)
-{
-    _DEBUG("doesObsoleteCapability " << candidate << ", " << cap);
-
-    Dep dep (Dep::OBSOLETES);
-    FindObsoletes info;
-    invokeOnEach( _pool.byCapabilityIndexBegin( cap.index(), dep ),
-                 _pool.byCapabilityIndexEnd( cap.index(), dep ),
-                 resfilter::ByCapMatch( cap ),
-                 functor::functorRef<bool,CapAndItem>(info) );
-
-    _DEBUG((info.obsoletes ? "YES" : "NO"));
-    return info.obsoletes;
-}
-
-
 bool
 Resolver::doesObsoleteItem (PoolItem candidate, PoolItem installed)
 {
-    Capability installedCap( installed->name(), Rel::EQ, installed->edition(), installed->kind());
-    return doesObsoleteCapability (candidate, installedCap);
+    return _satResolver->doesObsoleteItem (candidate, installed);
 }
 
 //-----------------------------------------------------------------------------
 
-// find best available providers for installed name
-
-typedef map<string, PoolItem> FindMap;
-
-struct FindProviders
-{
-    FindMap providers;         // the best providers which matched
-    PoolItem forItem;
-    bool otherVendorFound;
-    FindProviders (PoolItem item)
-       :forItem(item),
-        otherVendorFound(false)
-    { }
-
-    bool operator()( const CapAndItem & cai )
-    {
-       PoolItem provider( cai.item );
-       if ( !VendorAttr::instance().equivalent(provider->vendor(), forItem->vendor()) )
-       {
-           MIL << "Discarding '" << provider << "' from vendor '"
-               << provider->vendor() << "' different to uninstalled '"
-               << forItem->vendor() << "' vendor." << endl;
-           otherVendorFound = true;
-       } else if ( provider.status().isToBeUninstalled() ) {
-           MIL << "  IGNORE relation match (package is tagged to delete): " << cai.cap << " ==> " << provider << endl;
-       }
-       else {
-           FindMap::iterator it = providers.find( provider->name() );
-
-           if (it != providers.end()) {                                // provider with same name found
-               if (provider.status().isToBeInstalled()
-                   || it->second.status().isToBeInstalled()) {
-
-                   if (provider.status().isToBeInstalled()
-                       && it->second.status().isToBeInstalled()) {
-                       ERR << "only one should be set for installation: " << it->second << "; " << provider << endl;
-                   } else {
-                       if (provider.status().isToBeInstalled()) {
-                           it->second = provider; // take thatone which is already set for installation
-                       }
-                   }
-               } else {
-                   // not the same --> find better provider
-                   int cmp = it->second->arch().compare( provider->arch() );
-                   if (cmp < 0) {                                              // new provider has better arch
-                       it->second = provider;
-                   }
-                   else if (cmp == 0) {                                        // new provider has equal arch
-                       if (it->second->edition().compare( provider->edition() ) < 0) {
-                           it->second = provider;                              // new provider has better edition
-                       }
-                   }
-               }
-           }
-           else {
-               providers[provider->name()] = provider;
-           }
-       }
-       return true;
-    }
-};
-
 
 //-----------------------------------------------------------------------------
 
@@ -313,6 +215,8 @@ Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
   TodoMap     addProvided;
   TodoMap     addMultiProvided;
 
+  sat::Pool::instance().prepare();  
+
   Target_Ptr target;
   try {
        target = getZYpp()->target();
@@ -524,30 +428,70 @@ Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
       // If unique provides exists check if obsoleted (replaced).
       // Remember new package for 2nd pass.
 
-      Dep dep (Dep::PROVIDES);
       Capability installedCap( installed->name(), Rel::EQ, installed->edition(), installed->kind());
+      // find ALL providers
+      PoolItemList possibleProviders = _satResolver->whoProvides (installedCap);
+
+      // find best available providers for installed name
+      typedef map<string, PoolItem> FindMap;
+      FindMap providersMap;            // the best providers which matched
+      bool otherVendorFound = false;
+      for (PoolItemList::const_iterator iter = possibleProviders.begin(); iter != possibleProviders.end(); iter++) {
+         PoolItem provider = *iter;
+         if ( !VendorAttr::instance().equivalent(provider->vendor(), installed->vendor()) )
+         {
+             MIL << "Discarding '" << provider << "' from vendor '"
+                 << provider->vendor() << "' different to uninstalled '"
+                 << installed->vendor() << "' vendor." << endl;
+             otherVendorFound = true;
+         } else if ( provider.status().isToBeUninstalled() ) {
+             MIL << "  IGNORE relation match (package is tagged to delete): " << provider << endl;
+         }
+         else {
+             FindMap::iterator it = providersMap.find( provider->name() );
+
+             if (it != providersMap.end()) {                           // provider with same name found
+                 if (provider.status().isToBeInstalled()
+                     || it->second.status().isToBeInstalled()) {
+
+                     if (provider.status().isToBeInstalled()
+                         && it->second.status().isToBeInstalled()) {
+                         ERR << "only one should be set for installation: " << it->second << "; " << provider << endl;
+                     } else {
+                         if (provider.status().isToBeInstalled()) {
+                             it->second = provider; // take thatone which is already set for installation
+                         }
+                     }
+                 } else {
+                     // not the same --> find better provider
+                     int cmp = it->second->arch().compare( provider->arch() );
+                     if (cmp < 0) {                                            // new provider has better arch
+                         it->second = provider;
+                     }
+                     else if (cmp == 0) {                                      // new provider has equal arch
+                         if (it->second->edition().compare( provider->edition() ) < 0) {
+                             it->second = provider;                            // new provider has better edition
+                         }
+                     }
+                 }
+             }
+             else {
+                 providersMap[provider->name()] = provider;
+             }
+         }
+      }
 
-      FindProviders info(installed);
-
-      invokeOnEach( _pool.byCapabilityIndexBegin( installed->name(), dep ),
-                   _pool.byCapabilityIndexEnd( installed->name(), dep ),
-                   functor::chain( resfilter::ByCaIUninstalled(),
-                                   resfilter::ByCapMatch( installedCap ) ) ,
-                   functor::functorRef<bool,CapAndItem>(info) );
-
-      int num_providers = info.providers.size();
-
-      _DEBUG("lookup " << num_providers << " provides for installed " << installedCap);
+      _DEBUG("lookup " << providersMap.size() << " provides for installed " << installedCap);
 
       // copy from map to set
       PoolItemOrderSet providers;
-      for (FindMap::const_iterator mapit = info.providers.begin(); mapit != info.providers.end(); ++mapit) {
+      for (FindMap::const_iterator mapit = providersMap.begin(); mapit != providersMap.end(); ++mapit) {
        providers.insert( mapit->second );
       }
 
-      switch ( info.providers.size() ) {
+      switch ( providersMap.size() ) {
       case 0:
-         if (info.otherVendorFound) {
+         if (otherVendorFound) {
              MIL << " only resolvable with other vendor found ==> do nothing" << endl;
          } else {
              MIL << " ==> (dropped)" << endl;