///////////////////////////////////////////////////////////////////
typedef PoolItem_Ref PoolItem;
- typedef std::list<PoolItem> PoolItemList;
- typedef std::set<PoolItem> PoolItemSet;
/** \relates PoolItem_Ref Stream output */
std::ostream & operator<<( std::ostream & str, const PoolItem_Ref & obj );
#include "zypp/Pathname.h"
#include "zypp/ResPool.h"
-#include "zypp/solver/detail/Types.h"
-
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
public:
typedef target::TargetImpl Impl;
typedef intrusive_ptr<Impl> Impl_Ptr;
+ typedef std::list<PoolItem_Ref> PoolItemList;
public:
using namespace std;
using namespace zypp;
+#define ITEMNAME(item) (item)->name()
//-----------------------------------------------------------------------------
-InstallOrder::InstallOrder(const ResPool & pool, const PoolItemList & toinstall, const PoolItemList & installed)
- : _pool (pool)
- , _toinstall (toinstall.begin(), toinstall.end())
- , _installed (installed.begin(), installed.end())
+InstallOrder::InstallOrder( const PoolItemSet & toinstall, const PoolItemSet & installed )
+ : _toinstall( toinstall )
+ , _installed( installed )
, _dirty (true)
, _numrun (0)
{
{
Nodes::const_iterator niit = _nodes.find(gcit->first);
int order = niit->second.order;
- string name = gcit->first.resolvable()->name();
+ string name = gcit->first->name();
os << "\"" << name << "\"" << "[label=\"" << name << "\\n" << order << "\"";
os << "] " << endl;
- for (PoolItemSet::const_iterator scit = gcit->second.begin(); scit != gcit->second.end(); ++scit)
+ for (PoolItemList::const_iterator scit = gcit->second.begin(); scit != gcit->second.end(); ++scit)
{
- os << "\"" << name << "\" -> \"" << (*scit).resolvable()->name() << "\"" << endl;
+ os << "\"" << name << "\" -> \"" << (*scit)->name() << "\"" << endl;
}
}
os << "}" << endl;
if (it->second.order == 0
&& it->second.item) // the default Nodes constructor leaves this empty
{
- DBG << "InstallOrder::computeNextSet found " << it->second.item << endl;
+ DBG << "InstallOrder::computeNextSet found " << ITEMNAME(it->second.item) << endl;
newlist.push_back(it->second.item);
}
{
_dirty = true;
- PoolItemSet adj = _rgraph[item];
+ PoolItemList adj = _rgraph[item];
DBG << "InstallOrder::setInstalled " << item << endl;
// order will be < 0
_nodes[item].order--;
- _installed.insert (item);
- _toinstall.erase (item);
+ _installed.insert( item );
+ _toinstall.erase( item );
- for (PoolItemSet::iterator it = adj.begin(); it != adj.end(); ++it)
+ for (PoolItemList::iterator it = adj.begin(); it != adj.end(); ++it)
{
NodeInfo& info = _nodes[*it];
info.order--;
//-----------------------------------------------------------------------------
-
-void
-InstallOrder::startrdfs()
+bool
+InstallOrder::doesProvide( const Capability requirement, PoolItem_Ref item ) const
{
- _nodes.clear();
- _rgraph.clear();
- _graph.clear();
-
- _rdfstime = 1;
-
- _topsorted.clear();
-
- _numrun++;
- DBG << "run #" << _numrun << endl;
-
- // initialize all nodes
- for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
- {
- PoolItem_Ref item = *it;
- _nodes[item] = NodeInfo (item);
- _rgraph[item] = PoolItemSet();
- _graph[item] = PoolItemSet();
- }
-
- // visit all nodes
- for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
- {
- const PoolItem_Ref item = *it;
- if (_nodes[item].visited == false)
- {
- DBG << "start recursion on " << item << endl;
- rdfsvisit (item);
+ CapSet::const_iterator pend = item->dep( Dep::PROVIDES ).end();
+ for( CapSet::const_iterator pit = item->dep( Dep::PROVIDES ).begin(); pit != pend; ++pit) {
+ if( pit->matches( requirement ) == CapMatch::yes ) {
+ return item;
}
}
-
- _dirty = false;
+ return PoolItem_Ref();
}
-
-
-struct CollectProviders : public resfilter::OnCapMatchCallbackFunctor
+PoolItem_Ref
+InstallOrder::findProviderInSet( const Capability requirement, const PoolItemSet & candidates ) const
{
- const PoolItem_Ref requestor;
- PoolItemSet & tovisit;
- PoolItemSet & toinstall;
- PoolItemSet & installed;
-
- CollectProviders (const PoolItem_Ref pi, PoolItemSet & tv, PoolItemSet & ti, PoolItemSet i)
- : requestor (pi)
- , tovisit (tv)
- , toinstall (ti)
- , installed (i)
- { }
-
-
- bool operator()( PoolItem_Ref provider, const Capability & match )
- {
- // 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
- //
-
- if ((provider.resolvable() != requestor.resolvable()) // resolvable could provide its own requirement
- && (!provider.status().staysInstalled()) // only visit if provider is not already installed
- && (toinstall.find(provider) != toinstall.end() // only look at resolvables
- || installed.find(provider) != installed.end())) { // we are currently considering anyways
- tovisit.insert (provider);
+ for( PoolItemSet::const_iterator citer = candidates.begin(); citer != candidates.end(); citer++) {
+ if( doesProvide( requirement, *citer ) ) {
+ return *citer;
}
-
- return true;
}
-};
+ return PoolItem_Ref();
+}
+
+//-----------------------------------------------------------------------------
void
-InstallOrder::rdfsvisit (const PoolItem_Ref item)
+InstallOrder::rdfsvisit (const PoolItem_Ref item)
{
typedef list<Capability> CapList;
CapList requires;
- DBG << "InstallOrder::rdfsvisit, visiting " << item << endl;
+ DBG << "InstallOrder::rdfsvisit, visiting " << ITEMNAME(item) << endl;
NodeInfo& nodeinfo = _nodes[item];
for (CapList::const_iterator iter = requires.begin(); iter != requires.end(); ++iter)
{
const Capability requirement = *iter;
- XXX << "check requirement " << requirement << " of " << item << endl;
- PoolItemSet tovisit;
+ XXX << "check requirement " << requirement << " of " << ITEMNAME(item) << endl;
+ PoolItemList tovisit;
- CollectProviders info ( item, tovisit, _toinstall, _installed );
-
-
- // _world->foreachProvidingResItem (requirement, collect_providers, &info);
#if 0
+ // _world->foreachProvidingResItem (requirement, collect_providers, &info);
Dep dep (Dep::PROVIDES);
invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
_pool.byCapabilityIndexEnd( requirement.index(), dep ),
resfilter::callOnCapMatchIn( dep, requirement, functor::functorRef<bool,PoolItem,Capability>(info) ) );
#endif
+#if 0
+ CollectProviders info ( item, tovisit, _toinstall, _installed );
+
ResPool::const_indexiterator pend = _pool.providesend(requirement.index());
for (ResPool::const_indexiterator it = _pool.providesbegin(requirement.index()); it != pend; ++it) {
if (it->second.second->arch() == Arch_src)
break;
}
}
+#endif
+ // item could provide its own requirement
+ if( doesProvide( requirement, item ) ) {
+ XXX << "self-provides " << endl;
+// tovisit.push_back(node);
+ }
+ else {
+ PoolItem_Ref provider = findProviderInSet( requirement, _installed );
+
+ if (!provider)
+ {
+ provider = findProviderInSet( requirement, _toinstall );
+ if (provider) {
+ XXX << "provided by " << ITEMNAME(provider) << endl;
+ tovisit.push_back( provider );
+ }
+ }
+ }
- for (PoolItemSet::iterator it = tovisit.begin(); it != tovisit.end(); ++it)
+ for (PoolItemList::iterator it = tovisit.begin(); it != tovisit.end(); ++it)
{
const PoolItem_Ref must_visit = *it;
if (_nodes[must_visit].visited == false)
{
nodeinfo.order++;
- _rgraph[must_visit].insert (item);
- _graph[item].insert (must_visit);
- rdfsvisit(must_visit);
+ _rgraph[must_visit].push_back( item );
+ _graph[item].push_back( must_visit );
+ rdfsvisit( must_visit );
}
else if (_nodes[must_visit].endtime == 0)
{
if (must_visit != item)
{
ERR << "*************************************************************" << endl;
- ERR << "** dependency loop: " << item << " -> " << must_visit << endl;
+ ERR << "** dependency loop: " << ITEMNAME(item) << " -> " << ITEMNAME(must_visit) << endl;
ERR << "*************************************************************" << endl;
}
}
else
{
// filter multiple depends on same item (cosmetic)
- PoolItemSet & lrg = _rgraph[must_visit];
- if (lrg.find(item) == lrg.end())
+ PoolItemList & lrg = _rgraph[must_visit];
+ if( find( lrg.begin(), lrg.end(), item) == lrg.end() )
{
nodeinfo.order++;
- lrg.insert(item);
+ lrg.push_back( item );
- PoolItemSet & lg = _graph[item];
- if (lg.find (must_visit) == lg.end())
- lg.insert (must_visit);
+ PoolItemList & lg = _graph[item];
+ if( find( lg.begin(), lg.end(), must_visit ) == lg.end() )
+ lg.push_back( must_visit );
}
}
}
_nodes[item].endtime = _rdfstime;
_rdfstime++;
- DBG << item << " done" << endl;
+ DBG << ITEMNAME(item) << " done" << endl;
+}
+
+
+void
+InstallOrder::startrdfs()
+{
+ _nodes.clear();
+ _rgraph.clear();
+ _graph.clear();
+
+ _rdfstime = 1;
+
+ _topsorted.clear();
+
+ _numrun++;
+ DBG << "run #" << _numrun << endl;
+
+ // initialize all nodes
+ for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
+ {
+ PoolItem_Ref item = *it;
+ _nodes[item] = NodeInfo (item);
+ _rgraph[item] = PoolItemList();
+ _graph[item] = PoolItemList();
+ }
+
+ // visit all nodes
+ for (PoolItemSet::iterator it = _toinstall.begin(); it != _toinstall.end(); ++it)
+ {
+ const PoolItem_Ref item = *it;
+ if (_nodes[item].visited == false)
+ {
+ DBG << "start recursion on " << ITEMNAME(item) << endl;
+ rdfsvisit (item);
+ }
+ }
+
+ _dirty = false;
}
#ifndef ZYPP_SOLVER_DETAIL_INSTALLORDER_H
#define ZYPP_SOLVER_DETAIL_INSTALLORDER_H
+#include <list>
+#include <map>
+
#include "zypp/PoolItem.h"
#include "zypp/ResPool.h"
#include "zypp/CapSet.h"
class InstallOrder
{
private:
- ResPool _pool;
-
PoolItemSet _toinstall;
PoolItemSet _installed;
/** adjacency list type */
- typedef std::map<PoolItem_Ref, PoolItemSet> Graph;
+ typedef std::map<PoolItem_Ref, PoolItemList> Graph;
/** adjacency list, package -> requirements */
Graph _graph;
private:
void rdfsvisit (PoolItem_Ref item);
+ PoolItem_Ref findProviderInSet( const Capability requirement, const PoolItemSet & candidates ) const;
+ bool doesProvide( const Capability requirement, PoolItem_Ref item ) const;
+
public:
/**
* @param toinstall Set of ResItems that have to be installed
* @param installed Set of ResItems that are already installed
* */
- InstallOrder (const ResPool & pool, const PoolItemList & toinstall, const PoolItemList & installed);
+ InstallOrder( const PoolItemSet & toinstall, const PoolItemSet & installed);
/**
* Compute a list of ResItems which have no requirements and can be
/////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
+
+typedef std::list<PoolItem_Ref> PoolItemList;
+typedef std::set<PoolItem_Ref> PoolItemSet;
DEFINE_PTR_TYPE(Resolver);
#include "zypp/target/TargetImpl.h"
#include "zypp/target/TargetCallbackReceiver.h"
-#include "zypp/solver/detail/Types.h"
#include "zypp/solver/detail/InstallOrder.h"
using namespace std;
}
- int TargetImpl::commit(ResPool pool_r, unsigned int medianr, PoolItemList & errors_r, PoolItemList & remaining_r, PoolItemList & srcremaining_r)
+ int TargetImpl::commit(ResPool pool_r, unsigned int medianr, TargetImpl::PoolItemList & errors_r, TargetImpl::PoolItemList & remaining_r, TargetImpl::PoolItemList & srcremaining_r)
{
MIL << "TargetImpl::commit(<pool>, " << medianr << ")" << endl;
remaining_r.clear();
srcremaining_r.clear();
- PoolItemList to_uninstall;
- PoolItemList to_install;
- PoolItemList to_srcinstall;
+ TargetImpl::PoolItemList to_uninstall;
+ TargetImpl::PoolItemList to_install;
+ TargetImpl::PoolItemList to_srcinstall;
getResolvablesToInsDel( pool_r, to_uninstall, to_install, to_srcinstall );
if ( medianr ) {
}
else
{
- PoolItemList current_install;
- PoolItemList current_srcinstall;
+ TargetImpl::PoolItemList current_install;
+ TargetImpl::PoolItemList current_srcinstall;
- for (PoolItemList::iterator it = to_install.begin(); it != to_install.end(); ++it)
+ for (TargetImpl::PoolItemList::iterator it = to_install.begin(); it != to_install.end(); ++it)
{
Resolvable::constPtr res( it->resolvable() );
Package::constPtr pkg( asKind<Package>(res) );
current_install.push_back( *it );
}
}
- PoolItemList bad = commit (current_install);
+ TargetImpl::PoolItemList bad = commit (current_install);
remaining_r.insert(remaining_r.end(), bad.begin(), bad.end());
- for (PoolItemList::iterator it = to_srcinstall.begin(); it != to_srcinstall.end(); ++it)
+ for (TargetImpl::PoolItemList::iterator it = to_srcinstall.begin(); it != to_srcinstall.end(); ++it)
{
Resolvable::constPtr res( it->resolvable() );
Package::constPtr pkg( asKind<Package>(res) );
}
- PoolItemList
- TargetImpl::commit( const PoolItemList & items_r)
+ TargetImpl::PoolItemList
+ TargetImpl::commit( const TargetImpl::PoolItemList & items_r)
{
- PoolItemList remaining;
+ TargetImpl::PoolItemList remaining;
MIL << "TargetImpl::commit(<list>)" << endl;
- for (PoolItemList::const_iterator it = items_r.begin(); it != items_r.end(); it++)
+ for (TargetImpl::PoolItemList::const_iterator it = items_r.begin(); it != items_r.end(); it++)
{
if (isKind<Package>(it->resolvable()))
{
** obsoleting package likes to save whatever...
*/
static void
-strip_obsoleted_to_delete( PoolItemList & deleteList_r,
- const PoolItemList & instlist_r )
+strip_obsoleted_to_delete( TargetImpl::PoolItemList & deleteList_r,
+ const TargetImpl::PoolItemList & instlist_r )
{
if ( deleteList_r.size() == 0 || instlist_r.size() == 0 )
return; // ---> nothing to do
// build obsoletes from instlist_r
CapSet obsoletes;
- for ( PoolItemList::const_iterator it = instlist_r.begin();
+ for ( TargetImpl::PoolItemList::const_iterator it = instlist_r.begin();
it != instlist_r.end(); ++it )
{
PoolItem_Ref item( *it );
return; // ---> nothing to do
// match them... ;(
- PoolItemList undelayed;
+ TargetImpl::PoolItemList undelayed;
// forall applDelete Packages...
- for ( PoolItemList::iterator it = deleteList_r.begin();
+ for ( TargetImpl::PoolItemList::iterator it = deleteList_r.begin();
it != deleteList_r.end(); ++it )
{
PoolItem_Ref ipkg( *it );
void
TargetImpl::getResolvablesToInsDel ( const ResPool pool_r,
- PoolItemList & dellist_r,
- PoolItemList & instlist_r,
- PoolItemList & srclist_r ) const
+ TargetImpl::PoolItemList & dellist_r,
+ TargetImpl::PoolItemList & instlist_r,
+ TargetImpl::PoolItemList & srclist_r ) const
{
dellist_r.clear();
instlist_r.clear();
srclist_r.clear();
- PoolItemList nonpkglist;
+ TargetImpl::PoolItemList nonpkglist;
for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
{
// sort delete list...
//
///////////////////////////////////////////////////////////////////
- PoolItemList dlist; // for delete order
- PoolItemList dummy; // dummy, empty, should contain already installed
- for ( PoolItemList::iterator pkgIt = dellist_r.begin();
+ TargetImpl::PoolItemSet delset; // for delete order
+ TargetImpl::PoolItemSet dummy; // dummy, empty, should contain already installed
+ for ( TargetImpl::PoolItemList::iterator pkgIt = dellist_r.begin();
pkgIt != dellist_r.end(); ++pkgIt )
{
- dlist.push_back( *pkgIt );
+ delset.insert( *pkgIt );
}
- InstallOrder order( pool_r, dlist, dummy ); // sort according top prereq
+ InstallOrder order( delset, dummy ); // sort according top prereq
order.init();
- const PoolItemList dsorted( order.getTopSorted() );
+ const TargetImpl::PoolItemList dsorted( order.getTopSorted() );
dellist_r.clear();
- for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
+ for ( TargetImpl::PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
cit != dsorted.rend(); ++cit )
{
dellist_r.push_back( *cit );
///////////////////////////////////////////////////////////////////
// backup list for debug purpose.
// You can as well build the set, clear the list and rebuild it in install order.
- PoolItemList instbackup_r;
+ TargetImpl::PoolItemList instbackup_r;
instbackup_r.swap( instlist_r );
- PoolItemList ilist; // for install order
- PoolItemList installed; // dummy, empty, should contain already installed
- for ( PoolItemList::iterator resIt = instbackup_r.begin(); resIt != instbackup_r.end(); ++resIt ) {
- ilist.push_back( *resIt );
+ TargetImpl::PoolItemSet insset; // for install order
+ TargetImpl::PoolItemSet installed; // dummy, empty, should contain already installed
+ for ( TargetImpl::PoolItemList::iterator resIt = instbackup_r.begin(); resIt != instbackup_r.end(); ++resIt ) {
+ insset.insert( *resIt );
}
- InstallOrder order( pool_r, ilist, installed );
+ InstallOrder order( insset, installed );
// start recursive depth-first-search
order.init();
MIL << "order.init() done" << endl;
+ order.printAdj( cerr, false );
///////////////////////////////////////////////////////////////////
// build install list in install order
///////////////////////////////////////////////////////////////////
- PoolItemList best_list;
+ TargetImpl::PoolItemList best_list;
// unsigned best_prio = 0;
unsigned best_medianum = 0;
- PoolItemList last_list;
+ TargetImpl::PoolItemList last_list;
// unsigned last_prio = 0;
unsigned last_medianum = 0;
- PoolItemList other_list;
+ TargetImpl::PoolItemList other_list;
- for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
+ for ( TargetImpl::PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
{
MIL << "order.computeNextSet: " << items.size() << " resolvables" << endl;
///////////////////////////////////////////////////////////////////
last_list.clear();
other_list.clear();
- for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
+ for ( TargetImpl::PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
{
Resolvable::constPtr res( cit->resolvable() );
if (!res) continue;
// remove packages picked from install order and append them to
// install list.
///////////////////////////////////////////////////////////////////
- PoolItemList & take_list( last_list.empty() ? best_list : last_list );
+ TargetImpl::PoolItemList & take_list( last_list.empty() ? best_list : last_list );
if ( last_list.empty() )
{
MIL << "SET NEW media " << best_medianum << endl;
MIL << "SET CONTINUE" << endl;
}
- for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
+ for ( TargetImpl::PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
{
order.setInstalled( *it );
- MIL << "SET isrc " << (*it) << endl;
+ MIL << "SET isrc " << (*it)->name() << endl;
}
// move everthing from take_list to the end of instlist_r, clean take_list
instlist_r.splice( instlist_r.end(), take_list );
if ( instbackup_r.size() != instlist_r.size() )
{
- INT << "Lost packages in InstallOrder sort." << endl;
+ ERR << "***************** Lost packages in InstallOrder sort." << endl;
}
instlist_r.splice( instlist_r.end(), nonpkglist );
}
#define ZYPP_TARGET_TARGETIMPL_H
#include <iosfwd>
+#include <list>
+#include <set>
#include "zypp/base/ReferenceCounted.h"
#include "zypp/base/NonCopyable.h"
#include "zypp/base/PtrTypes.h"
#include "zypp/ResStore.h"
+#include "zypp/PoolItem.h"
#include "zypp/Pathname.h"
#include "zypp/media/MediaAccess.h"
#include "zypp/Target.h"
#include "zypp/target/rpm/RpmDb.h"
#include "zypp/target/store/PersistentStorage.h"
-#include "zypp/solver/detail/Types.h"
///////////////////////////////////////////////////////////////////
namespace zypp
friend std::ostream & operator<<( std::ostream & str, const TargetImpl & obj );
public:
+ /** list of pool items */
+ typedef std::list<PoolItem_Ref> PoolItemList;
+
+ /** set of pool items */
+ typedef std::set<PoolItem_Ref> PoolItemSet;
+
+ public:
/** JUST FOR TESTSUITE */
/** Sort according to prereqs and media numbers */
void getResolvablesToInsDel ( const ResPool pool_r,