// whatdependson
-struct RequiringPoolItem : public resfilter::OnCapMatchCallbackFunctor
+struct RequiringPoolItem
{
PoolItemSet itemset;
PoolItem_Ref provider;
: provider (p)
{ }
- bool operator()( PoolItem_Ref requirer, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
+ PoolItem_Ref requirer( cai.item );
+ Capability cap( cai.cap );
if (itemset.insert (requirer).second) {
if (first) {
cout << "\t" << provider.resolvable() << " provides " << cap << " required by" << endl;
Dep dep( Dep::REQUIRES );
invokeOnEach( God->pool().byCapabilityIndexBegin( info.cap.index(), dep ),
God->pool().byCapabilityIndexEnd( info.cap.index(), dep ),
- resfilter::callOnCapMatchIn( dep, info.cap, functor::functorRef<bool,PoolItem,Capability>(info) ) );
+ resfilter::ByCapMatch( info.cap ),
+ functor::functorRef<bool,CapAndItem>(info) );
}
// whatprovides
-struct ProvidingPoolItem : public resfilter::OnCapMatchCallbackFunctor
+struct ProvidingPoolItem
{
PoolItemSet itemset;
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
- itemset.insert (provider);
+ itemset.insert( cai.item );
return true;
}
};
invokeOnEach( God->pool().byCapabilityIndexBegin( cap.index(), dep ),
God->pool().byCapabilityIndexEnd( cap.index(), dep ),
- resfilter::callOnCapMatchIn( dep, cap, functor::functorRef<bool,PoolItem,Capability>(info) ) );
+ resfilter::ByCapMatch( cap ),
+ functor::functorRef<bool,CapAndItem>(info) );
return info.itemset;
}
typedef pair<PoolItem_Ref,PoolItem_Ref> UpgradePair;
typedef map<string,UpgradePair > UpgradeMap;
-struct DoUpgrades : public resfilter::OnCapMatchCallbackFunctor, public resfilter::PoolItemFilterFunctor
+struct DoUpgrades : public resfilter::PoolItemFilterFunctor
{
PoolItem_Ref installed;
UpgradeMap upgrades;
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/CapAndItem.h
+ *
+*/
+#ifndef ZYPP_CAPANDITEM_H
+#define ZYPP_CAPANDITEM_H
+
+#include "zypp/PoolItem.h"
+#include "zypp/Capability.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : CapAndItem
+ //
+ /** */
+ struct CapAndItem
+ {
+ friend std::ostream & operator<<( std::ostream & str, const CapAndItem & obj );
+ public:
+ Capability cap;
+ PoolItem item;
+
+ CapAndItem( Capability c, PoolItem i )
+ : cap( c )
+ , item( i )
+ { }
+ };
+
+ /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_CAPANDITEM_H
#include "zypp/source/SourceImpl.h"
#include "zypp/PoolItem.h"
+#include "zypp/CapAndItem.h"
///////////////////////////////////////////////////////////////////
namespace zypp
{ return byEdition( edition_r, _Compare() ); }
- /** Select ResObject if at least one Capability with
- * index \a index_r was found in dependency \a depType_r.
- */
- struct ByCapabilityIndex : public ResObjectFilterFunctor
- {
- ByCapabilityIndex( const std::string & index_r, Dep depType_r )
- : _dep( depType_r )
- , _index( index_r )
- {}
- ByCapabilityIndex( const Capability & cap_r, Dep depType_r )
- : _dep( depType_r )
- , _index( cap_r.index() )
- {}
-
- bool operator()( ResObject::constPtr p ) const
- {
- using capfilter::ByIndex;
- return( make_filter_begin( ByIndex(_index), p->dep( _dep ) )
- != make_filter_end( ByIndex(_index), p->dep( _dep ) ) );
- }
-
- Dep _dep;
- std::string _index;
- };
-
-
-
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
- typedef std::binary_function<PoolItem,Capability,
- bool> OnCapMatchCallbackFunctor;
+ /** Select ResObject if at least one Capability with
+ * index \a index_r was found in dependency \a depType_r.
+ */
+ struct ByCapabilityIndex
+ {
+ bool operator()( const CapAndItem & cai ) const
+ {
+ return true; // its all in the PoolImpl !
+ }
+ };
- /** Find matching Capabilities in a ResObjects dependency and invoke a
- * callback on matches.
- *
- * Iterates through the PoolItem (in fact the ResObject it holds)
- * CapSet denoted by \a dep_r. For each Capability matching the
- * provided \a cap_r the callback functor \a fnc_r is called with
- * the PoolItem and the PoolItem's matching Capability.
- *
- * \returns \c true, unless an invokation of the callback functor
- * returned \c false.
- *
- * \todo Unfortunately a pure PoolItem Filter, but woud be usefull with
- * plain ResObjects too. But the Solver urgently needs the PoolItem in
- * the OnCapMatchCallback.
+
+ /** Select ResObject if at least one Capability with
+ * index \a index_r was found in dependency \a depType_r.
*/
- template<class _OnCapMatchCallback>
- struct CallOnCapMatchIn
+ struct ByCapMatch
+ {
+ bool operator()( const CapAndItem & cai ) const
{
- bool operator()( const PoolItem & p ) const
- {
- const CapSet & depSet( p->dep( _dep ) ); // dependency set in p to iterate
- capfilter::ByCapMatch matching( _cap ); // predicate: true if match with _cap
-
- int res
- = invokeOnEach( depSet.begin(), depSet.end(), // iterate this set
- matching, // Filter: if match
- std::bind1st(_fnc,p) ); // Action: invoke _fnc(p,match)
- // Maybe worth to note: Filter and Action are invoked with the same
- // iterator, thus Action will use the same capability that cause
- // the match in Filter.
- return ( res >= 0 );
- }
+ return cai.cap.matches( _cap ) == CapMatch::yes;
+ }
+ ByCapMatch( const Capability & cap_r )
+ : _cap( cap_r )
+ {}
+ const Capability & _cap;
+ };
- CallOnCapMatchIn( Dep dep_r, const Capability & cap_r,
- _OnCapMatchCallback fnc_r )
- : _dep( dep_r )
- , _cap( cap_r )
- , _fnc( fnc_r )
- {}
- Dep _dep;
- const Capability & _cap;
- _OnCapMatchCallback _fnc;
- };
- /** */
- template<class _OnCapMatchCallback>
- inline CallOnCapMatchIn<_OnCapMatchCallback>
- callOnCapMatchIn( Dep dep_r, const Capability & cap_r,
- _OnCapMatchCallback fnc_r )
+ /** Select PoolItem by uninstalled. */
+ struct ByCaIUninstalled
+ {
+ bool operator()( const CapAndItem & cai ) const
{
- return CallOnCapMatchIn<_OnCapMatchCallback>( dep_r, cap_r, fnc_r );
+ return cai.item.status().staysUninstalled();
}
+ };
+
+ /** Select PoolItem by transact. */
+ struct ByCaITransact
+ {
+ bool operator()( const CapAndItem & cai ) const
+ {
+ return cai.item.status().transacts();
+ }
+ };
+
///////////////////////////////////////////////////////////////////
ResPool::const_iterator ResPool::end() const
{ return _pimpl->end(); }
- ResPool::const_indexiterator ResPool::providesbegin(const std::string & tag_r) const
- { return _pimpl->providesbegin(tag_r); }
+ ResPool::byName_iterator ResPool::byNameBegin( const std::string & name_r ) const
+ { return make_filter_iterator( ByName( name_r ), _pimpl->_namehash.begin( name_r ), _pimpl->_namehash.end( name_r ) ); }
- ResPool::const_indexiterator ResPool::providesend(const std::string & tag_r) const
- { return _pimpl->providesend(tag_r); }
+ ResPool::byName_iterator ResPool::byNameEnd( const std::string & name_r ) const
+ { return make_filter_iterator( ByName( name_r ), _pimpl->_namehash.end( name_r ), _pimpl->_namehash.end( name_r ) ); }
- ResPool::const_indexiterator ResPool::requiresbegin(const std::string & tag_r) const
- { return _pimpl->requiresbegin(tag_r); }
+ ResPool::byCapabilityIndex_iterator ResPool::byCapabilityIndexBegin( const std::string & index_r, Dep depType_r ) const
+ { return make_filter_iterator( ByCapabilityIndex(), _pimpl->_caphash.begin( index_r, depType_r ), _pimpl->_caphash.end( index_r, depType_r ) ); }
- ResPool::const_indexiterator ResPool::requiresend(const std::string & tag_r) const
- { return _pimpl->requiresend(tag_r); }
-
- ResPool::const_indexiterator ResPool::conflictsbegin(const std::string & tag_r) const
- { return _pimpl->conflictsbegin(tag_r); }
-
- ResPool::const_indexiterator ResPool::conflictsend(const std::string & tag_r) const
- { return _pimpl->conflictsend(tag_r); }
-
- ResPool::const_nameiterator ResPool::namebegin(const std::string & tag_r) const
- { return _pimpl->namebegin(tag_r); }
-
- ResPool::const_nameiterator ResPool::nameend(const std::string & tag_r) const
- { return _pimpl->nameend(tag_r); }
+ ResPool::byCapabilityIndex_iterator ResPool::byCapabilityIndexEnd( const std::string & index_r, Dep depType_r ) const
+ { return make_filter_iterator( ByCapabilityIndex(), _pimpl->_caphash.end( index_r, depType_r ), _pimpl->_caphash.end( index_r, depType_r ) ); }
/******************************************************************
**
public:
/** \ref zypp::pool::PoolItem */
- typedef pool::PoolTraits::Item Item;
- typedef pool::PoolTraits::size_type size_type;
- typedef pool::PoolTraits::const_iterator const_iterator;
- typedef pool::PoolTraits::const_indexiterator const_indexiterator;
- typedef pool::PoolTraits::const_nameiterator const_nameiterator;
+ typedef pool::PoolTraits::Item Item;
+ typedef pool::PoolTraits::size_type size_type;
+ typedef pool::PoolTraits::const_iterator const_iterator;
+ typedef pool::PoolTraits::const_capitemiterator const_capitemiterator;
public:
/** Default ctor: empty pool */
const_iterator end() const;
//@}
- /** \name Iterate through all ResObjects which provide tag_r. */
- //@{
- /** */
- const_indexiterator providesbegin(const std::string & tag_r) const;
- /** */
- const_indexiterator providesend(const std::string & tar_r) const;
- //@}
-
- /** \name Iterate through all ResObjects which require tag_r. */
- //@{
- /** */
- const_indexiterator requiresbegin(const std::string & tag_r) const;
- /** */
- const_indexiterator requiresend(const std::string & tar_r) const;
- //@}
-
- /** \name Iterate through all ResObjects which conflict tag_r. */
- //@{
- /** */
- const_indexiterator conflictsbegin(const std::string & tag_r) const;
- /** */
- const_indexiterator conflictsend(const std::string & tar_r) const;
- //@}
-
- /** \name Iterate through all ResObjects with name tag_r. */
- //@{
- /** */
- const_nameiterator namebegin(const std::string & tag_r) const;
- /** */
- const_nameiterator nameend(const std::string & tar_r) const;
- //@}
-
public:
/** \name Iterate through all ResObjects of a certain kind. */
//@{
typedef resfilter::ByName ByName;
typedef filter_iterator<ByName,const_iterator> byName_iterator;
- byName_iterator byNameBegin( const std::string & name_r ) const
- { return make_filter_begin( ByName(name_r), *this ); }
+ byName_iterator byNameBegin( const std::string & name_r ) const;
- byName_iterator byNameEnd( const std::string & name_r ) const
- { return make_filter_end( ByName(name_r), *this ); }
+ byName_iterator byNameEnd( const std::string & name_r ) const;
//@}
public:
*/
//@{
typedef resfilter::ByCapabilityIndex ByCapabilityIndex;
- typedef filter_iterator<ByCapabilityIndex,const_iterator> byCapabilityIndex_iterator;
+ typedef filter_iterator<ByCapabilityIndex,const_capitemiterator> byCapabilityIndex_iterator;
- byCapabilityIndex_iterator byCapabilityIndexBegin( const std::string & index_r, Dep depType_r ) const
- { return make_filter_begin( ByCapabilityIndex(index_r,depType_r), *this ); }
+ byCapabilityIndex_iterator byCapabilityIndexBegin( const std::string & index_r, Dep depType_r ) const;
- byCapabilityIndex_iterator byCapabilityIndexEnd( const std::string & index_r, Dep depType_r ) const
- { return make_filter_end( ByCapabilityIndex(index_r,depType_r), *this ); }
+ byCapabilityIndex_iterator byCapabilityIndexEnd( const std::string & index_r, Dep depType_r ) const;
//@}
private:
private:
/** */
- typedef pool::PoolTraits::ContainerT ContainerT;
+ typedef pool::PoolTraits::ItemContainerT ContainerT;
typedef pool::PoolTraits::Impl Impl;
typedef pool::PoolTraits::Inserter Inserter;
typedef pool::PoolTraits::Deleter Deleter;
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
+
+ std::ostream & operator<<( std::ostream & str, const CapAndItem & obj )
+ {
+ return str << "{" << obj.cap << ", " << obj.item << "}";
+ }
+
///////////////////////////////////////////////////////////////////
namespace pool
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
+ // METHOD NAME : NameHash::NameHash
+ // METHOD TYPE : Ctor
+ //
+ NameHash::NameHash()
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : NameHash::~NameHash
+ // METHOD TYPE : Dtor
+ //
+ NameHash::~NameHash()
+ {}
+
+ void
+ NameHash::insert( const PoolItem & item_r )
+ {
+ _store[item_r->name()].insert( item_r );
+ }
+
+ void
+ NameHash::erase( const PoolItem & item_r )
+ {
+ PoolTraits::ItemContainerT items = _store[item_r->name()];
+ for (PoolTraits::iterator nit = items.begin();
+ nit != items.end(); ++nit)
+ {
+ if (*nit == item_r)
+ items.erase( nit );
+ }
+ }
+
+ NameHash::ItemContainerT & NameHash::getItemContainer( const std::string & tag_r )
+ { ContainerT::iterator it = _store.find( tag_r );
+ if (it == _store.end()) {
+XXX << "item container for " << tag_r << " not found" << endl;
+ return _empty;
+ }
+XXX << "item container for " << tag_r << " contains " << it->second.size() << " items" << endl;
+ return it->second;
+ }
+
+ const NameHash::ItemContainerT & NameHash::getConstItemContainer( const std::string & tag_r ) const
+ { ContainerT::const_iterator it = _store.find( tag_r );
+ if (it == _store.end()) {
+XXX << "const item container for " << tag_r << " not found" << endl;
+ return _empty;
+ }
+XXX << "const item container for " << tag_r << " contains " << it->second.size() << " items" << endl;
+ return it->second;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : CapHash::CapHash
+ // METHOD TYPE : Ctor
+ //
+ CapHash::CapHash()
+ {}
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // METHOD NAME : CapHash::~CapHash
+ // METHOD TYPE : Dtor
+ //
+ CapHash::~CapHash()
+ {}
+
+ static void
+ storeInsert( CapHash::ContainerT & store_r, const PoolItem & item_r, Dep cap_r )
+ {
+ CapSet caps = item_r->dep( cap_r );
+ for (CapSet::iterator ic = caps.begin(); ic != caps.end(); ++ic) {
+ store_r[cap_r][ic->index()].push_back( CapAndItem( *ic, item_r ) );
+ }
+ }
+
+ void CapHash::insert( const PoolItem & item_r )
+ {
+ storeInsert( _store, item_r, Dep::PROVIDES );
+ storeInsert( _store, item_r, Dep::REQUIRES );
+ storeInsert( _store, item_r, Dep::CONFLICTS );
+ storeInsert( _store, item_r, Dep::OBSOLETES );
+ storeInsert( _store, item_r, Dep::FRESHENS );
+ storeInsert( _store, item_r, Dep::EXTENDS );
+ }
+
+ static void
+ storeDelete( PoolTraits::DepCapItemContainerT & store_r, const PoolItem & item_r, Dep cap_r )
+ {
+ CapSet caps = item_r->dep( cap_r );
+ for (CapSet::iterator ic = caps.begin(); ic != caps.end(); ++ic) {
+ PoolTraits::CapItemContainerT capitems = store_r[cap_r][ic->index()];
+ for (PoolTraits::CapItemContainerT::iterator pos = capitems.begin();
+ pos != capitems.end(); ++pos)
+ {
+ if (pos->item == item_r)
+ capitems.erase( pos );
+ }
+ }
+ }
+
+ void CapHash::erase( const PoolItem & item_r )
+ {
+ storeDelete( _store, item_r, Dep::PROVIDES );
+ storeDelete( _store, item_r, Dep::REQUIRES );
+ storeDelete( _store, item_r, Dep::CONFLICTS );
+ storeDelete( _store, item_r, Dep::OBSOLETES );
+ storeDelete( _store, item_r, Dep::FRESHENS );
+ storeDelete( _store, item_r, Dep::EXTENDS );
+ }
+
+ const CapHash::CapItemStoreT & CapHash::capItemStore ( Dep cap_r ) const
+ { static CapItemStoreT capitemstore;
+ ContainerT::const_iterator it = store().find( cap_r );
+ if (it == store().end()) {
+XXX << "CapItemStoreT for " << cap_r << " not found" << endl;
+ return capitemstore;
+ }
+XXX << "CapItemStoreT for " << cap_r << " contains " << it->second.size() << " items" << endl;
+ return it->second;
+ }
+
+ // CapItemStoreT, index -> CapItemContainerT
+ const CapHash::CapItemContainerT & CapHash::capItemContainer( const CapItemStoreT & cis, const std::string & tag_r ) const
+ { static CapItemContainerT captemcontainer;
+ CapItemStoreT::const_iterator it = cis.find( tag_r );
+ if (it == cis.end()) {
+XXX << "CapItemContainerT for " << tag_r << " not found" << endl;
+ return captemcontainer;
+ }
+XXX << "CapItemContainerT for " << tag_r << " contains " << it->second.size() << " items" << endl;
+for (CapItemContainerT::const_iterator cai = it->second.begin(); cai != it->second.end(); ++cai) XXX << *cai << endl;
+ return it->second;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ //
// METHOD NAME : PoolImpl::PoolImpl
// METHOD TYPE : Ctor
//
void PoolImplInserter::operator()( ResObject::constPtr ptr_r )
{
PoolImpl::Item item ( ptr_r, ResStatus (_installed) );
- _poolImpl.store().insert( item );
- _poolImpl.namestore().insert( PoolImpl::NameContainerT::value_type (item->name(), item ) );
- CapSet provides = item->dep( Dep::PROVIDES );
- for (CapSet::iterator ic = provides.begin(); ic != provides.end(); ++ic) {
- _poolImpl.providesstore().insert( PoolImpl::IndexContainerT::value_type (ic->index(), std::make_pair( *ic, item ) ) );
- }
- CapSet requires = item->dep( Dep::REQUIRES );
- for (CapSet::iterator ic = requires.begin(); ic != requires.end(); ++ic) {
- _poolImpl.requiresstore().insert( PoolImpl::IndexContainerT::value_type (ic->index(), std::make_pair( *ic, item ) ) );
- }
- CapSet conflicts = item->dep( Dep::CONFLICTS );
- for (CapSet::iterator ic = conflicts.begin(); ic != conflicts.end(); ++ic) {
- _poolImpl.conflictsstore().insert( PoolImpl::IndexContainerT::value_type (ic->index(), std::make_pair( *ic, item ) ) );
- }
+ _poolImpl._store.insert( item );
+ _poolImpl._namehash.insert( item );
+ _poolImpl._caphash.insert( item );
// don't miss to invalidate ResPoolProxy
_poolImpl.invalidateProxy();
void PoolImplDeleter::operator()( ResObject::constPtr ptr_r )
{
PoolImpl::Item item( ptr_r );
- _poolImpl.store().erase( item );
- for (PoolImpl::nameiterator nit = _poolImpl.namestore().lower_bound (item->name());
- nit != _poolImpl.namestore().upper_bound (item->name()); ++nit)
- {
- if (nit->second == item)
- _poolImpl.namestore().erase( nit );
- }
- CapSet provides = ptr_r->dep( Dep::PROVIDES );
- for (CapSet::iterator ic = provides.begin(); ic != provides.end(); ++ic) {
- for (PoolImpl::indexiterator iit = _poolImpl.providesstore().lower_bound (ic->index());
- iit != _poolImpl.providesstore().upper_bound (ic->index()); ++iit)
- {
- if (iit->second.second == item)
- _poolImpl.providesstore().erase( iit );
- }
- }
- CapSet requires = ptr_r->dep( Dep::REQUIRES );
- for (CapSet::iterator ic = requires.begin(); ic != requires.end(); ++ic) {
- for (PoolImpl::indexiterator iit = _poolImpl.requiresstore().lower_bound (ic->index());
- iit != _poolImpl.requiresstore().upper_bound (ic->index()); ++iit)
- {
- if (iit->second.second == item)
- _poolImpl.requiresstore().erase( iit );
- }
- }
- CapSet conflicts = ptr_r->dep( Dep::CONFLICTS );
- for (CapSet::iterator ic = conflicts.begin(); ic != conflicts.end(); ++ic) {
- for (PoolImpl::indexiterator iit = _poolImpl.conflictsstore().lower_bound (ic->index());
- iit != _poolImpl.conflictsstore().upper_bound (ic->index()); ++iit)
- {
- if (iit->second.second == item)
- _poolImpl.conflictsstore().erase( iit );
- }
- }
+ _poolImpl._store.erase( item );
+ _poolImpl._namehash.erase( item );
+ _poolImpl._caphash.erase( item );
// don't miss to invalidate ResPoolProxy
_poolImpl.invalidateProxy();
}
+
/////////////////////////////////////////////////////////////////
} // namespace pool
///////////////////////////////////////////////////////////////////
#define ZYPP_POOL_POOLIMPL_H
#include <iosfwd>
+#include <map>
#include "zypp/pool/PoolTraits.h"
#include "zypp/ResPoolProxy.h"
namespace pool
{ /////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////
//
- // CLASS NAME : PoolImpl
+ // CLASS NAME : NameHash
//
/** */
- class PoolImpl
+ class NameHash
{
- friend std::ostream & operator<<( std::ostream & str, const PoolImpl & obj );
-
- public:
- /** */
- typedef PoolTraits::Item Item;
- typedef PoolTraits::ContainerT ContainerT;
- typedef PoolTraits::IndexContainerT IndexContainerT;
- typedef PoolTraits::NameContainerT NameContainerT;
- typedef PoolTraits::size_type size_type;
- typedef PoolTraits::iterator iterator;
- typedef PoolTraits::const_iterator const_iterator;
- typedef PoolTraits::indexiterator indexiterator;
- typedef PoolTraits::const_indexiterator const_indexiterator;
- typedef PoolTraits::nameiterator nameiterator;
- typedef PoolTraits::const_nameiterator const_nameiterator;
- typedef PoolTraits::Inserter Inserter;
- typedef PoolTraits::Deleter Deleter;
-
public:
/** Default ctor */
- PoolImpl();
+ NameHash();
/** Dtor */
- ~PoolImpl();
+ ~NameHash();
- public:
+ public:
+
+ typedef PoolTraits::ItemContainerT ItemContainerT;
+ typedef PoolTraits::NameItemContainerT ContainerT;
+ typedef PoolTraits::size_type size_type;
+ typedef PoolTraits::iterator iterator;
+ typedef PoolTraits::const_iterator const_iterator;
+
+ private:
+ ItemContainerT & getItemContainer( const std::string & tag_r );
+ const ItemContainerT & getConstItemContainer( const std::string & tag_r ) const;
+
+ public:
/** */
ContainerT & store()
{ return _store; }
{ return _store; }
/** */
- IndexContainerT & providesstore()
- { return _providesstore; }
+ bool empty() const
+ { return _store.empty(); }
/** */
- const IndexContainerT & providesstore() const
- { return _providesstore; }
+ size_type size() const
+ { return _store.size(); }
- IndexContainerT & requiresstore()
- { return _requiresstore; }
- /** */
- const IndexContainerT & requiresstore() const
- { return _requiresstore; }
+ /** */
+ iterator begin( const std::string & tag_r )
+ { return getItemContainer( tag_r ).begin(); }
+ /** */
+ const_iterator begin( const std::string & tag_r ) const
+ { return getConstItemContainer( tag_r ).begin(); }
- IndexContainerT & conflictsstore()
- { return _conflictsstore; }
- /** */
- const IndexContainerT & conflictsstore() const
- { return _conflictsstore; }
+ /** */
+ iterator end( const std::string & tag_r )
+ { return getItemContainer( tag_r ).end(); }
+ /** */
+ const_iterator end( const std::string & tag_r ) const
+ { return getConstItemContainer( tag_r ).end(); }
+
+ /** */
+ void clear()
+ { _store.clear(); }
+
+ /** */
+ void insert( const PoolItem & item_r );
+ /** */
+ void erase( const PoolItem & item_r );
+
+ private:
+ ContainerT _store;
+ ItemContainerT _empty; // for begin(), end() if tag_r can't be found
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : CapHash
+ //
+ /** */
+ class CapHash
+ {
+ public:
+ /** Default ctor */
+ CapHash();
+ /** Dtor */
+ ~CapHash();
+
+ public:
+
+ typedef PoolTraits::DepCapItemContainerT ContainerT;
+ typedef PoolTraits::capitemsize_type size_type;
+ typedef PoolTraits::capitemiterator iterator;
+ typedef PoolTraits::const_capitemiterator const_iterator;
+
+ private:
+
+ typedef PoolTraits::CapItemStoreT CapItemStoreT;
+ typedef PoolTraits::CapItemContainerT CapItemContainerT;
+
+ // Dep -> CapItemStoreT
+ const CapItemStoreT & capItemStore ( Dep cap_r ) const;
+
+ // CapItemStoreT, index -> CapItemContainerT
+ const CapItemContainerT & capItemContainer( const CapItemStoreT & cis, const std::string & tag_r ) const;
+
+ public:
/** */
- NameContainerT & namestore()
- { return _namestore; }
+ ContainerT & store()
+ { return _store; }
/** */
- const NameContainerT & namestore() const
- { return _namestore; }
+ const ContainerT & store() const
+ { return _store; }
/** */
bool empty() const
{ return _store.size(); }
/** */
- iterator begin()
- { return _store.begin(); }
+ iterator begin( const std::string & tag_r, Dep cap_r )
+ { return _store[cap_r][tag_r].begin(); }
/** */
- const_iterator begin() const
- { return _store.begin(); }
+ const_iterator begin( const std::string & tag_r, Dep cap_r ) const
+ { const CapItemStoreT & capitemstore = capItemStore( cap_r );
+ const CapItemContainerT & capcontainer = capItemContainer ( capitemstore, tag_r );
+ return capcontainer.begin(); }
/** */
- indexiterator providesbegin(const std::string & tag_r)
- { return _providesstore.lower_bound (tag_r); }
+ iterator end( const std::string & tag_r, Dep cap_r )
+ { return _store[cap_r][tag_r].begin(); }
/** */
- const_indexiterator providesbegin(const std::string & tag_r) const
- { return _providesstore.lower_bound (tag_r); }
+ const_iterator end( const std::string & tag_r, Dep cap_r ) const
+ { const CapItemStoreT & capitemstore = capItemStore( cap_r );
+ const CapItemContainerT & capcontainer = capItemContainer ( capitemstore, tag_r );
+ return capcontainer.end(); }
/** */
- indexiterator requiresbegin(const std::string & tag_r)
- { return _requiresstore.lower_bound (tag_r); }
- /** */
- const_indexiterator requiresbegin(const std::string & tag_r) const
- { return _requiresstore.lower_bound (tag_r); }
+ void clear()
+ { _store.clear(); }
/** */
- indexiterator conflictsbegin(const std::string & tag_r)
- { return _conflictsstore.lower_bound (tag_r); }
+ void insert( const PoolItem & item_r );
/** */
- const_indexiterator conflictsbegin(const std::string & tag_r) const
- { return _conflictsstore.lower_bound (tag_r); }
+ void erase( const PoolItem & item_r );
- /** */
- nameiterator namebegin(const std::string & tag_r)
- { return _namestore.lower_bound (tag_r); }
- /** */
- const_nameiterator namebegin(const std::string & tag_r) const
- { return _namestore.lower_bound (tag_r); }
+ private:
+ PoolTraits::DepCapItemContainerT _store;
+ };
- /** */
- iterator end()
- { return _store.end(); }
- /** */
- const_iterator end() const
- { return _store.end(); }
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PoolImpl
+ //
+ /** */
+ class PoolImpl
+ {
+ friend std::ostream & operator<<( std::ostream & str, const PoolImpl & obj );
- /** */
- indexiterator providesend(const std::string & tag_r)
- { return _providesstore.upper_bound (tag_r); }
- /** */
- const_indexiterator providesend(const std::string & tag_r) const
- { return _providesstore.upper_bound (tag_r); }
+ public:
+ /** */
+ typedef PoolTraits::Item Item;
+ typedef PoolTraits::ItemContainerT ContainerT;
+ typedef PoolTraits::iterator iterator;
+ typedef PoolTraits::const_iterator const_iterator;
+ typedef PoolTraits::size_type size_type;
+ typedef PoolTraits::Inserter Inserter;
+ typedef PoolTraits::Deleter Deleter;
- /** */
- indexiterator requiresend(const std::string & tag_r)
- { return _requiresstore.upper_bound (tag_r); }
- /** */
- const_indexiterator requiresend(const std::string & tag_r) const
- { return _requiresstore.upper_bound (tag_r); }
+ public:
+ /** Default ctor */
+ PoolImpl();
+ /** Dtor */
+ ~PoolImpl();
+
+ public:
+ /** */
+ ContainerT & store()
+ { return _store; }
+ /** */
+ const ContainerT & store() const
+ { return _store; }
+
+ /** */
+ bool empty() const
+ { return _store.empty(); }
+ /** */
+ size_type size() const
+ { return _store.size(); }
/** */
- indexiterator conflictsend(const std::string & tag_r)
- { return _conflictsstore.upper_bound (tag_r); }
+ iterator begin()
+ { return _store.begin(); }
/** */
- const_indexiterator conflictsend(const std::string & tag_r) const
- { return _conflictsstore.upper_bound (tag_r); }
+ const_iterator begin() const
+ { return _store.begin(); }
/** */
- nameiterator nameend(const std::string & tag_r)
- { return _namestore.upper_bound (tag_r); }
+ iterator end()
+ { return _store.end(); }
/** */
- const_nameiterator nameend(const std::string & tag_r) const
- { return _namestore.upper_bound (tag_r); }
+ const_iterator end() const
+ { return _store.end(); }
/** */
void clear()
{ _store.clear();
- _providesstore.clear();
- _requiresstore.clear();
- _conflictsstore.clear();
- _namestore.clear();
+ _caphash.clear();
+ _namehash.clear();
return;
}
public:
/** */
ContainerT _store;
- IndexContainerT _providesstore;
- IndexContainerT _requiresstore;
- IndexContainerT _conflictsstore;
- NameContainerT _namestore;
+ NameHash _namehash;
+ CapHash _caphash;
public:
ResPoolProxy proxy( ResPool self ) const
#include <map>
#include "zypp/PoolItem.h"
+#include "zypp/Capability.h"
+#include "zypp/CapAndItem.h"
+#include "zypp/Dep.h"
///////////////////////////////////////////////////////////////////
namespace zypp
{
public:
/** */
- typedef PoolItem Item;
- typedef std::set<Item> ContainerT;
- typedef std::multimap<std::string,std::pair<Capability,Item> > IndexContainerT;
- typedef std::multimap<std::string,Item> NameContainerT;
- typedef ContainerT::size_type size_type;
- typedef ContainerT::iterator iterator;
- typedef ContainerT::const_iterator const_iterator;
- typedef IndexContainerT::iterator indexiterator;
- typedef IndexContainerT::const_iterator const_indexiterator;
- typedef NameContainerT::iterator nameiterator;
- typedef NameContainerT::const_iterator const_nameiterator;
+ typedef PoolItem Item;
+
+ /** pure items */
+ typedef std::set<Item> ItemContainerT;
+ typedef ItemContainerT::iterator iterator;
+ typedef ItemContainerT::const_iterator const_iterator;
+ typedef ItemContainerT::size_type size_type;
+
+ /** hashed by name */
+ // use same iterators as above
+ // internal organization
+ typedef std::map<std::string,ItemContainerT> NameItemContainerT;
+
+ /** hashed by capability index */
+ typedef std::list<CapAndItem> CapItemContainerT; // (why,who) pairs
+ typedef CapItemContainerT::iterator capitemiterator;
+ typedef CapItemContainerT::const_iterator const_capitemiterator;
+ typedef CapItemContainerT::size_type capitemsize_type;
+
+ // internal organization
+ typedef std::map<std::string,CapItemContainerT> CapItemStoreT; // capability.index -> (why,who) pairs
+ typedef std::map<Dep,CapItemStoreT> DepCapItemContainerT; // Dep -> (capability.index -> (why,who) pairs)
typedef PoolImpl Impl;
typedef shared_ptr<PoolImpl> Impl_Ptr;
}
-class LookFor : public resfilter::OnCapMatchCallbackFunctor, public resfilter::PoolItemFilterFunctor
+class LookFor : public resfilter::PoolItemFilterFunctor
{
public:
PoolItem_Ref item;
Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
{
LookFor info;
-#if 0
+
invokeOnEach( pool.byNameBegin( name ),
pool.byNameEnd( name ),
functor::chain (resfilter::ByInstalled (), // ByInstalled
resfilter::ByKind( kind ) ), // equal kind
functor::functorRef<bool,PoolItem> (info) );
-#endif
- ResPool::const_nameiterator pend = pool.nameend(name);
- for (ResPool::const_nameiterator it = pool.namebegin(name); it != pend; ++it) {
- PoolItem item = it->second;
- if (item.status().isInstalled()
- && item->kind() == kind) {
- if (!info( it->second ))
- break;
- }
- }
_XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
return info.item;
Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
{
LookFor info;
-#if 0
+
invokeOnEach( pool.byNameBegin( name ),
pool.byNameEnd( name ),
- functor::chain (resfilter::ByInstalled (), // ByInstalled
+ functor::chain (resfilter::ByUninstalled (), // ByUninstalled
resfilter::ByKind( kind ) ), // equal kind
functor::functorRef<bool,PoolItem> (info) );
-#endif
- ResPool::const_nameiterator pend = pool.nameend(name);
- for (ResPool::const_nameiterator it = pool.namebegin(name); it != pend; ++it) {
- PoolItem item = it->second;
- if (item.status().isUninstalled()
- && item->kind() == kind) {
- if (!info( it->second ))
- break;
- }
- }
_XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
return info.item;
//----------------------------------------------------------------------------
-class LookForUpdate : public resfilter::OnCapMatchCallbackFunctor, public resfilter::PoolItemFilterFunctor
+class LookForUpdate : public resfilter::PoolItemFilterFunctor
{
public:
PoolItem_Ref uninstalled;
{
LookForUpdate info;
#warning FIXME, should not report locked update candidates.
-#if 0
+
invokeOnEach( pool.byNameBegin( item->name() ),
pool.byNameEnd( item->name() ),
functor::chain (functor::chain (resfilter::ByUninstalled (), // ByUninstalled
resfilter::ByKind( item->kind() ) ), // equal kind
resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),
functor::functorRef<bool,PoolItem> (info) );
-#endif
- ResPool::const_nameiterator pend = pool.nameend(item->name());
- for (ResPool::const_nameiterator it = pool.namebegin(item->name()); it != pend; ++it) {
- PoolItem pos = it->second;
- if (pos.status().staysUninstalled()
- && pos->kind() == item->kind()
- && item->edition().compare(pos->edition()) < 0)
- {
- if (!info( pos ))
- break;
- }
- }
_XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled);
return info.uninstalled;
//----------------------------------------------------------------------------
-class LookForReinstall : public resfilter::OnCapMatchCallbackFunctor, public resfilter::PoolItemFilterFunctor
+class LookForReinstall : public resfilter::PoolItemFilterFunctor
{
public:
PoolItem_Ref uninstalled;
{
LookForReinstall info;
#warning FIXME, should not report locked update candidates.
-#if 0
+
invokeOnEach( pool.byNameBegin( item->name() ),
pool.byNameEnd( item->name() ),
functor::chain (functor::chain (resfilter::ByUninstalled (), // ByUninstalled
resfilter::ByKind( item->kind() ) ), // equal kind
resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )),
functor::functorRef<bool,PoolItem> (info) );
-#endif
- ResPool::const_nameiterator pend = pool.nameend(item->name());
- for (ResPool::const_nameiterator it = pool.namebegin(item->name()); it != pend; ++it) {
- PoolItem pos = it->second;
- if (pos.status().staysUninstalled()
- && pos->kind() == item->kind()
- && item->edition().compare(pos->edition()) == 0)
- {
- if (!info( pos ))
- break;
- }
- }
_XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled);
return info.uninstalled;
#include "zypp/ResFilters.h"
#include "zypp/ResStatus.h"
+#include "zypp/CapAndItem.h"
/////////////////////////////////////////////////////////////////////////
namespace zypp
return PoolItem_Ref();
}
-struct CollectProviders : public resfilter::OnCapMatchCallbackFunctor
+struct CollectProviders
{
const PoolItem_Ref requestor;
PoolItemList result;
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ 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(" << provider <<")"<< endl;
- if ((provider.resolvable() != requestor.resolvable()) // resolvable could provide its own requirement
- && (limitto.find( provider ) != limitto.end())) // limit to members of 'limitto' set
+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(provider) << endl;
- result.push_back (provider);
+ XXX << "tovisit " << ITEMNAME(c_and_i.item) << endl;
+ result.push_back (c_and_i.item);
}
return true;
XXX << "check requirement " << requirement << " of " << ITEMNAME(item) << endl;
PoolItemList tovisit;
-#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 1
- // first, look in _installed
+ // first, look in _installed
CollectProviders info ( item, _installed );
- ResPool::const_indexiterator pend = _pool.providesend( requirement.index() );
- for (ResPool::const_indexiterator it = _pool.providesbegin( requirement.index() ); it != pend; ++it) {
- if (it->second.first.matches (requirement) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ 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 );
- ResPool::const_indexiterator pend = _pool.providesend( requirement.index() );
- for (ResPool::const_indexiterator it = _pool.providesbegin( requirement.index() ); it != pend; ++it) {
- if (it->second.first.matches (requirement) == CapMatch::yes) {
- if (!info1( it->second.second, it->second.first))
- break;
- }
- }
+ invokeOnEach( _pool.byCapabilityIndexBegin( requirement.index(), dep ),
+ _pool.byCapabilityIndexEnd( requirement.index(), dep ),
+ resfilter::ByCapMatch( requirement ),
+ functor::functorRef<bool,CapAndItem>(info1) );
+
tovisit = info1.result;
}
-#endif
-#if 0
- // 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 );
- }
- }
- }
-#endif
for (PoolItemList::iterator it = tovisit.begin(); it != tovisit.end(); ++it)
{
const PoolItem_Ref must_visit = *it;
#include "zypp/ResPool.h"
#include "zypp/ResFilters.h"
#include "zypp/CapFilters.h"
+#include "zypp/CapAndItem.h"
#include "zypp/solver/detail/Types.h"
// phi tends to upgrade the item
// testcases: exercise-02conflict-08-test.xml, exercise-02conflict-09-test.xml
-struct UpgradeCandidate : public resfilter::OnCapMatchCallbackFunctor
+struct UpgradeCandidate
{
PoolItem_Ref item; // the conflicting resolvable, used to filter upgrades with an identical resolvable
ResolverContext_Ptr context;
, context (ctx)
{ }
- bool operator() (const PoolItem & candidate, const Capability & cap)
+ bool operator() (const CapAndItem & cai)
{
+ PoolItem candidate = cai.item;
+
//MIL << "UpgradeCandidate? " << candidate << ":[" << context->getStatus (candidate) << "]" << (item->edition().compare(candidate->edition())) << "<" << item->arch() << "," << candidate->arch() << ">" << endl;
// FIXME put this in the resfilter chain
ResStatus status = context->getStatus (candidate);
//---------------------------------------------------------------------------------------
-struct ConflictProcess : public resfilter::OnCapMatchCallbackFunctor
+struct ConflictProcess
{
ResPool pool;
PoolItem_Ref conflict_issuer; // the item which issues 'conflicts:'
, actually_an_obsolete (ao)
{ }
- bool operator()( const PoolItem_Ref & provider, const Capability & provides )
+ bool operator()( const CapAndItem & cai )
{
ResStatus status;
ResolverInfo_Ptr log_info;
CapFactory factory;
+ PoolItem provider = cai.item;
+ Capability provides = cai.cap;
+
_XDEBUG("conflict_process_cb (resolvable[" << provider <<"], provides[" << provides << "], conflicts with [" <<
conflict_issuer << " conflicts: " << conflict_capability);
UpgradeCandidate upgrade_info (provider, context);
Capability maybe_upgrade_cap = factory.parse ( provider->kind(), provider->name(), Rel::ANY, Edition::noedition );
-#if 0
+
// pool->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);
Dep dep( Dep::PROVIDES );
invokeOnEach( pool.byCapabilityIndexBegin( maybe_upgrade_cap.index(), dep ),
pool.byCapabilityIndexEnd( maybe_upgrade_cap.index(), dep ),
- resfilter::callOnCapMatchIn( dep, maybe_upgrade_cap, functor::functorRef<bool,PoolItem,Capability>(upgrade_info) ) );
-#endif
- ResPool::const_indexiterator pend = pool.providesend(maybe_upgrade_cap.index());
- for (ResPool::const_indexiterator it = pool.providesbegin(maybe_upgrade_cap.index()); it != pend; ++it) {
- if (maybe_upgrade_cap.matches (it->second.first) == CapMatch::yes) {
- if (!upgrade_info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( maybe_upgrade_cap ),
+ functor::functorRef<bool,CapAndItem>(upgrade_info) );
_XDEBUG("found " << upgrade_info.upgrades.size() << " upgrade candidates");
#endif
ConflictProcess info (pool(), _conflicting_item, _capability, context, new_items, _actually_an_obsolete);
// world()->foreachProvidingPoolItem (_capability, conflict_process_cb, (void *)&info);
-#if 0
+
Dep dep( Dep::PROVIDES );
invokeOnEach( pool().byCapabilityIndexBegin( _capability.index(), dep ),
pool().byCapabilityIndexEnd( _capability.index(), dep ),
- resfilter::callOnCapMatchIn( dep, _capability, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
- ResPool::const_indexiterator pend = pool().providesend(_capability.index());
- for (ResPool::const_indexiterator it = pool().providesbegin(_capability.index()); it != pend; ++it) {
- if (_capability.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( _capability ),
+ functor::functorRef<bool,CapAndItem>(info) );
return true;
}
// Handle items which freshen us -> re-establish them
-struct EstablishFreshens : public resfilter::OnCapMatchCallbackFunctor
+struct EstablishFreshens
{
const ResPool & pool;
QueueItemList & qil;
// provider has a freshens on a just to-be-installed item
// re-establish provider, maybe its incomplete now
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
- _XDEBUG("EstablishFreshens (" << provider << ", " << match << ")");
+ _XDEBUG("EstablishFreshens (" << cai.item << ", " << cai.cap << ")");
- QueueItemEstablish_Ptr establish_item = new QueueItemEstablish (pool, provider, soft);
+ QueueItemEstablish_Ptr establish_item = new QueueItemEstablish (pool, cai.item, soft);
qil.push_back (establish_item);
return true;
}
};
+
+//---------------------------------------------------------------------------
+
+// Handle items which conflict us -> uninstall them
+
+struct UninstallConflicting
+{
+ ResolverContext_Ptr _context;
+ const Capability _provided_cap;
+ PoolItem _install_item;
+ PoolItem _upgrade_item;
+ QueueItemList & _qil;
+ bool ignored;
+
+ UninstallConflicting( ResolverContext_Ptr ctx, const Capability & provided_cap, PoolItem install_item, PoolItem upgrade_item, QueueItemList & qil )
+ : _context( ctx )
+ , _provided_cap( provided_cap )
+ , _install_item( install_item )
+ , _upgrade_item( upgrade_item )
+ , _qil( qil )
+ , ignored( false )
+ { }
+
+ bool operator()( const CapAndItem & cai)
+ {
+ PoolItem_Ref conflicting_item = cai.item;
+
+ if (conflicting_item == _install_item) { // self conflict ?
+ WAR << "Ignoring self-conflicts" << endl;
+ return true;
+ }
+ if (conflicting_item == _upgrade_item) { // upgrade conflict ?
+ _XDEBUG("We're upgrading the conflicting item");
+ return true;
+ }
+
+ const Capability conflicting_cap = cai.cap;
+ ResolverInfo_Ptr log_info;
+ QueueItemUninstall_Ptr uninstall_item;
+
+ IgnoreMap ignoreMap = _context->getIgnoreConflicts(); // ignored conflict ?
+ // checking for ignoring dependencies
+ for (IgnoreMap::iterator it = ignoreMap.begin(); it != ignoreMap.end(); it++) {
+ if (it->first == conflicting_item
+ && it->second == conflicting_cap)
+ {
+ _XDEBUG("Found ignoring requires " << conflicting_cap << " for " << conflicting_item);
+ ignored = true;
+ return false; // stop iteration
+ } else {
+ _XDEBUG("Ignoring requires " << it->second << " for " << it->first << " does not fit");
+ }
+ }
+
+ /* Check to see if we conflict with ourself and don't create
+ * an uninstall item for it if we do. This is Debian's way of
+ * saying that one and only one item with this provide may
+ * exist on the system at a time.
+ */
+
+ if (compareByNVR (conflicting_item.resolvable(), _install_item.resolvable()) == 0) {
+ return true;
+ }
+
+#warning Make behaviour configurable
+ // If the package is installed or is set to be installed by the user,
+ // let the user decide deleting conflicting package. This is only an info.
+ // Try at first updating packages.
+ //
+ if (_context->getStatus(conflicting_item).isToBeInstalled() // scheduled for installation
+ && !_context->getStatus(conflicting_item).isToBeUninstalled() // not scheduled for uninstallation
+ || conflicting_item.status().staysInstalled()) // not scheduled at all but installed
+ {
+ ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL,
+ _install_item, RESOLVER_INFO_PRIORITY_VERBOSE, _provided_cap);
+ misc_info->setOtherPoolItem (conflicting_item);
+ misc_info->setOtherCapability (conflicting_cap);
+ _context->addInfo (misc_info);
+ }
+
+ _XDEBUG("because: '" << conflicting_item << "' provides " << conflicting_cap);
+
+ QueueItemUninstall_Ptr uninstall_qitem = new QueueItemUninstall (_context->pool(), conflicting_item, QueueItemUninstall::CONFLICT);
+ uninstall_qitem->setDueToConflict ();
+ log_info = new ResolverInfoConflictsWith (conflicting_item, _install_item);
+ uninstall_qitem->addInfo (log_info);
+ _qil.push_front (uninstall_qitem);
+
+ return true;
+ }
+};
+
//---------------------------------------------------------------------------------------
bool
// Searching item that conflict with us and try to uninstall it if it is useful
- IgnoreMap ignoreMap = context->getIgnoreConflicts();
caps = _item->dep (Dep::PROVIDES);
for (CapSet::const_iterator iter = caps.begin(); iter != caps.end(); iter++) {
const Capability cap = *iter;
- ResPool::const_indexiterator cend = pool().conflictsend(cap.index());
- for (ResPool::const_indexiterator it = pool().conflictsbegin(cap.index()); it != cend; ++it) {
-
- if (cap.matches (it->second.first) == CapMatch::yes) {
- // conflicting item found
- PoolItem_Ref conflicting_item = it->second.second;
-
- if (conflicting_item == _item) {
- WAR << "Ignoring self-conflicts" << endl;
- continue;
- }
- if (conflicting_item == _upgrades) {
- _XDEBUG("We're upgrading the conflicting item");
- continue;
- }
- const Capability conflicting_cap = it->second.first;
- ResolverInfo_Ptr log_info;
- QueueItemUninstall_Ptr uninstall_item;
-
- // checking for ignoring dependencies
- for (IgnoreMap::iterator it = ignoreMap.begin();
- it != ignoreMap.end(); it++) {
- if (it->first == conflicting_item
- && it->second == conflicting_cap) {
- _XDEBUG("Found ignoring requires " << conflicting_cap << " for " << conflicting_item);
- return true;
- } else {
- _XDEBUG("Ignoring requires " << it->second << " for " << it->first << " does not fit");
- }
- }
-
- /* Check to see if we conflict with ourself and don't create
- * an uninstall item for it if we do. This is Debian's way of
- * saying that one and only one item with this provide may
- * exist on the system at a time.
- */
-
- if (compareByNVR (conflicting_item.resolvable(), _item.resolvable()) == 0) {
- continue;
- }
+ UninstallConflicting info( context, cap, _item, _upgrades, qil );
-#warning Make behaviour configurable
- // If the package is installed or is set to be installed by the user,
- // let the user decide deleting conflicting package. This is only an info.
- // Try at first updating packages.
- //
- if (context->getStatus(conflicting_item).isToBeInstalled() // scheduled for installation
- && !context->getStatus(conflicting_item).isToBeUninstalled() // not scheduled for uninstallation
- || conflicting_item.status().staysInstalled()) // not scheduled at all but installed
- {
- ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL,
- _item, RESOLVER_INFO_PRIORITY_VERBOSE, cap);
- misc_info->setOtherPoolItem (conflicting_item);
- misc_info->setOtherCapability (conflicting_cap);
- context->addInfo (misc_info);
- }
-
- _XDEBUG("because: '" << conflicting_item << "' provides " << cap);
-
- uninstall_item = new QueueItemUninstall (pool(), conflicting_item, QueueItemUninstall::CONFLICT, _soft);
- uninstall_item->setDueToConflict ();
- log_info = new ResolverInfoConflictsWith (conflicting_item, _item);
- uninstall_item->addInfo (log_info);
- qil.push_front (uninstall_item);
- }
- }
+ Dep dep( Dep::CONFLICTS );
+ invokeOnEach( pool().byCapabilityIndexBegin( cap.index(), dep ),
+ pool().byCapabilityIndexEnd( cap.index(), dep ),
+ resfilter::ByCapMatch( cap ),
+ functor::functorRef<bool,CapAndItem>(info) );
+
+ if (info.ignored) // user choose to ignore these conflitcs
+ return true;
}
/* Construct establish items for each of those which freshen this resolvable. */
Dep dep( Dep::FRESHENS);
invokeOnEach( pool().byCapabilityIndexBegin( cap.index(), dep ), // begin()
pool().byCapabilityIndexEnd( cap.index(), dep ), // end()
- resfilter::callOnCapMatchIn( dep, cap, functor::functorRef<bool,PoolItem,Capability>(info)) );
+ resfilter::ByCapMatch( cap ),
+ functor::functorRef<bool,CapAndItem>(info) );
} // end of block
};
//---------------------------------------------------------------------------
-struct RequireProcess : public resfilter::OnCapMatchCallbackFunctor
+struct RequireProcess
{
PoolItem_Ref requirer;
const Capability capability;
, pool (p)
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
//const Capability match;
ResStatus status;
+ PoolItem provider = cai.item;
+ Capability match = cai.cap;
status = context->getStatus( provider );
};
-struct NoInstallableProviders : public resfilter::OnCapMatchCallbackFunctor
+struct NoInstallableProviders
{
PoolItem_Ref requirer;
ResolverContext_Ptr context;
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem cai)
{
+ PoolItem provider = cai.item;
+ Capability match = cai.cap;
+
string msg_str;
//const Capability match;
};
-struct LookForUpgrades : public resfilter::OnCapMatchCallbackFunctor
+struct LookForUpgrades
{
PoolItem_Ref installed;
PoolItemList upgrades;
bool operator()( PoolItem_Ref provider )
{
-// if (installed->edition().compare (provider->edition()) < 0) {
- upgrades.push_front (provider);
- return true;
-// }
-// return false;
+ upgrades.push_front (provider);
+ return true;
}
};
if (! _remove_only) {
-#if 0
Dep dep( Dep::PROVIDES );
MIL << "Look for providers of " << _capability << endl;
// world->foreachProvidingResItem (_capability, require_process_cb, &info);
invokeOnEach( pool().byCapabilityIndexBegin( _capability.index(), dep ),
pool().byCapabilityIndexEnd( _capability.index(), dep ),
- resfilter::callOnCapMatchIn( dep, _capability, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
+ resfilter::ByCapMatch( _capability ),
+ functor::functorRef<bool,CapAndItem>(info) );
+
_XDEBUG("Look for providers of " << _capability);
- // world->foreachProvidingResItem (_capability, require_process_cb, &info);
- ResPool::const_indexiterator pend = pool().providesend(_capability.index());
- for (ResPool::const_indexiterator it = pool().providesbegin(_capability.index()); it != pend; ++it) {
- if (_capability.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
num_providers = info.providers.size();
// Maybe we can add some extra info on why none of the providers are suitable.
// pool()->foreachProvidingResItem (_capability, no_installable_providers_info_cb, (void *)&info);
-#if 0
+
Dep dep( Dep::PROVIDES );
invokeOnEach( pool().byCapabilityIndexBegin( _capability.index(), dep ), // begin()
pool().byCapabilityIndexEnd( _capability.index(), dep ), // end()
- resfilter::callOnCapMatchIn( dep, _capability, functor::functorRef<bool,PoolItem,Capability>(info)) );
-#endif
- // world->foreachProvidingResItem (_capability, require_process_cb, &info);
- ResPool::const_indexiterator pend = pool().providesend(_capability.index());
- for (ResPool::const_indexiterator it = pool().providesbegin(_capability.index()); it != pend; ++it) {
- if (_capability.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( _capability ),
+ functor::functorRef<bool,CapAndItem>(info) );
}
// pool()->foreachUpgrade (_requiring_item, new Channel(CHANNEL_TYPE_ANY), look_for_upgrades_cb, (void *)&upgrade_list);
-#if 0 // **!!!** re-enable editon check in LookForUpgrades()
-
invokeOnEach( pool().byNameBegin( _requiring_item->name() ), pool().byNameEnd( _requiring_item->name() ),
- resfilter::ByKind( _requiring_item->kind() ),
-#if 0
- // CompareByGT is broken resfilter::byEdition<CompareByGT<Edition> >( _requiring_item->edition() )),
-#endif
+ functor::chain (resfilter::ByKind( _requiring_item->kind() ),
+ resfilter::byEdition<CompareByGT<Edition> >( _requiring_item->edition() ) ),
functor::functorRef<bool,PoolItem>(info) );
-#endif
- ResPool::const_nameiterator pend = pool().nameend(_requiring_item->name());
- for (ResPool::const_nameiterator it = pool().namebegin(_requiring_item->name()); it != pend; ++it) {
- PoolItem pos = it->second;
- if (pos->kind() == _requiring_item->kind()
- && _requiring_item->edition().compare(pos->edition()) < 0)
- {
- if (!info( pos ))
- break;
- }
- }
if (!info.upgrades.empty()) {
string label;
//---------------------------------------------------------------------------
-struct UnlinkCheck: public resfilter::OnCapMatchCallbackFunctor
+struct UnlinkCheck
{
ResolverContext_Ptr context;
bool cancel_unlink;
// or if the uninstall breaks the requirer
// in this case, we have to cancel the uninstallation
- bool operator()( PoolItem_Ref requirer, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
if (cancel_unlink) // already cancelled
return true;
- if (! context->isPresent (requirer)) // item is not (to-be-)installed
+ if (! context->isPresent (cai.item)) // item is not (to-be-)installed
return true;
- if (context->requirementIsMet (match)) // another resolvable provided match
+ if (context->requirementIsMet (cai.cap)) // another resolvable provided match
return true;
cancel_unlink = true; // cancel, as this would break dependencies
//---------------------------------------------------------------------------
-struct UninstallProcess: public resfilter::OnCapMatchCallbackFunctor
+struct UninstallProcess
{
ResPool pool;
ResolverContext_Ptr context;
// the uninstall of uninstalled_item breaks the dependency 'match' of resolvable 'requirer'
- bool operator()( PoolItem_Ref requirer, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
+ PoolItem requirer( cai.item );
if (! context->isPresent (requirer)) // its not installed -> dont care
return true;
- if (context->requirementIsMet (match, false)) // its provided by another installed resolvable -> dont care
+ if (context->requirementIsMet( cai.cap, false )) // its provided by another installed resolvable -> dont care
return true;
if (context->getStatus(requirer).isSatisfied()) { // it is just satisfied, check freshens
qil.push_back (establish_item);
return true;
}
- QueueItemRequire_Ptr require_item = new QueueItemRequire (pool, match); // issue a new require to fulfill this dependency
+ QueueItemRequire_Ptr require_item = new QueueItemRequire( pool, cai.cap ); // issue a new require to fulfill this dependency
require_item->addPoolItem (requirer);
if (remove_only) {
require_item->setRemoveOnly ();
for (CapSet::const_iterator iter = provides.begin(); iter != provides.end() && ! info.cancel_unlink; iter++) {
//world()->foreachRequiringPoolItem (*iter, unlink_check_cb, &info);
-#if 1
+
Dep dep( Dep::REQUIRES);
invokeOnEach( pool().byCapabilityIndexBegin( iter->index(), dep ),
pool().byCapabilityIndexEnd( iter->index(), dep ),
- resfilter::callOnCapMatchIn( dep, *iter, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#else
- Capability c = *iter;
- ResPool::const_indexiterator rend = pool().requiresend(c.index());
- for (ResPool::const_indexiterator it = pool().requiresbegin(c.index()); it != rend; ++it) {
- if (c.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
-#endif
+ resfilter::ByCapMatch( *iter ),
+ functor::functorRef<bool,CapAndItem>(info) );
}
for (CapSet::const_iterator iter = provides.begin(); iter != provides.end(); iter++) {
UninstallProcess info ( pool(), context, _item, _upgraded_to, qil, _remove_only, _soft);
-#if 0
+
//world()->foreachRequiringPoolItem (*iter, uninstall_process_cb, &info);
Dep dep( Dep::REQUIRES);
invokeOnEach( pool().byCapabilityIndexBegin( iter->index(), dep ),
pool().byCapabilityIndexEnd( iter->index(), dep ),
- resfilter::callOnCapMatchIn( dep, *iter, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
- Capability c = *iter;
- ResPool::const_indexiterator rend = pool().requiresend(c.index());
- for (ResPool::const_indexiterator it = pool().requiresbegin(c.index()); it != rend; ++it) {
- if (c.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( *iter ),
+ functor::functorRef<bool,CapAndItem>(info) );
}
}
// establish state
-struct EstablishState : public resfilter::OnCapMatchCallbackFunctor
+struct EstablishState
{
Resolver & resolver;
//---------------------------------------------------------------------------
// requirements
-struct RequirementMet : public resfilter::OnCapMatchCallbackFunctor
+struct RequirementMet
{
ResolverContext_Ptr context;
const Capability capability;
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
+ Capability match( cai.cap );
+ PoolItem provider( cai.item );
// capability is set for item set children. If it is set, query the
// exact version only.
if ((capability == Capability::noCap
RequirementMet info (this, is_child ? dependency : Capability::noCap);
// world()->foreachProviding (dependency, requirement_met_cb, (void *)&info);
-#if 0
+
Dep dep( Dep::PROVIDES );
// world->foreachProvidingResItem (dependency, require_process_cb, &info);
invokeOnEach( pool().byCapabilityIndexBegin( dependency.index(), dep ),
pool().byCapabilityIndexEnd( dependency.index(), dep ),
- resfilter::callOnCapMatchIn( dep, dependency, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
- ResPool::const_indexiterator pend = pool().providesend(dependency.index());
- for (ResPool::const_indexiterator it = pool().providesbegin(dependency.index()); it != pend; ++it) {
- if (dependency.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( dependency ),
+ functor::functorRef<bool,CapAndItem>(info) );
return info.flag;
}
//---------------------------------------------------------------------------
-struct RequirementPossible : public resfilter::OnCapMatchCallbackFunctor
+struct RequirementPossible
{
ResolverContext_Ptr context;
bool flag;
, flag (false)
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
+ PoolItem provider( cai.item );
ResStatus status = context->getStatus( provider );
if (! (status.isToBeUninstalled () || status.isImpossible())
RequirementPossible info( this );
// world()->foreachProviding (dep, requirement_possible_cb, (void *)&info);
-#if 0
+
Dep dep( Dep::PROVIDES );
invokeOnEach( pool().byCapabilityIndexBegin( dependency.index(), dep ),
pool().byCapabilityIndexEnd( dependency.index(), dep ),
- resfilter::callOnCapMatchIn( dep, dependency, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
- ResPool::const_indexiterator pend = pool().providesend(dependency.index());
- for (ResPool::const_indexiterator it = pool().providesbegin(dependency.index()); it != pend; ++it) {
- if (dependency.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ resfilter::ByCapMatch( dependency ),
+ functor::functorRef<bool,CapAndItem>(info) );
_XDEBUG("requirementIsPossible( " << dependency << ") = " << (info.flag ? "Y" : "N"));
return info.flag;
}
-struct FindObsoletes : public resfilter::OnCapMatchCallbackFunctor
+struct FindObsoletes
{
bool obsoletes;
: obsoletes (false)
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
obsoletes = true; // we have a match
return false; // stop looping here
FindObsoletes info;
invokeOnEach( _pool.byCapabilityIndexBegin( cap.index(), dep ),
_pool.byCapabilityIndexEnd( cap.index(), dep ),
- resfilter::callOnCapMatchIn( dep, cap, functor::functorRef<bool,PoolItem_Ref,Capability>(info) ) );
+ resfilter::ByCapMatch( cap ),
+ functor::functorRef<bool,CapAndItem>(info) );
_DEBUG((info.obsoletes ? "YES" : "NO"));
return info.obsoletes;
// find all available providers for installed name
-struct FindProviders : public resfilter::OnCapMatchCallbackFunctor
+struct FindProviders
{
PoolItemSet providers; // the providers which matched
FindProviders ()
{ }
- bool operator()( PoolItem_Ref provider, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
+ PoolItem provider( cai.item );
if ( provider.status().isToBeUninstalled() ) {
- MIL << " IGNORE relation match (package is tagged to delete): " << match << " ==> " << provider << endl;
+ MIL << " IGNORE relation match (package is tagged to delete): " << cai.cap << " ==> " << provider << endl;
}
else {
- MIL << " relation match: " << match << " ==> " << provider << endl;
+ MIL << " relation match: " << cai.cap << " ==> " << provider << endl;
providers.insert (provider);
}
return true;
Capability installedCap = factory.parse ( installed->kind(), installed->name(), Rel::EQ, installed->edition());
FindProviders info;
-#if 0
+
invokeOnEach( _pool.byCapabilityIndexBegin( installed->name(), dep ),
_pool.byCapabilityIndexEnd( installed->name(), dep ),
- resfilter::ByUninstalled (),
- resfilter::callOnCapMatchIn( dep, installedCap, functor::functorRef<bool,PoolItem,Capability>(info) ) );
-#endif
- ResPool::const_indexiterator pend = pool().providesend(installed->name());
- for (ResPool::const_indexiterator it = pool().providesbegin(installed->name()); it != pend; ++it) {
- if (it->second.second.status().staysUninstalled()
- && installedCap.matches (it->second.first) == CapMatch::yes) {
- if (!info( it->second.second, it->second.first))
- break;
- }
- }
+ functor::chain( resfilter::ByCaIUninstalled (),
+ resfilter::ByCapMatch( installedCap ) ),
+ functor::functorRef<bool,CapAndItem>(info) );
int num_providers = info.providers.size();
}
}
-struct AllRequires : public resfilter::OnCapMatchCallbackFunctor
+struct AllRequires
{
PoolItemList requirers;
- bool operator()( PoolItem_Ref requirer, const Capability & match )
+ bool operator()( const CapAndItem & cai )
{
- DBG << requirer << " requires " << match << endl;
- requirers.push_back (requirer);
+ DBG << cai.item << " requires " << cai.cap << endl;
+ requirers.push_back( cai.item );
return true;
}
invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
_pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ), // end()
- resfilter::callOnCapMatchIn( dep, misc_info->capability(),
- functor::functorRef<bool,PoolItem,Capability>(info)) );
+ resfilter::ByCapMatch( misc_info->capability() ),
+ functor::functorRef<bool,CapAndItem>(info) );
if (info.requirers.size() > 1)
problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
RpmRemovePackageReceiver progress(it->resolvable());
progress.connect();
try {
- rpm().removePackage(p);
+ rpm().removePackage( p );
}
catch (Exception & excpt_r) {
ZYPP_CAUGHT(excpt_r);
WAR << "Remove failed, retrying with --nodeps" << endl;
try {
- rpm().removePackage(p, rpm::RpmDb::RPMINST_NODEPS);
+ rpm().removePackage( p, rpm::RpmDb::RPMINST_NODEPS);
}
catch (Exception & excpt_r) {
ZYPP_CAUGHT(excpt_r);