New behaviour in the solver: try with 'best' package first, try with
authorStefan Schubert <schubi@suse.de>
Fri, 25 Aug 2006 11:10:51 +0000 (11:10 +0000)
committerStefan Schubert <schubi@suse.de>
Fri, 25 Aug 2006 11:10:51 +0000 (11:10 +0000)
'all' packages if this fails.
Bug :Bug 191983e und die folgenden Zeilen werden ignoriert --

M    libzypp/testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.xml
M    libzypp/testsuite/solver/data.deptestomatic/bugzilla-tests/ignore
M    libzypp/testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-test.solution
A    libzypp/testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.solution
M    libzypp/package/libzypp.changes
M    libzypp/zypp/solver/detail/Resolver.h
M    libzypp/zypp/solver/detail/ResolverContext.cc
M    libzypp/zypp/solver/detail/QueueItemRequire.cc
M    libzypp/zypp/solver/detail/Resolver.cc
M    libzypp/zypp/solver/detail/ResolverContext.h

package/libzypp.changes
testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.solution [new file with mode: 0644]
testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.xml
testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-test.solution
testsuite/solver/data.deptestomatic/bugzilla-tests/ignore
zypp/solver/detail/QueueItemRequire.cc
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/ResolverContext.cc
zypp/solver/detail/ResolverContext.h

index f3dbbdf38a1a24491f8cec52d4e48f7c1ee47b86..856a84a6dd6c49c8965aef9b984319f2b90d6a1e 100644 (file)
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------
+Fri Aug 25 13:05:33 CEST 2006 - schubi@suse.de
+
+- New behaviour in the solver: try with 'best' package first, try with 'all'
+  packages if this fails. 
+  Bug :Bug 191983
+
 -------------------------------------------------------------------
 Fri Aug 25 11:35:48 CEST 2006 - dmacvicar@suse.de
 
diff --git a/testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.solution b/testsuite/solver/data.deptestomatic/bugzilla-tests/bug191983-bare-test.solution
new file mode 100644 (file)
index 0000000..3740720
--- /dev/null
@@ -0,0 +1,15 @@
+>!> Installing apache2-mod_python from channel sles10
+>!> Installing apache2-prefork from channel sles10
+>!> 1 problems found:
+>!> Problem:
+>!> Cannot install apache2-2.2.0-21.2.i586[sles10]
+>!> Can't install apache2-2.2.0-21.2.i586[sles10], since apache2-2.2.2-5.i586[stable] is already marked as needing to be installed
+>!>    Solution:
+>!>       do not install apache2-2.2.0-21.2.i586[sles10]
+>!>       
+>!>    Solution:
+>!>       do not install apache2-2.2.2-5.i586[stable]
+>!>       
+>!>    Solution:
+>!>       Ignore that apache2 is already set to install
+>!>       
index 6af580a25d3f7a27aaf0f8d09cae25167bf3ab53..f1c08ae7d7e771f933ead7ff4d80e6eec405cc8f 100644 (file)
@@ -7,5 +7,6 @@
 <trial>
   <install channel="sles10" package="apache2-mod_python"/>
   <install channel="sles10" package="apache2-prefork"/>
+  <reportproblems/>
 </trial>
 </test>
index bc0e34a73c61cebc108345d2eaf0733e940f94af..1888c2592d0651e574f399d4e5de76a7638448ad 100644 (file)
 >!> install libapr-util1-1.2.2-13.2.i586[sles10]
 >!> install libapr1-1.2.2-13.2.i586[sles10]
 >!> installs=5, upgrades=0, uninstalls=0
->!> Solution #4:
->!> install apache2-2.2.0-21.2.i586[sles10]
->!> install apache2-mod_python-3.1.3-60.2.i586[sles10]
->!> install apache2-prefork-2.2.0-21.2.i586[sles10]
->!> install libapr-util1-1.2.7-3.i586[stable]
->!> install libapr1-1.2.2-13.2.i586[sles10]
->!> installs=5, upgrades=0, uninstalls=0
index 6e395dd0506e94b8b87b265e735e486a76c0298a..35e3d5df30820256402af99747e968ee487c5fb2 100644 (file)
@@ -1,5 +1,2 @@
-#currently there is no fix available
-bug191983-bare-test.xml
-bug191983-test.xml
 #have fix repo on machcd2
-bug186196-test.xml
\ No newline at end of file
+bug186196-test.xml
index 3ca178da09c9f087046e74a2a72a472296e8ea80..6a2404ebbb9bf299e558bdac846eea9eddaa3653 100644 (file)
@@ -221,32 +221,40 @@ struct RequireProcess
            }
 
 
-           // if we already have same name
-           //   check for better architecture, then edition
-           //   see yast2-pkg-bindings, Package.cc, ProvideProcess
-
-           UniqMap::iterator upos = uniq.find( provider->name() );
-           if (upos != uniq.end()) {
-               if ((upos->second->arch().compare( provider->arch() ) < 0)      // better arch
-                   || ((upos->second->arch().compare( provider->arch() ) == 0)             // or same arch
-                       && (upos->second->edition().compare( provider->edition() ) < 0) ) ) // and better edition
-               {
-                   // new provider is 'better'
-
-                   // erase the old provider
-                   for (PoolItemList::iterator it = providers.begin(); it != providers.end(); ++it) {
-                       if (*it == upos->second) {
-                           _XDEBUG("Kicking " << *it << " for " << provider)
-                           providers.erase( it );
-                           break;
-                       }
-                   } 
-                   upos = uniq.end();  // trigger insertion of new provider below
+           if (!_context->tryAllPossibilities()) {
+               // if we already have same name
+               //   check for better architecture, then edition
+               //   see yast2-pkg-bindings, Package.cc, ProvideProcess
+
+               UniqMap::iterator upos = uniq.find( provider->name() );
+
+               if (upos != uniq.end()) {
+                   if ((upos->second->arch().compare( provider->arch() ) < 0)  // better arch
+                       || ((upos->second->arch().compare( provider->arch() ) == 0)                 // or same arch
+                           && (upos->second->edition().compare( provider->edition() ) < 0) ) ) // and better edition
+                   {
+                       // new provider is 'better'
+
+                       // erase the old provider
+                       for (PoolItemList::iterator it = providers.begin(); it != providers.end(); ++it) {
+                           if (*it == upos->second) {
+                               _context->setScippedPossibilities( true ); // Flag that there are other possibilities
+                               // which we are currently ignore
+                               _XDEBUG("Kicking " << *it << " for " << provider)
+                                   providers.erase( it );
+                               break;
+                           }
+                       } 
+                       upos = uniq.end();      // trigger insertion of new provider below
+                   }
                }
-           }
-           if (upos == uniq.end()) {
+               if (upos == uniq.end()) {
+                   providers.push_front( provider );
+                   uniq[provider->name()] = provider;
+               }
+           } else {
+               // try all alternatives
                providers.push_front( provider );
-               uniq[provider->name()] = provider;
            }
        }
 
index 724066666e1bef5c330be39197b0b8df31e3005a..be160b524fb9308f77e4d28519fcf7456906b73c 100644 (file)
@@ -34,7 +34,8 @@
 #include "zypp/ZYppFactory.h"
 #include "zypp/SystemResObject.h"
 
-
+#define MAX_SECOND_RUNS 3
+#define TIMOUT_SECOND_RUN 30
 
 /////////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -96,6 +97,8 @@ Resolver::Resolver (const ResPool & pool)
     , _maxSolverPasses (0)
     , _verifying (false)
     , _testing (false)
+    , _tryAllPossibilities (false)
+    , _scippedPossibilities (false)
     , _valid_solution_count (0)
     , _best_context (NULL)
     , _timed_out (false)
@@ -142,6 +145,10 @@ Resolver::reset (void)
 
     _best_context = NULL;
     _timed_out = false;
+    
+    _tryAllPossibilities = false;
+    _scippedPossibilities = false;
+    
 }
 
 
@@ -670,6 +677,8 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
                                    _ignoreArchitectureItem);
     initial_queue->context()->setForceResolve( _forceResolve );
     initial_queue->context()->setUpgradeMode( _upgradeMode );
+    initial_queue->context()->setTryAllPossibilities( _tryAllPossibilities );
+    initial_queue->context()->setScippedPossibilities( _scippedPossibilities );
 
     /* If this is a verify, we do a "soft resolution" */
 
@@ -853,6 +862,44 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
                   << " / Prun " << (long) _pruned_queues.size()
                   << " / Defr " << (long) _deferred_queues.size()
                   << " / Invl " << (long) _invalid_queues.size() );
+    
+    
+    if ( !(_best_context && _best_context->isValid()) // no valid solution
+        && !_tryAllPossibilities ) { // a second run with ALL possibilities has not been tried
+
+       for (ResolverQueueList::iterator iter = _invalid_queues.begin();
+            iter != _invalid_queues.end(); iter++) {
+           // evaluate if there are other possibilities which have not been regarded
+           ResolverQueue_Ptr invalid = *iter;              
+           if (invalid->context()->scippedPossibilities()) {
+               _scippedPossibilities = true;
+               break;
+           }
+       }
+       
+       if (_scippedPossibilities) { // possible other solutions scipped         
+           // lets try a second run with ALL possibilities
+           _tryAllPossibilities = true;
+           MIL << "================================================================"
+               << endl;
+           MIL << "No valid solution, lets try a second run with ALL possibilities"
+               << endl;
+           if (_maxSolverPasses <= 0) 
+               _maxSolverPasses = MAX_SECOND_RUNS;         
+           if (_timeout_seconds <= 0) 
+               _timeout_seconds = TIMOUT_SECOND_RUN;
+
+           MIL << "But no longer than " << MAX_SECOND_RUNS << " runs or "
+               << TIMOUT_SECOND_RUN << " seconds" << endl;
+           MIL << "================================================================"
+               << endl;
+           // saving invalid queue
+           ResolverQueueList   save_queues = _invalid_queues;
+           resolveDependencies ();
+           if (!(_best_context && _best_context->isValid()))
+               _invalid_queues = save_queues; // take the old
+       }
+    }
 
     return _best_context && _best_context->isValid();
 }
index 0b459569593c7cbba430496fa64a3bfcd0d13585..5b49883d85b08f1782fe98e9621eed571c570511 100644 (file)
@@ -67,6 +67,15 @@ class Resolver : public base::ReferenceCounted, private base::NonCopyable {
     int _maxSolverPasses;
     bool _verifying;
     bool _testing;
+    
+    // In order reducing solver time we are reducing the branches
+    // by skipping resolvables which have worse architecture,edition
+    // than a resolvable which provides the same cababilities.
+    // BUT if there is no valid solution we will regard the "other"
+    // resolvables in a second solver run too.
+    bool _tryAllPossibilities; // Try ALL alternatives
+    bool _scippedPossibilities;// Flag that there are other possibilities
+                               // which we are currently ignore
 
     // list populated by calls to addPoolItemTo*()
     QueueItemList _initial_items;
index fc61861fa8712fbbb537b800c75dfbbffa731fd6..4add80dc25930c1dd3dc8a4368fc26e636e683f1 100644 (file)
@@ -99,6 +99,8 @@ ResolverContext::ResolverContext (const ResPool & pool, const Arch & arch, Resol
     , _architecture(arch)
     , _forceResolve(false)
     , _upgradeMode(false)
+    , _tryAllPossibilities(false)
+    , _scippedPossibilities(false)
       
 {
 _XDEBUG( "ResolverContext[" << this << "]::ResolverContext(" << parent << ")" );
@@ -119,6 +121,9 @@ _XDEBUG( "ResolverContext[" << this << "]::ResolverContext(" << parent << ")" );
        _ignoreArchitectureItem = parent->_ignoreArchitectureItem;      
        _forceResolve        = parent->_forceResolve;
        _upgradeMode         = parent->_upgradeMode;
+       _tryAllPossibilities = parent->_tryAllPossibilities;
+       _scippedPossibilities = parent->_scippedPossibilities;
+       
     } else {
        _min_priority = MAXINT;
     }
index 1a021045bc8a16e5209d70f6beeb8938f149889c..1da653344f34e43bcc30f13b6fefccdab900a24a 100644 (file)
@@ -105,6 +105,16 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
                         // This behaviour is favourited by ZMD    
     bool _upgradeMode;  // Resolver has been called with doUpgrade
     
+    // In order reducing solver time we are reducing the branches
+    // by skipping resolvables which have worse architecture,edition
+    // than a resolvable which provides the same cababilities.
+    // BUT if there is no valid solution we will regard the "other"
+    // resolvables in a second solver run too.
+    bool _tryAllPossibilities; // Try ALL alternatives
+    bool _scippedPossibilities;// Flag that there are other possibilities
+                               // which we are currently ignore
+    
+    
   public:
     ResolverContext (const ResPool & pool, const Arch & arch, ResolverContext_Ptr parent = NULL);
     virtual ~ResolverContext();
@@ -129,6 +139,12 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
     bool verifying (void) const { return _verifying; }
     void setVerifying (bool verifying) { _verifying = verifying; }
 
+    bool tryAllPossibilities (void) const { return _tryAllPossibilities; }
+    void setTryAllPossibilities (bool tryAllPossibilities) { _tryAllPossibilities = tryAllPossibilities; }
+    
+    bool scippedPossibilities (void) const { return _scippedPossibilities; }
+    void setScippedPossibilities (bool scippedPossibilities) { _scippedPossibilities = scippedPossibilities; }
+
     bool establishing (void) const { return _establishing; }
     void setEstablishing (bool establishing) { _establishing = establishing; }