- Take into account the requirements of all obsoleted packages uninstall
[platform/upstream/libzypp.git] / zypp / solver / detail / InstallOrder.cc
index 78095e1..68925f2 100644 (file)
 #include "zypp/base/Iterator.h"
 #include "zypp/base/Algorithm.h"
 
+#include "zypp/solver/detail/SATResolver.h"
+
 #include "zypp/ResFilters.h"
 #include "zypp/ResStatus.h"
-#include "zypp/CapAndItem.h"
 #include "zypp/NameKindProxy.h"
+#include "zypp/sat/Pool.h"
+#include <zypp/sat/WhatObsoletes.h>
 
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -102,9 +105,6 @@ InstallOrder::computeNextSet()
        if (it->second.order == 0
            && it->second.item)                 // the default Nodes constructor leaves this empty
        {
-           if (isKind<SystemResObject>( it->second.item.resolvable() ))
-               continue;
-
            XXX << "InstallOrder::computeNextSet found " << ITEMNAME(it->second.item) << endl;
 
            newlist.push_back(it->second.item);
@@ -117,7 +117,7 @@ InstallOrder::computeNextSet()
 
 // decrease order of every adjacent node
 void
-InstallOrder::setInstalled(PoolItem_Ref item )
+InstallOrder::setInstalled(PoolItem item )
 {
     _dirty = true;
 
@@ -154,19 +154,19 @@ InstallOrder::setInstalled( const PoolItemList & rl )
 //-----------------------------------------------------------------------------
 
 bool
-InstallOrder::doesProvide( const Capability requirement, PoolItem_Ref item ) const
+InstallOrder::doesProvide( const Capability requirement, PoolItem item ) const
 {
-    CapSet::const_iterator pend = item->dep( Dep::PROVIDES ).end();
-    for( CapSet::const_iterator pit = item->dep( Dep::PROVIDES ).begin(); pit != pend; ++pit) {
+    Capabilities::const_iterator pend = item->dep( Dep::PROVIDES ).end();
+    for( Capabilities::const_iterator pit = item->dep( Dep::PROVIDES ).begin(); pit != pend; ++pit) {
        if( pit->matches( requirement ) == CapMatch::yes ) {
            return item;
        }
     }
-    return PoolItem_Ref();
+    return PoolItem();
 }
 
 
-PoolItem_Ref
+PoolItem
 InstallOrder::findProviderInSet( const Capability requirement, const PoolItemSet & candidates ) const
 {
     for( PoolItemSet::const_iterator citer = candidates.begin(); citer != candidates.end(); citer++) {
@@ -175,45 +175,14 @@ InstallOrder::findProviderInSet( const Capability requirement, const PoolItemSet
        }
     }
 
-    return PoolItem_Ref();
+    return PoolItem();
 }
 
-struct CollectProviders
-{
-    const PoolItem_Ref requestor;
-    PoolItemList result;
-    const PoolItemSet & limitto;               // limit search to members of this set
-
-    CollectProviders (const PoolItem_Ref pi, const PoolItemSet & limit)
-       : requestor (pi)
-       , limitto (limit)
-    { }
-
-
-    bool operator()( const CapAndItem & c_and_i )
-    {
-       // item provides cap which matches a requirement from info->requestor
-       //   this function gets _all_ providers and filter out those which are
-       //   either installed or in our toinstall input list
-       //
-XXX << "info(" << c_and_i.item <<")"<< endl;
-       if ((c_and_i.item.resolvable() != requestor.resolvable())       // resolvable could provide its own requirement
-           && (limitto.find( c_and_i.item ) != limitto.end()))         // limit to members of 'limitto' set
-       {
-           XXX << "tovisit " << ITEMNAME(c_and_i.item) << endl;
-           result.push_back (c_and_i.item);
-       }
-
-       return true;
-    }
-
-};
-
 //-----------------------------------------------------------------------------
 
 
 void
-InstallOrder::rdfsvisit (const PoolItem_Ref item)
+InstallOrder::rdfsvisit (const PoolItem item)
 {
     typedef list<Capability> CapList;
     CapList requires;
@@ -227,17 +196,17 @@ InstallOrder::rdfsvisit (const PoolItem_Ref item)
     _rdfstime++;
 
     // items prereq
-    CapSet prq( item->dep(Dep::PREREQUIRES) );
-    // an installed items prereq (in case they are reqired for uninstall scripts)
-    NameKindProxy nkp( _pool, item->name(), item->kind() );
-    if ( ! nkp.installedEmpty() )
+    CapabilitySet prq( item->dep(Dep::PREREQUIRES).begin(), item->dep(Dep::PREREQUIRES).end() );
+    // any obsoleted items prereq (in case they are reqired for uninstall scripts)
+    sat::WhatObsoletes obs( item );
+    for_( it, obs.begin(), obs.end() )
     {
-      prq.insert( (*nkp.installedBegin())->dep(Dep::PREREQUIRES).begin(),
-                 (*nkp.installedBegin())->dep(Dep::PREREQUIRES).end() );
+      Capabilities p( it->prerequires() );
+      prq.insert( p.begin(), p.end() );
     }
     // put prerequires first and requires last on list to ensure
     // that prerequires are processed first
-    for (CapSet::const_iterator it = prq.begin(); it != prq.end(); ++it)
+    for (CapabilitySet::const_iterator it = prq.begin(); it != prq.end(); ++it)
     {
        requires.push_back(*it);
     }
@@ -246,7 +215,7 @@ InstallOrder::rdfsvisit (const PoolItem_Ref item)
     // as early as possible. Some stuff depends on it (e.g. registration).
     if ( ! isKind<Product>( item.resolvable() ) )
       {
-        for (CapSet::const_iterator it = item->dep (Dep::REQUIRES).begin(); it != item->dep (Dep::REQUIRES).end(); ++it)
+        for (Capabilities::const_iterator it = item->dep (Dep::REQUIRES).begin(); it != item->dep (Dep::REQUIRES).end(); ++it)
           {
             requires.push_back(*it);
           }
@@ -254,37 +223,50 @@ InstallOrder::rdfsvisit (const PoolItem_Ref item)
 
     for (CapList::const_iterator iter = requires.begin(); iter != requires.end(); ++iter)
     {
+        bool goBack = false;
        const Capability requirement = *iter;
+        PoolItemList providers;
+
        XXX << "check requirement " << requirement << " of " << ITEMNAME(item) << endl;
+        SATResolver satResolver(_pool, sat::Pool::instance().get());
        PoolItemList tovisit;
-
-       // _world->foreachProvidingResItem (requirement, collect_providers, &info);
-       Dep dep (Dep::PROVIDES);
+        sat::WhatProvides possibleProviders(requirement);
 
        // first, look in _installed
-       CollectProviders info ( item, _installed );
-
-       invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
-                     _pool.byCapabilityIndexEnd( requirement.index(), dep ),
-                     resfilter::ByCapMatch( requirement ),
-                     functor::functorRef<bool,CapAndItem>(info) );
-
-       // if not found in _iustalled, look in _toinstall
-
-       if (info.result.empty()) {
-           CollectProviders info1 ( item, _toinstall );
-
-           invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
-                         _pool.byCapabilityIndexEnd( requirement.index(), dep ),
-                         resfilter::ByCapMatch( requirement ),
-                         functor::functorRef<bool,CapAndItem>(info1) );
-
-           tovisit = info1.result;
+        for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+            PoolItem provider = ResPool::instance().find( *iter );
+            if ( provider == item )
+            {
+              goBack = true;
+              break;
+            }
+            if (_installed.find( provider ) != _installed.end())       // and is not installed
+            {
+                XXX << "tovisit " << ITEMNAME(provider) << endl;
+                providers.push_back (provider);
+            }
+        }
+
+        if ( goBack )
+          continue;
+
+       // if not found in _installed, look in _toinstall
+
+       if (providers.empty()) {
+            for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+                PoolItem provider = ResPool::instance().find( *iter );
+                if ((provider.resolvable() != item.resolvable())               // resolvable could provide its own requirement
+                    && (_toinstall.find( provider ) != _toinstall.end()))      // and is not to be installed
+                {
+                    XXX << "tovisit " << ITEMNAME(provider) << endl;
+                    tovisit.push_back (provider);
+                }
+            }
        }
 
        for (PoolItemList::iterator it = tovisit.begin(); it != tovisit.end(); ++it)
        {
-           const PoolItem_Ref must_visit = *it;
+           const PoolItem must_visit = *it;
            if (_nodes[must_visit].visited == false)
            {
                nodeinfo.order++;
@@ -347,7 +329,7 @@ InstallOrder::startrdfs()
     // initialize all nodes
     for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
     {
-       PoolItem_Ref item = *it;
+       PoolItem item = *it;
        _nodes[item] = NodeInfo (item);
        _rgraph[item] = PoolItemList();
        _graph[item] = PoolItemList();
@@ -356,7 +338,7 @@ InstallOrder::startrdfs()
     // visit all nodes
     for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
     {
-       const PoolItem_Ref item = *it;
+       const PoolItem item = *it;
        if (_nodes[item].visited == false)
        {
            XXX << "start recursion on " << ITEMNAME(item) << endl;