ContextPool.cc

Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /* ResolverQueue.cc
00003  *
00004  * Copyright (C) 2007 SUSE Linux Products GmbH
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License,
00008  * version 2, as published by the Free Software Foundation.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018  * 02111-1307, USA.
00019  */
00020 
00021 #include "zypp/base/Logger.h"
00022 #include "zypp/solver/detail/ContextPool.h"
00023 #include "zypp/solver/detail/ResolverContext.h"
00024 
00026 namespace zypp
00027 { 
00028 
00029   namespace solver
00030   { 
00031 
00032     namespace detail
00033     { 
00034 
00035 using namespace std;
00036 
00037 IMPL_PTR_TYPE(ContextPool);
00038         
00039 #define MAXCONTEXT 10
00040 
00041 //---------------------------------------------------------------------------
00042 
00043 void  dumpTaskList(const PoolItemList &list )
00044 {
00045     for (PoolItemList::const_iterator iter = list.begin();
00046          iter != list.end(); iter++) {
00047         XXX << "          " << *iter << endl;
00048     }
00049 }
00050 
00051 //---------------------------------------------------------------------------
00052 
00053 ostream&
00054 operator<<( ostream& os, const ContextPool & contextPool)
00055 {
00056     os << str::form ("ContextPool [entries: %d]", contextPool.contextListSize()) << endl;
00057     return os;
00058 }
00059 
00060 //---------------------------------------------------------------------------
00061 
00062 ContextPool::ContextPool (const int maxCount)
00063     : maxContext (maxCount)
00064 {
00065     _XDEBUG("ContextPool::ContextPool(" << maxContext << ")");
00066 }
00067 
00068 
00069 ContextPool::ContextPool ()
00070     : maxContext (MAXCONTEXT)
00071 {
00072     _XDEBUG("ContextPool::ContextPool(" << MAXCONTEXT << ")");
00073 }
00074 
00075 ContextPool::~ContextPool()
00076 {
00077 }
00078 
00079 //---------------------------------------------------------------------------
00080 void ContextPool::addContext (ResolverContext_Ptr context,
00081                               const PoolItemList & installItems,
00082                               const PoolItemList & deleteItems,
00083                               const PoolItemList & lockUninstalledItems,
00084                               const PoolItemList & keepItems)
00085 {
00086     if ((installItems.size() == 0
00087         && deleteItems.size() == 0)
00088         || context == NULL )
00089         return; // empty context is useless
00090 
00091     // make an copy
00092     ResolverContext_Ptr new_context = new ResolverContext (context->pool(), context->architecture(),
00093                                                            context);
00094     
00095     new_context->setUserInstallItems (installItems);
00096     new_context->setUserDeleteItems (deleteItems);
00097     new_context->setUserLockUninstalledItems (lockUninstalledItems);
00098     new_context->setUserKeepItems (keepItems);    
00099     
00100     if (contextList.size() <= 0) {
00101         contextList.push_front (new_context);
00102     } else {
00103         // does context already exists in the list ?
00104         bool exists = false;
00105 
00106         for ( ResolverContextList::iterator it = contextList.begin(); it != contextList.end(); ++it ) {
00107             // checking installed items
00108             PoolItemList left = (*it)->userInstallItems();
00109             PoolItemList right = context->userInstallItems();
00110             if (left.size() != right.size())
00111                 continue;
00112             bool found = true;      
00113             for (PoolItemList::iterator itleft = left.begin();
00114                  (itleft != left.end()) && found ; ++itleft) {
00115                 found = false;
00116                 for (PoolItemList::iterator itright = right.begin(); itright != right.end(); ++itright) {
00117                     if (*itleft == *itright) {
00118                         found = true;
00119                         break;
00120                     }
00121                 }
00122             }
00123 
00124             if (!found ) continue;
00125             
00126             // checking deleted items
00127             left = (*it)->userDeleteItems();
00128             right = context->userDeleteItems();
00129             if (left.size() != right.size())
00130                 continue;
00131             found = true;           
00132             for (PoolItemList::iterator itleft = left.begin();
00133                  (itleft != left.end()) && found ; ++itleft) {
00134                 found = false;
00135                 for (PoolItemList::iterator itright = right.begin(); itright != right.end(); ++itright) {
00136                     if (*itleft == *itright) {
00137                         found = true;
00138                         break;
00139                     }
00140                 }
00141             }
00142 
00143             if (!found ) continue;
00144             
00145             // checking locked items
00146             left = (*it)->userLockUninstalledItems();
00147             right = context->userLockUninstalledItems();
00148             if (left.size() != right.size())
00149                 continue;
00150             found = true;           
00151             for (PoolItemList::iterator itleft = left.begin();
00152                  (itleft != left.end()) && found ; ++itleft) {
00153                 found = false;
00154                 for (PoolItemList::iterator itright = right.begin(); itright != right.end(); ++itright) {
00155                     if (*itleft == *itright) {
00156                         found = true;
00157                         break;
00158                     }
00159                 }
00160             }
00161 
00162             // checking keep items
00163             left = (*it)->userKeepItems();
00164             right = context->userKeepItems();
00165             if (left.size() != right.size())
00166                 continue;
00167             found = true;           
00168             for (PoolItemList::iterator itleft = left.begin();
00169                  (itleft != left.end()) && found ; ++itleft) {
00170                 found = false;
00171                 for (PoolItemList::iterator itright = right.begin(); itright != right.end(); ++itright) {
00172                     if (*itleft == *itright) {
00173                         found = true;
00174                         break;
00175                     }
00176                 }
00177             }
00178             
00179             if (found) {
00180                 exists = true;
00181                 break;
00182             }
00183         }
00184 
00185         if (!exists) {
00186             contextList.push_front (new_context);
00187         } else {
00188             _XDEBUG("----------------------");    
00189             _XDEBUG("ContextPool::addContext Context ALREADY INSERTED ");
00190             _XDEBUG("----------------------");
00191         }
00192     }
00193 
00194     if (contextList.size() > 0
00195         && contextList.size() > maxContext)
00196     {
00197         // keep max size
00198         contextList.remove (contextList.back());
00199     }
00200 
00201     _XDEBUG("----------------------");    
00202     _XDEBUG("ContextPool::addContext latest context with ");
00203     _XDEBUG("   installed:");
00204     dumpTaskList (new_context->userInstallItems());
00205     _XDEBUG("   deleted:");
00206     dumpTaskList (new_context->userDeleteItems());
00207     _XDEBUG("   locked:");
00208     dumpTaskList (new_context->userLockUninstalledItems());
00209     _XDEBUG("   keep:");
00210     dumpTaskList (new_context->userKeepItems());    
00211 #if 0
00212     _XDEBUG("CONTEXT : " << endl << *new_context );
00213 #endif
00214     _XDEBUG("----------------------");
00215 #if 0
00216     int count = 0;
00217     for ( ResolverContextList::iterator it = contextList.begin(); it != contextList.end(); ++it ) {
00218 
00219         PoolItemList contextInstall = (*it)->userInstallItems();
00220         _XDEBUG(" inserted CONTEXT Nr " << count++ << " of " << contextList.size() << " : " << endl << **it );          
00221         _XDEBUG(" with entries");
00222         dumpTaskList (contextInstall);
00223     _XDEBUG("----------------------");          
00224     }
00225 #endif
00226     
00227 }
00228 
00229 ResolverContext_Ptr ContextPool::findContext (PoolItemList & installItems,
00230                                               PoolItemList & deleteItems,
00231                                               const PoolItemList & lockUninstalledItems,
00232                                               const PoolItemList & keepItems)
00233 {
00234     // searching for context with same entries
00235     int counter = 1;
00236     for ( ResolverContextList::iterator it = contextList.begin(); it != contextList.end(); ++it ) {
00237 
00238         PoolItemList contextInstall = (*it)->userInstallItems();
00239         PoolItemList contextDelete = (*it)->userDeleteItems();
00240         PoolItemList contextLockUninstalled = (*it)->userLockUninstalledItems();
00241         PoolItemList contextKeep = (*it)->userKeepItems();                      
00242         
00243         _XDEBUG("ContextPool::findContext() trying " << counter++ << ". of " <<  contextList.size() );  
00244         _XDEBUG("   comparing");
00245         _XDEBUG("      installed:");    
00246         dumpTaskList (contextInstall);
00247         _XDEBUG("      deleted:");      
00248         dumpTaskList (contextDelete);
00249         _XDEBUG("      lockedUninstalled:");    
00250         dumpTaskList (contextLockUninstalled);
00251         _XDEBUG("      keep:"); 
00252         dumpTaskList (contextKeep);
00253         
00254         
00255         _XDEBUG("   with needed");
00256         _XDEBUG("      installed:");
00257         dumpTaskList (installItems);    
00258         _XDEBUG("      deleted:");      
00259         dumpTaskList (deleteItems);
00260         _XDEBUG("      lockedUninstalled:");    
00261         dumpTaskList (lockUninstalledItems);
00262         _XDEBUG("      keep:"); 
00263         dumpTaskList (keepItems);
00264         
00265         if (contextInstall.size() > installItems.size()
00266             || contextDelete.size() > deleteItems.size()
00267             || contextLockUninstalled.size() != lockUninstalledItems.size()
00268             || contextKeep.size() != keepItems.size())
00269             continue; // cannot fit at all
00270 
00271         bool found = true;              
00272         
00273         found = true;
00274         // check if the lock of unistalled items are the same.
00275         // If not --> try the next context
00276         for (PoolItemList::iterator itContext = contextLockUninstalled.begin();
00277              (itContext != contextLockUninstalled.end()) && found; ++itContext) {
00278             found = false;
00279             for (PoolItemList::const_iterator itInstall = lockUninstalledItems.begin();
00280                  itInstall != lockUninstalledItems.end(); ++itInstall) {
00281                 if (*itContext == *itInstall) {
00282                     found = true;
00283                     break;
00284                 }
00285             }
00286         }
00287         if (!found) continue;
00288 
00289         // check if the keep items are the same.
00290         // If not --> try the next context
00291         for (PoolItemList::iterator itContext = contextKeep.begin();
00292              (itContext != contextKeep.end()) && found; ++itContext) {
00293             found = false;
00294             for (PoolItemList::const_iterator itInstall = keepItems.begin();
00295                  itInstall != keepItems.end(); ++itInstall) {
00296                 if (*itContext == *itInstall) {
00297                     found = true;
00298                     break;
00299                 }
00300             }
00301         }
00302         if (!found) continue;   
00303 
00304         // checking items which will be installed
00305         PoolItemList addInsItems = installItems;
00306         for (PoolItemList::iterator itContext = contextInstall.begin();
00307              (itContext != contextInstall.end()) && found; ++itContext) {
00308             found = false;
00309             for (PoolItemList::iterator itInstall = addInsItems.begin();
00310                  itInstall != addInsItems.end(); ++itInstall) {
00311                 if (*itContext == *itInstall) {
00312                     found = true;
00313                     addInsItems.remove (*itInstall); 
00314                     break;
00315                 }
00316             }
00317         }
00318 
00319         PoolItemList addDelItems = deleteItems; 
00320         if (found) {
00321             // checking items which will be deleted
00322             PoolItemList addDelItems = deleteItems;
00323             for (PoolItemList::iterator itContext = contextDelete.begin();
00324                  (itContext != contextDelete.end()) && found; ++itContext) {
00325                 found = false;
00326                 for (PoolItemList::iterator itInstall = addDelItems.begin();
00327                      itInstall != addDelItems.end(); ++itInstall) {
00328                     if (*itContext == *itInstall) {
00329                         found = true;
00330                         addDelItems.remove (*itInstall); 
00331                         break;
00332                     }
00333                 }
00334             }
00335         }
00336         
00337         if (found) {
00338             if (addInsItems.size() > 0
00339                 || addDelItems.size() > 0) {
00340                 _XDEBUG("ContextPool::findContext() found one with following additional install/delete items: ");
00341                 _XDEBUG("      installed:");
00342                 dumpTaskList (addInsItems);     
00343                 _XDEBUG("      deleted:");      
00344                 dumpTaskList (addDelItems);
00345             } else {
00346                 _XDEBUG("ContextPool::findContext() found with the SAME selected entries. ");
00347             }
00348             installItems = addInsItems; // Rest of items which has to be installed additionally
00349             deleteItems = addDelItems; // Rest of items which has to be deleted additionally        
00350 #if 0
00351             _XDEBUG("----------------------");              
00352             _XDEBUG(" returned CONTEXT : " << endl << **it );
00353             _XDEBUG("----------------------");
00354 #endif
00355             return *it;
00356         }
00357     }
00358     // nothing found
00359     _XDEBUG("ContextPool::findContext() have not found a proper context. Solving completely");
00360     return NULL;
00361 }
00362 
00363 
00365     };// namespace detail
00368   };// namespace solver
00371 };// namespace zypp
00373 

Generated on Tue Sep 25 19:23:06 2007 for libzypp by  doxygen 1.5.3