- Added new calls : isInstalledBy (const PoolItem item);
authorStefan Schubert <schubi@suse.de>
Fri, 16 May 2008 14:45:32 +0000 (14:45 +0000)
committerStefan Schubert <schubi@suse.de>
Fri, 16 May 2008 14:45:32 +0000 (14:45 +0000)
                    installs (const PoolItem item);

VERSION.cmake
zypp/Resolver.cc
zypp/Resolver.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/SATResolver.cc
zypp/solver/detail/SATResolver.h

index 3588388..80ea36e 100644 (file)
@@ -45,6 +45,6 @@
 #
 
 SET(LIBZYPP_MAJOR "4")
-SET(LIBZYPP_MINOR "22")
+SET(LIBZYPP_MINOR "23")
 SET(LIBZYPP_COMPATMINOR "21")
 SET(LIBZYPP_PATCH "0")
index 5140453..4f893fa 100644 (file)
@@ -109,6 +109,10 @@ namespace zypp
   bool Resolver::createSolverTestcase (const std::string & dumpPath)
   { solver::detail::Testcase testcase (dumpPath);
     return testcase.createTestcase(*_pimpl);}
+  const solver::detail::ItemCapKindList Resolver::isInstalledBy (const PoolItem item)
+  { return _pimpl->isInstalledBy (item); }
+  const solver::detail::ItemCapKindList Resolver::installs (const PoolItem item)
+  { return _pimpl->installs (item); }
 
 
   /////////////////////////////////////////////////////////////////
index 3421af1..1f7eca9 100644 (file)
@@ -216,8 +216,33 @@ namespace zypp
      */
     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;
index cc59968..a3e9fab 100644 (file)
@@ -102,6 +102,9 @@ Resolver::reset (bool keepExtras )
       _extra_requires.clear();
       _extra_conflicts.clear();
     }
+
+    _isInstalledBy.clear();
+    _installs.clear();
 }
 
 void
@@ -288,6 +291,11 @@ Resolver::solverInit()
 
        if (_verifying)
            _satResolver->setFixsystem(true);
+
+       // Resetting additional solver information
+       _isInstalledBy.clear();
+       _installs.clear();
+       
 }
 
 bool
@@ -420,6 +428,165 @@ bool Resolver::checkUnmaintainedItems () {
 }
 
 
+//----------------------------------------------------------------------------
+// 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
     /////////////////////////////////////////////////////////////////////
index a965b82..ab27c8f 100644 (file)
@@ -58,6 +58,32 @@ namespace zypp
     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
@@ -94,11 +120,16 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     // 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.
@@ -160,7 +191,14 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     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);
+    
     
 };
 
index cddfbe2..1c0870b 100644 (file)
@@ -444,12 +444,8 @@ SATResolver::solving()
 
     // 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++)
@@ -464,6 +460,7 @@ SATResolver::solving()
       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;
       }
@@ -489,6 +486,7 @@ SATResolver::solving()
          } else {
              SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
          }
+         _result_items_to_remove.push_back (poolItem);   
       } else {
          ERR << "id " << i << " not found in ZYPP pool." << endl;
       }
@@ -557,6 +555,13 @@ SATResolver::solving()
            _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);    
index 36a4319..7386347 100644 (file)
@@ -69,7 +69,11 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     PoolItemList _items_to_install;
     PoolItemList _items_to_remove;
     PoolItemList _items_to_lock;
-    PoolItemList _items_to_keep;    
+    PoolItemList _items_to_keep;
+
+    // solve results
+    PoolItemList _result_items_to_install;
+    PoolItemList _result_items_to_remove;
 
     bool _fixsystem;                   // repair errors in rpm dependency graph 
     bool _allowdowngrade;              // allow to downgrade installed solvable 
@@ -160,6 +164,10 @@ class SATResolver : public base::ReferenceCounted, private base::NonCopyable {
     void setOnlyRequires ( const bool onlyRequires) { _onlyRequires = onlyRequires;}
 
     bool doesObsoleteItem (PoolItem candidate, PoolItem installed);
+
+    PoolItemList resultItemsToInstall () { return _result_items_to_install; }
+    PoolItemList resultItemsToRemove () { return _result_items_to_remove; }
+    
 };
 
 ///////////////////////////////////////////////////////////////////