backup
authorMichael Andres <ma@suse.de>
Fri, 7 Apr 2006 08:57:35 +0000 (08:57 +0000)
committerMichael Andres <ma@suse.de>
Fri, 7 Apr 2006 08:57:35 +0000 (08:57 +0000)
devel/devel.ma/Iorder.h [new file with mode: 0644]
devel/devel.ma/Parse.cc

diff --git a/devel/devel.ma/Iorder.h b/devel/devel.ma/Iorder.h
new file mode 100644 (file)
index 0000000..57bd472
--- /dev/null
@@ -0,0 +1,423 @@
+
+/******************************************************************
+ **
+ **
+ **    FUNCTION NAME : strip_obsoleted_to_delete
+ **    FUNCTION TYPE : void
+ **
+ ** strip packages to_delete which get obsoleted by
+ ** to_install (i.e. delay deletion in case the
+ ** obsoleting package likes to save whatever...
+*/
+
+static void
+strip_obsoleted_to_delete( PoolItemList & deleteList_r,
+                           const PoolItemList & instlist_r )
+{
+  if ( deleteList_r.size() == 0 || instlist_r.size() == 0 )
+    return; // ---> nothing to do
+
+  // build obsoletes from instlist_r
+  CapSet obsoletes;
+  for ( PoolItemList::const_iterator it = instlist_r.begin();
+       it != instlist_r.end(); ++it )
+    {
+      PoolItem_Ref item( *it );
+      obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
+    }
+  if ( obsoletes.size() == 0 )
+    return; // ---> nothing to do
+
+  // match them... ;(
+  PoolItemList undelayed;
+  // forall applDelete Packages...
+  for ( PoolItemList::iterator it = deleteList_r.begin();
+       it != deleteList_r.end(); ++it )
+    {
+      PoolItem_Ref ipkg( *it );
+      bool delayPkg = false;
+      // ...check whether an obsoletes....
+      for ( CapSet::iterator obs = obsoletes.begin();
+            ! delayPkg && obs != obsoletes.end(); ++obs )
+        {
+          // ...matches anything provided by the package?
+          for ( CapSet::const_iterator prov = ipkg->dep(Dep::PROVIDES).begin();
+                prov != ipkg->dep(Dep::PROVIDES).end(); ++prov )
+            {
+              if ( obs->matches( *prov ) == CapMatch::yes )
+                {
+                  // if so, delay package deletion
+                  DBG << "Ignore appl_delete (should be obsoleted): " << ipkg << endl;
+                  delayPkg = true;
+                  ipkg.status().setTransact( false, ResStatus::USER );
+                  break;
+                }
+            }
+        }
+      if ( ! delayPkg ) {
+        DBG << "undelayed " << ipkg << endl;
+        undelayed.push_back( ipkg );
+      }
+    }
+  // Puhh...
+  deleteList_r.swap( undelayed );
+}
+
+
+
+
+void
+getResolvablesToInsDel ( const ResPool pool_r,
+                         PoolItemList & dellist_r,
+                         PoolItemList & instlist_r,
+                         PoolItemList & srclist_r )
+{
+  dellist_r.clear();
+  instlist_r.clear();
+  srclist_r.clear();
+  PoolItemList nonpkglist;
+
+  for ( ResPool::const_iterator it = pool_r.begin(); it != pool_r.end(); ++it )
+    {
+      if (it->status().isToBeInstalled())
+       {
+          if ((*it)->kind() == ResTraits<SrcPackage>::kind) {
+            srclist_r.push_back( *it );
+          }
+          else if ((*it)->kind() != ResTraits<Package>::kind) {
+            nonpkglist.push_back( *it );
+          }
+          else
+            instlist_r.push_back( *it );
+       }
+      else if (it->status().isToBeUninstalled())
+       {
+          if ( it->status().isToBeUninstalledDueToObsolete() )
+           {
+              DBG << "Ignore auto_delete (should be obsoleted): " << *it << endl;
+           }
+          else if ( it->status().isToBeUninstalledDueToUpgrade() )
+           {
+              DBG << "Ignore auto_delete (should be upgraded): " << *it << endl;
+           }
+          else {
+            dellist_r.push_back( *it );
+          }
+       }
+    }
+
+  MIL << "ResolvablesToInsDel: delete " << dellist_r.size()
+  << ", install " << instlist_r.size()
+  << ", srcinstall " << srclist_r.size()
+  << ", nonpkg " << nonpkglist.size() << endl;
+
+  ///////////////////////////////////////////////////////////////////
+  //
+  // strip packages to_delete which get obsoleted by
+  // to_install (i.e. delay deletion in case the
+  // obsoleting package likes to save whatever...
+  //
+  ///////////////////////////////////////////////////////////////////
+  strip_obsoleted_to_delete( dellist_r, instlist_r );
+
+  if ( dellist_r.size() ) {
+    ///////////////////////////////////////////////////////////////////
+    //
+    // sort delete list...
+    //
+    ///////////////////////////////////////////////////////////////////
+    PoolItemSet delset( dellist_r.begin(), dellist_r.end() );  // for delete order
+    PoolItemSet dummy; // dummy, empty, should contain already installed
+
+    InstallOrder order( pool_r, delset, dummy ); // sort according top prereq
+    order.init();
+    const PoolItemList dsorted( order.getTopSorted() );
+
+    dellist_r.clear();
+    for ( PoolItemList::const_reverse_iterator cit = dsorted.rbegin();
+          cit != dsorted.rend(); ++cit )
+      {
+       dellist_r.push_back( *cit );
+      }
+  }
+
+  ///////////////////////////////////////////////////////////////////
+  //
+  // sort installed list...
+  //
+  ///////////////////////////////////////////////////////////////////
+  if ( instlist_r.empty() ) {
+    instlist_r.splice( instlist_r.end(), nonpkglist );
+
+    return;
+  }
+#warning Source Rank Priority ?
+#if 0
+  ///////////////////////////////////////////////////////////////////
+  // Get desired order of InstSrc'es to install from.
+  ///////////////////////////////////////////////////////////////////
+  typedef map<unsigned,unsigned> RankPriority;
+
+  RankPriority rankPriority;
+  {
+    InstSrcManager::ISrcIdList sourcerank( Y2PM::instSrcManager().instOrderSources() );
+    // map InstSrc rank to install priority
+    unsigned prio = 0;
+    for ( InstSrcManager::ISrcIdList::const_iterator it = sourcerank.begin();
+          it != sourcerank.end(); ++it, ++prio ) {
+      rankPriority[(*it)->descr()->default_rank()] = prio;
+    }
+  }
+#endif
+
+  ///////////////////////////////////////////////////////////////////
+  // Compute install order according to packages prereq.
+  // Try to group packages with respect to the desired install order
+  ///////////////////////////////////////////////////////////////////
+  // backup list for debug purpose.
+  // You can as well build the set, clear the list and rebuild it in install order.
+  PoolItemList instbackup_r;
+  instbackup_r.swap( instlist_r );
+
+  PoolItemSet insset( instbackup_r.begin(), instbackup_r.end() ); // for install order
+  PoolItemSet installed; // dummy, empty, should contain already installed
+
+  InstallOrder order( pool_r, insset, installed );
+  // start recursive depth-first-search
+  order.init();
+  MIL << "order.init() done" << endl;
+  order.printAdj( XXX, false );
+  ///////////////////////////////////////////////////////////////////
+  // build install list in install order
+  // NOTE: for now _prio is Source numeric Id.
+  ///////////////////////////////////////////////////////////////////
+  PoolItemList best_list;
+  unsigned best_prio     = 0;
+  unsigned best_medianum = 0;
+
+  PoolItemList last_list;
+  unsigned last_prio     = 0;
+  unsigned last_medianum = 0;
+
+  PoolItemList other_list;
+
+  for ( PoolItemList items = order.computeNextSet(); ! items.empty(); items = order.computeNextSet() )
+    {
+      MIL << "order.computeNextSet: " << items.size() << " resolvables" << endl;
+      ///////////////////////////////////////////////////////////////////
+      // items contains all packages we could install now. Pick all packages
+      // from current media, or best media if none for current.
+      ///////////////////////////////////////////////////////////////////
+
+      best_list.clear();
+      last_list.clear();
+      other_list.clear();
+
+      for ( PoolItemList::iterator cit = items.begin(); cit != items.end(); ++cit )
+        {
+          Resolvable::constPtr res( cit->resolvable() );
+          if (!res) continue;
+          Package::constPtr cpkg( asKind<Package>(res) );
+          if (!cpkg) {
+           XXX << "Not a package " << *cit << endl;
+           order.setInstalled( *cit );
+           other_list.push_back( *cit );
+           continue;
+          }
+          XXX << "Package " << *cpkg << ", media " << cpkg->mediaId() << " last_medianum " << last_medianum << " best_medianum " << best_medianum << endl;
+          if ( cpkg->source().numericId() == last_prio &&
+               cpkg->mediaId() == last_medianum ) {
+            // prefer packages on current media.
+            last_list.push_back( *cit );
+            continue;
+          }
+
+          if ( last_list.empty() ) {
+            // check for best media as long as there are no packages for current media.
+
+            if ( ! best_list.empty() ) {
+
+              if ( cpkg->source().numericId() < best_prio ) {
+                best_list.clear(); // new best
+              } else if ( cpkg->source().numericId() == best_prio ) {
+                if ( cpkg->mediaId() < best_medianum ) {
+                  best_list.clear(); // new best
+                } else if ( cpkg->mediaId() == best_medianum ) {
+                  best_list.push_back( *cit ); // same as best -> add
+                  continue;
+                } else {
+                  continue; // worse
+                }
+              } else {
+                continue; // worse
+              }
+            }
+
+            if ( best_list.empty() )
+              {
+                // first package or new best
+                best_list.push_back( *cit );
+                best_prio     = cpkg->source().numericId();
+                best_medianum = cpkg->mediaId();
+                continue;
+              }
+          }
+
+        } // for all packages in current set
+
+      ///////////////////////////////////////////////////////////////////
+      // remove packages picked from install order and append them to
+      // install list.
+      ///////////////////////////////////////////////////////////////////
+      PoolItemList & take_list( last_list.empty() ? best_list : last_list );
+      if ( last_list.empty() )
+        {
+          MIL << "SET NEW media " << best_medianum << endl;
+          last_prio     = best_prio;
+          last_medianum = best_medianum;
+        }
+      else
+        {
+          MIL << "SET CONTINUE" << endl;
+        }
+
+      for ( PoolItemList::iterator it = take_list.begin(); it != take_list.end(); ++it )
+        {
+          order.setInstalled( *it );
+          DBG << "SET isrc " << (*it)->source().numericId() << " -> " << (*it) << endl;
+        }
+      // move everthing from take_list to the end of instlist_r, clean take_list
+      instlist_r.splice( instlist_r.end(), take_list );
+      // same for other_list
+      instlist_r.splice( instlist_r.end(), other_list );
+
+    } // for all sets computed
+
+
+  if ( instbackup_r.size() != instlist_r.size() )
+    {
+      ERR << "***************** Lost packages in InstallOrder sort." << endl;
+    }
+  instlist_r.splice( instlist_r.end(), nonpkglist );
+}
+
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+ inline  unsigned mediaId( const PoolItem & pi )
+  {
+    Package::constPtr pkg( asKind<Package>(pi.resolvable()) );
+    if ( pkg )
+      return pkg->mediaId();
+    return 0;
+  }
+PoolItemList commit( const PoolItemList & items_r, bool cont )
+{
+  static unsigned  go = 0;
+  static unsigned  hop = 0;
+  static unsigned  itm = 0;
+  static unsigned  sid = 0;
+  static unsigned  mid = 0;
+
+  MIL << "=====[" << ++go << "]========================================" << endl;
+  if ( ! cont )
+    {
+      MIL << "DONE  on item " << itm << endl;
+      return PoolItemList();
+    }
+
+  for ( PoolItemList::const_iterator it = items_r.begin(); it != items_r.end(); ++it )
+    {
+      ++itm;
+      unsigned cmid = mediaId( *it );
+      unsigned csid = (*it)->source().numericId();
+
+      if ( cmid && ( cmid != mid || csid != sid ) )
+        {
+          MIL << "Hop " << ++hop << ": "
+              << "S" << sid << "/M" << mid
+              << " -> ";
+          sid = csid;
+          mid = cmid;
+          MIL << "S" << sid << "/M" << mid
+              << " on item " << itm
+              << endl;
+        }
+    }
+
+  return PoolItemList();
+}
+
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+int commit( ResPool pool_r, unsigned int medianr,
+            PoolItemList & errors_r,
+            PoolItemList & remaining_r,
+            PoolItemList & srcremaining_r, bool dry_run )
+{
+  MIL << "TargetImpl::commit(<pool>, " << medianr << ")" << endl;
+  dry_run = true;
+
+  errors_r.clear();
+  remaining_r.clear();
+  srcremaining_r.clear();
+
+  PoolItemList to_uninstall;
+  PoolItemList to_install;
+  PoolItemList to_srcinstall;
+  getResolvablesToInsDel( pool_r, to_uninstall, to_install, to_srcinstall );
+
+  if ( medianr ) {
+    MIL << "Restrict to media number " << medianr << endl;
+  }
+
+  //commit (to_uninstall, dry_run );
+
+  if (medianr == 0) {                  // commit all
+    remaining_r = commit( to_install, dry_run );
+    srcremaining_r = commit( to_srcinstall, dry_run );
+  }
+  else
+    {
+      PoolItemList current_install;
+      PoolItemList current_srcinstall;
+
+      for (PoolItemList::iterator it = to_install.begin(); it != to_install.end(); ++it)
+        {
+          Resolvable::constPtr res( it->resolvable() );
+          Package::constPtr pkg( asKind<Package>(res) );
+          if (pkg && medianr != pkg->mediaId())                                                                // check medianr for packages only
+            {
+              XXX << "Package " << *pkg << ", wrong media " << pkg->mediaId() << endl;
+              remaining_r.push_back( *it );
+            }
+          else
+            {
+              current_install.push_back( *it );
+            }
+        }
+      PoolItemList bad = commit( current_install, dry_run );
+      remaining_r.insert(remaining_r.end(), bad.begin(), bad.end());
+
+      for (PoolItemList::iterator it = to_srcinstall.begin(); it != to_srcinstall.end(); ++it)
+        {
+          Resolvable::constPtr res( it->resolvable() );
+          Package::constPtr pkg( asKind<Package>(res) );
+          if (pkg && medianr != pkg->mediaId()) // check medianr for packages only
+            {
+              XXX << "Package " << *pkg << ", wrong media " << pkg->mediaId() << endl;
+              srcremaining_r.push_back( *it );
+            }
+          else {
+            current_srcinstall.push_back( *it );
+          }
+        }
+      bad = commit( current_srcinstall, dry_run );
+      srcremaining_r.insert(srcremaining_r.end(), bad.begin(), bad.end());
+    }
+  commit( PoolItemList(), false );
+  return to_install.size() - remaining_r.size();
+}
index 09a1279..98d1411 100644 (file)
@@ -186,7 +186,7 @@ namespace zypp
 }
 
 ///////////////////////////////////////////////////////////////////
-
+#if 0
 template<class _InstIterator, class _DelIterator, class _OutputIterator>
 void strip_obsoleted_to_delete( _InstIterator instBegin_r, _InstIterator instEnd_r,
                                 _DelIterator  delBegin_r,  _DelIterator  delEnd_r,
@@ -200,9 +200,9 @@ void strip_obsoleted_to_delete( _InstIterator instBegin_r, _InstIterator instEnd
     CapSet obsoletes;
     for ( /**/; instBegin_r != instEnd_r; ++instBegin_r )
     {
-      xxxxx
-      PoolItem_Ref item( *it );
-      obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
+      //xxxxx
+      //PoolItem_Ref item( *it );
+      //obsoletes.insert( item->dep(Dep::OBSOLETES).begin(), item->dep(Dep::OBSOLETES).end() );
     }
   if ( obsoletes.size() == 0 )
     return; // ---> nothing to do
@@ -242,7 +242,7 @@ void strip_obsoleted_to_delete( _InstIterator instBegin_r, _InstIterator instEnd
   deleteList_r.swap( undelayed );
 
 }
-
+#endif
 ///////////////////////////////////////////////////////////////////
 
 /******************************************************************
@@ -310,13 +310,7 @@ int main( int argc, char * argv[] )
                   make_filter_begin<resfilter::ByTransact>(pool),
                   make_filter_end<resfilter::ByTransact>(pool) ) << endl;
 
-  CollectTransacting toTransact;
-  std::for_each( make_filter_begin<resfilter::ByTransact>(pool),
-                 make_filter_end<resfilter::ByTransact>(pool),
-                 functor::functorRef<void,PoolItem>(toTransact) );
-  MIL << toTransact;
-
-  if ( 0 )
+  if ( 1 )
     {
       PoolItemList errors_r;
       PoolItemList remaining_r;
@@ -326,6 +320,14 @@ int main( int argc, char * argv[] )
       dumpPoolStats( WAR << "remaining_r ", remaining_r.begin(), remaining_r.end() ) << endl;
       dumpPoolStats( WAR << "srcremaining_r ", srcremaining_r.begin(), srcremaining_r.end() ) << endl;
     }
+  else
+    {
+      CollectTransacting toTransact;
+      std::for_each( make_filter_begin<resfilter::ByTransact>(pool),
+                     make_filter_end<resfilter::ByTransact>(pool),
+                     functor::functorRef<void,PoolItem>(toTransact) );
+      MIL << toTransact;
+    }
 
 #if 0
   Source_Ref src( *SourceManager::sourceManager()->Source_begin() );