*/
bool createSolverTestcase (const std::string & dumpPath = "/var/log/YaST2/solverTestcase");
+ /**
+ * Gives information about WHO has pused an installation of an given item.
+ *
+ * \param item Evaluate additional information for this resolvable.
+ * \return A list of structures which contains:
+ * item Item which has triggered the installation of the given param item.
+ * cap Capability which has triggerd this installation
+ * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... )
+ *
+ * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid.
+ *
+ */
+ const solver::detail::ItemCapKindList isInstalledBy (const PoolItem item);
- protected:
+ /**
+ * Gives information about WHICH additional items will be installed due the installation of an item.
+ *
+ * \param item Evaluate additional information for this resolvable.
+ * \return A list of structures which contains:
+ * item Item which will be installed due to the installation of the given param item too.
+ * cap Capability which causes the installation
+ * capKind Kind of that capability (e.g. Dep::REQUIRES,Dep::RECOMMENDS,... )
+ *
+ * Note: In order to have a result start a solver run before. Not matter if it is valid or invalid.
+ *
+ */
+ const solver::detail::ItemCapKindList installs (const PoolItem item);
private:
solver::detail::Resolver_Ptr _pimpl;
_extra_requires.clear();
_extra_conflicts.clear();
}
+
+ _isInstalledBy.clear();
+ _installs.clear();
}
void
if (_verifying)
_satResolver->setFixsystem(true);
+
+ // Resetting additional solver information
+ _isInstalledBy.clear();
+ _installs.clear();
+
}
bool
}
+//----------------------------------------------------------------------------
+// Getting more information about the solve results
+
+
+void
+Resolver::collectResolverInfo(void)
+{
+ if ( _satResolver
+ && _isInstalledBy.empty()
+ && _installs.empty()) {
+
+ // generating new
+ PoolItemList itemsToInstall = _satResolver->resultItemsToInstall();
+
+ for (PoolItemList::const_iterator instIter = itemsToInstall.begin();
+ instIter != itemsToInstall.end(); instIter++) {
+
+ // Requires
+ for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::REQUIRES).begin(); capIt != (*instIter)->dep (Dep::REQUIRES).end(); ++capIt)
+ {
+ sat::WhatProvides possibleProviders(*capIt);
+ for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+ PoolItem provider = ResPool::instance().find( *iter );
+
+ // searching if this provider will already be installed
+ bool found = false;
+ bool alreadySetForInstallation = false;
+ ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
+ while (pos != _isInstalledBy.end()
+ && pos->first == provider
+ && !found) {
+ alreadySetForInstallation = true;
+ ItemCapKind capKind = pos->second;
+ if (capKind.item == *instIter) found = true;
+ pos++;
+ }
+
+ if (!found
+ && provider.status().isToBeInstalled()) {
+ if (provider.status().isBySolver()) {
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ } else {
+ // no initial installation cause it has been set be e.g. user
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, false );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ }
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
+ _installs.insert (make_pair( *instIter, capKindisInstalledBy));
+ }
+ }
+ }
+
+ //Recommends
+ for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt)
+ {
+ sat::WhatProvides possibleProviders(*capIt);
+ for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+ PoolItem provider = ResPool::instance().find( *iter );
+
+ // searching if this provider will already be installed
+ bool found = false;
+ bool alreadySetForInstallation = false;
+ ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
+ while (pos != _isInstalledBy.end()
+ && pos->first == provider
+ && !found) {
+ alreadySetForInstallation = true;
+ ItemCapKind capKind = pos->second;
+ if (capKind.item == *instIter) found = true;
+ pos++;
+ }
+
+ if (!found
+ && provider.status().isToBeInstalled()) {
+ if (provider.status().isBySolver()) {
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ } else {
+ // no initial installation cause it has been set be e.g. user
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, false );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ }
+ ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
+ _installs.insert (make_pair( *instIter, capKindisInstalledBy));
+ }
+ }
+ }
+
+ //Suggests
+ for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUGGESTS).begin(); capIt != (*instIter)->dep (Dep::SUGGESTS).end(); ++capIt)
+ {
+ sat::WhatProvides possibleProviders(*capIt);
+ for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
+ PoolItem provider = ResPool::instance().find( *iter );
+
+ // searching if this provider will already be installed
+ bool found = false;
+ bool alreadySetForInstallation = false;
+ ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
+ while (pos != _isInstalledBy.end()
+ && pos->first == provider
+ && !found) {
+ alreadySetForInstallation = true;
+ ItemCapKind capKind = pos->second;
+ if (capKind.item == *instIter) found = true;
+ pos++;
+ }
+
+ if (!found) {
+ ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUGGESTS, !alreadySetForInstallation );
+ _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
+ }
+ }
+ }
+ }
+ }
+}
+
+
+const ItemCapKindList Resolver::isInstalledBy (const PoolItem item) {
+ ItemCapKindList ret;
+ collectResolverInfo();
+
+ for (ItemCapKindMap::const_iterator iter = _isInstalledBy.find(item); iter != _isInstalledBy.end();) {
+ ItemCapKind info = iter->second;
+ PoolItem iterItem = iter->first;
+ if (iterItem == item) {
+ ret.push_back(info);
+ iter++;
+ } else {
+ // exit
+ iter = _isInstalledBy.end();
+ }
+ }
+ return ret;
+}
+
+const ItemCapKindList Resolver::installs (const PoolItem item) {
+ ItemCapKindList ret;
+ collectResolverInfo();
+
+ for (ItemCapKindMap::const_iterator iter = _installs.find(item); iter != _installs.end();) {
+ ItemCapKind info = iter->second;
+ PoolItem iterItem = iter->first;
+ if (iterItem == item) {
+ ret.push_back(info);
+ iter++;
+ } else {
+ // exit
+ iter = _installs.end();
+ }
+ }
+ return ret;
+}
+
+
+
+
///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
class SATResolver;
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ItemCapKind
+ //
+ /** */
+ struct ItemCapKind
+ {
+ public:
+ Capability cap; //Capability which has triggerd this selection
+ Dep capKind; //Kind of that capability
+ PoolItem item; //Item which has triggered this selection
+ bool initialInstallation; //This item has triggered the installation
+ //Not already fullfilled requierement only.
+
+ ItemCapKind() : capKind("FRESHENS") {}
+ ItemCapKind( PoolItem i, Capability c, Dep k, bool initial)
+ : cap( c )
+ , capKind( k )
+ , item( i )
+ , initialInstallation( initial )
+ { }
+ };
+ typedef std::multimap<PoolItem,ItemCapKind> ItemCapKindMap;
+ typedef std::list<ItemCapKind> ItemCapKindList;
+
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Resolver
// Additional QueueItems which has to be regarded by the solver
// This will be used e.g. by solution actions
solver::detail::SolverQueueItemList _removed_queue_items;
- solver::detail::SolverQueueItemList _added_queue_items;
+ solver::detail::SolverQueueItemList _added_queue_items;
+
+ // Additional information about the solverrun
+ ItemCapKindMap _isInstalledBy;
+ ItemCapKindMap _installs;
// helpers
bool doesObsoleteCapability (PoolItem candidate, const Capability & cap);
bool doesObsoleteItem (PoolItem candidate, PoolItem installed);
+ void collectResolverInfo (void);
// Unmaintained packages which does not fit to the updated system
// (broken dependencies) will be deleted.
void reset (bool keepExtras = false );
bool testing(void) const { return _testing; }
- void setTesting( bool testing ) { _testing = testing; }
+ void setTesting( bool testing ) { _testing = testing; }
+
+ // Get more information about the solverrun
+ // Which item will be installed by another item or triggers an item for
+ // installation
+ const ItemCapKindList isInstalledBy (const PoolItem item);
+ const ItemCapKindList installs (const PoolItem item);
+
};
// copying solution back to zypp pool
//-----------------------------------------
-
- if (_solv->problems.count > 0 )
- {
- ERR << "Solverrun finished with an ERROR" << endl;
- return false;
- }
+ _result_items_to_install.clear();
+ _result_items_to_remove.clear();
/* solvables to be installed */
for (int i = 0; i < _solv->decisionq.count; i++)
PoolItem poolItem = _pool.find (sat::Solvable(p));
if (poolItem) {
SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
+ _result_items_to_install.push_back (poolItem);
} else {
ERR << "id " << p << " not found in ZYPP pool." << endl;
}
} else {
SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
}
+ _result_items_to_remove.push_back (poolItem);
} else {
ERR << "id " << i << " not found in ZYPP pool." << endl;
}
_XDEBUG("SATSolutionToPool(" << item << " ) broken !");
}
}
+
+ if (_solv->problems.count > 0 )
+ {
+ ERR << "Solverrun finished with an ERROR" << endl;
+ return false;
+ }
+
map_free(&installedmap);
queue_free(&(solvableQueue));
queue_free(&flags);