Regarding keep state while recycle old valid solver results. Bug 286889
authorStefan Schubert <schubi@suse.de>
Wed, 12 Sep 2007 13:48:13 +0000 (13:48 +0000)
committerStefan Schubert <schubi@suse.de>
Wed, 12 Sep 2007 13:48:13 +0000 (13:48 +0000)
zypp/ResFilters.h
zypp/solver/detail/ContextPool.cc
zypp/solver/detail/ContextPool.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/ResolverContext.h

index 9ba0030..8ee8952 100644 (file)
@@ -338,6 +338,16 @@ namespace zypp
       }
     };
 
+    /** Select PoolItem by keep. */
+    struct ByKeep : public PoolItemFilterFunctor
+    {
+      bool operator()( const PoolItem & p ) const
+      {
+       return p.status().isKept();
+      }
+    };
+      
+
 
     ///////////////////////////////////////////////////////////////////
 
index e457047..c5a6e98 100644 (file)
@@ -80,7 +80,8 @@ ContextPool::~ContextPool()
 void ContextPool::addContext (ResolverContext_Ptr context,
                              const PoolItemList & installItems,
                              const PoolItemList & deleteItems,
-                             const PoolItemList & lockUninstalledItems)
+                             const PoolItemList & lockUninstalledItems,
+                             const PoolItemList & keepItems)
 {
     if ((installItems.size() == 0
        && deleteItems.size() == 0)
@@ -93,7 +94,8 @@ void ContextPool::addContext (ResolverContext_Ptr context,
     
     new_context->setUserInstallItems (installItems);
     new_context->setUserDeleteItems (deleteItems);
-    new_context->setUserLockUninstalledItems (lockUninstalledItems);    
+    new_context->setUserLockUninstalledItems (lockUninstalledItems);
+    new_context->setUserKeepItems (keepItems);    
     
     if (contextList.size() <= 0) {
        contextList.push_front (new_context);
@@ -156,6 +158,23 @@ void ContextPool::addContext (ResolverContext_Ptr context,
                    }
                }
            }
+
+           // checking keep items
+           left = (*it)->userKeepItems();
+           right = context->userKeepItems();
+           if (left.size() != right.size())
+               continue;
+           found = true;           
+           for (PoolItemList::iterator itleft = left.begin();
+                (itleft != left.end()) && found ; ++itleft) {
+               found = false;
+               for (PoolItemList::iterator itright = right.begin(); itright != right.end(); ++itright) {
+                   if (*itleft == *itright) {
+                       found = true;
+                       break;
+                   }
+               }
+           }
            
            if (found) {
                exists = true;
@@ -186,7 +205,9 @@ void ContextPool::addContext (ResolverContext_Ptr context,
     _XDEBUG("   deleted:");
     dumpTaskList (new_context->userDeleteItems());
     _XDEBUG("   locked:");
-    dumpTaskList (new_context->userLockUninstalledItems());    
+    dumpTaskList (new_context->userLockUninstalledItems());
+    _XDEBUG("   keep:");
+    dumpTaskList (new_context->userKeepItems());    
 #if 0
     _XDEBUG("CONTEXT : " << endl << *new_context );
 #endif
@@ -207,7 +228,8 @@ void ContextPool::addContext (ResolverContext_Ptr context,
 
 ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
                                              PoolItemList & deleteItems,
-                                             const PoolItemList & lockUninstalledItems)
+                                             const PoolItemList & lockUninstalledItems,
+                                             const PoolItemList & keepItems)
 {
     // searching for context with same entries
     int counter = 1;
@@ -215,7 +237,8 @@ ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
 
        PoolItemList contextInstall = (*it)->userInstallItems();
        PoolItemList contextDelete = (*it)->userDeleteItems();
-       PoolItemList contextLockUninstalled = (*it)->userLockUninstalledItems();                
+       PoolItemList contextLockUninstalled = (*it)->userLockUninstalledItems();
+       PoolItemList contextKeep = (*it)->userKeepItems();                      
        
        _XDEBUG("ContextPool::findContext() trying " << counter++ << ". of " <<  contextList.size() );  
        _XDEBUG("   comparing");
@@ -225,6 +248,9 @@ ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
        dumpTaskList (contextDelete);
        _XDEBUG("      lockedUninstalled:");    
        dumpTaskList (contextLockUninstalled);
+       _XDEBUG("      keep:"); 
+       dumpTaskList (contextKeep);
+       
        
        _XDEBUG("   with needed");
        _XDEBUG("      installed:");
@@ -233,10 +259,13 @@ ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
        dumpTaskList (deleteItems);
        _XDEBUG("      lockedUninstalled:");    
        dumpTaskList (lockUninstalledItems);
+       _XDEBUG("      keep:"); 
+       dumpTaskList (keepItems);
        
        if (contextInstall.size() > installItems.size()
            || contextDelete.size() > deleteItems.size()
-           || contextLockUninstalled.size() != lockUninstalledItems.size())
+           || contextLockUninstalled.size() != lockUninstalledItems.size()
+           || contextKeep.size() != keepItems.size())
            continue; // cannot fit at all
 
        bool found = true;              
@@ -257,6 +286,21 @@ ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
        }
        if (!found) continue;
 
+       // check if the keep items are the same.
+       // If not --> try the next context
+       for (PoolItemList::iterator itContext = contextKeep.begin();
+            (itContext != contextKeep.end()) && found; ++itContext) {
+           found = false;
+           for (PoolItemList::const_iterator itInstall = keepItems.begin();
+                itInstall != keepItems.end(); ++itInstall) {
+               if (*itContext == *itInstall) {
+                   found = true;
+                   break;
+               }
+           }
+       }
+       if (!found) continue;   
+
        // checking items which will be installed
        PoolItemList addInsItems = installItems;
        for (PoolItemList::iterator itContext = contextInstall.begin();
index 59a228c..a23f35e 100644 (file)
@@ -94,12 +94,14 @@ class ContextPool : public base::ReferenceCounted, private base::NonCopyable {
      * @param installItems List of items which are selected by the user
      * @param deleteItems List of items which are selected by the user
      * @param lockUninstalledItems List of items which are selected by the user
+     * @param keepItems List of items which are selected by the user
      *
      * */         
     void addContext (ResolverContext_Ptr context,
                     const PoolItemList & installItems,
                     const PoolItemList & deleteItems,
-                    const PoolItemList & lockUninstalledItems);
+                    const PoolItemList & lockUninstalledItems,
+                    const PoolItemList & keepItems);
     /** 
      * Find a solver result in order to use it for the next solver run.
      *
@@ -107,11 +109,13 @@ class ContextPool : public base::ReferenceCounted, private base::NonCopyable {
      * @param installItems List of items which are selected by the user
      * @param deleteItems List of items which are selected by the user
      * @param lockUninstalledItems List of items which are selected by the user
+     * @param keepItems List of items which are selected by the user     
      * @return solver context
      * */             
     ResolverContext_Ptr findContext (PoolItemList & installItems,
                                     PoolItemList & deleteItems,
-                                    const PoolItemList & lockUninstalledItems);
+                                    const PoolItemList & lockUninstalledItems,
+                                    const PoolItemList & keepItems);
 
     /** 
      * Delete all sucessful solver run.
index 132fe9a..36ff4df 100644 (file)
@@ -151,6 +151,7 @@ Resolver::reset (bool resetValidResults, bool keepExtras )
     _items_to_remove.clear();
     _items_to_verify.clear();
     _items_to_establish.clear();
+    _items_to_keep.clear();
 
     if (!keepExtras) {
       _extra_caps.clear();
@@ -374,6 +375,12 @@ Resolver::addPoolItemToLockUninstalled (PoolItem_Ref item)
     _items_to_lockUninstalled.unique ();
 }
 
+void
+Resolver::addPoolItemToKepp (PoolItem_Ref item)
+{
+    _items_to_keep.push_back (item);
+    _items_to_keep.unique ();          
+}
 
 void
 Resolver::addPoolItemToEstablish (PoolItem_Ref item)
@@ -1221,6 +1228,12 @@ struct CollectTransact : public resfilter::PoolItemFilterFunctor
             resolver.addPoolItemToLockUninstalled (item);
         }
 
+        if (status.isKept()
+            && !by_solver) {
+           // collecting all keep states
+           resolver.addPoolItemToKepp (item);
+       }
+
        return true;
     }
 };
@@ -1237,9 +1250,11 @@ show_pool( ResPool pool )
 
        if (!full_pool_shown                                    // show item if not shown all before
            || it->status().transacts()                         // or transacts
+           || it->status().isKept()
+           || it->status().isLocked()
            || !it->status().isUndetermined())                  // or established status
        {
-           _DEBUG( count << ": " << *it );
+           _XDEBUG( count << ": " << *it );
        }
     }
     _XDEBUG( "---------------------------------------" );
@@ -1312,13 +1327,19 @@ Resolver::resolvePool( bool tryAllPossibilities )
     invokeOnEach ( _pool.begin(), _pool.end(),
                    resfilter::ByLock( ),                        // collect locks from Pool to resolver queue
                    functor::functorRef<bool,PoolItem>(info) );
+
+    invokeOnEach ( _pool.begin(), _pool.end(),
+                   resfilter::ByKeep( ),                        // collect keeps from Pool to resolver queue
+                   functor::functorRef<bool,PoolItem>(info) );    
+    
     // List of installing/removing items of the complete run (not regarding a recycled solver run)
     PoolItemList _completeItems_to_install = _items_to_install;
     PoolItemList _completeItems_to_remove = _items_to_remove;
     PoolItemList _completeItems_to_lockUninstalled = _items_to_lockUninstalled;
+    PoolItemList _completeItems_to_keep = _items_to_keep;
 
     // We have to find a valid context in order to recycle it.
-    saveContext = contextPool.findContext (_items_to_install, _items_to_remove, _items_to_lockUninstalled);
+    saveContext = contextPool.findContext (_items_to_install, _items_to_remove, _items_to_lockUninstalled, _items_to_keep);
     // _items_to_install, _items_to_remove contains addition items which has been selected but are
     // not solved with that context. They will be solved now.
     // If we have not found any former fitting context, saveContext is NULL. So the solver
@@ -1342,7 +1363,9 @@ Resolver::resolvePool( bool tryAllPossibilities )
        show_pool( _pool );
 #endif
         // insert best_context in ContextPool for further solver runs
-        contextPool.addContext( solution,_completeItems_to_install, _completeItems_to_remove, _completeItems_to_lockUninstalled);
+        contextPool.addContext( solution,_completeItems_to_install, _completeItems_to_remove,
+                               _completeItems_to_lockUninstalled,
+                               _completeItems_to_keep);
 
     }
     else {
index c5a6507..1ee723f 100644 (file)
@@ -110,6 +110,7 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     PoolItemList _items_to_remove;
     PoolItemList _items_to_verify;
     PoolItemList _items_to_lockUninstalled;
+    PoolItemList _items_to_keep;    
 
     // pool of valid contexts which are "recycled" in order to fasten the solver
     ContextPool contextPool;
@@ -216,6 +217,7 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     void addPoolItemsToInstallFromList (PoolItemList & rl);
 
     void addPoolItemToLockUninstalled (PoolItem_Ref item);
+    void addPoolItemToKepp (PoolItem_Ref item);
 
     void addPoolItemToRemove (PoolItem_Ref item);
     void addPoolItemsToRemoveFromList (PoolItemList & rl);
index 15d1d4d..09e44ba 100644 (file)
@@ -108,6 +108,7 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
     PoolItemList _userDeleteItems;
     PoolItemList _userInstallItems;
     PoolItemList _userLockUninstalledItems;
+    PoolItemList _userKeepItems;    
 
     bool _forceResolve; // remove items which are conflicts with others or
                         // have unfulfilled requirements.
@@ -199,9 +200,11 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
     void setUserDeleteItems ( const PoolItemList & deleteItems) { _userDeleteItems = deleteItems; }
     void setUserInstallItems ( const PoolItemList& installItems) { _userInstallItems = installItems; }
     void setUserLockUninstalledItems ( const PoolItemList& lockItems) { _userLockUninstalledItems = lockItems; }
+    void setUserKeepItems ( const PoolItemList& keepItems) { _userKeepItems = keepItems; }    
     PoolItemList userDeleteItems () { return _userDeleteItems; }
     PoolItemList userInstallItems () { return _userInstallItems; }
     PoolItemList userLockUninstalledItems () { return _userLockUninstalledItems; }
+    PoolItemList userKeepItems () { return _userKeepItems; }    
     
     // ---------------------------------- methods