- Allow computation of disk usage per solvable.
authorMichael Andres <ma@suse.de>
Tue, 30 Sep 2008 15:41:42 +0000 (15:41 +0000)
committerMichael Andres <ma@suse.de>
Tue, 30 Sep 2008 15:41:42 +0000 (15:41 +0000)
VERSION.cmake
devel/devel.ma/MaTest.cc
devel/devel.ma/NewPool.cc
package/libzypp.changes
zypp/DiskUsageCounter.cc
zypp/DiskUsageCounter.h

index c2f3c30..b4a7b1f 100644 (file)
@@ -60,8 +60,8 @@
 #
 SET(LIBZYPP_MAJOR "5")
 SET(LIBZYPP_COMPATMINOR "13")
-SET(LIBZYPP_MINOR "13")
-SET(LIBZYPP_PATCH "2")
+SET(LIBZYPP_MINOR "14")
+SET(LIBZYPP_PATCH "0")
 #
 # LAST RELEASED: 5.13.1 (13)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
index 9b74140..6cda813 100644 (file)
-#include <iostream>
+#include "Tools.h"
 
-#include <boost/signal.hpp>
-#include <boost/bind.hpp>
+#include "zypp/PoolQueryResult.h"
 
+#include <zypp/base/PtrTypes.h>
+#include <zypp/base/Exception.h>
+#include <zypp/base/Gettext.h>
 #include <zypp/base/LogTools.h>
-#include <zypp/base/Easy.h>
+#include <zypp/base/Debug.h>
+#include <zypp/base/Functional.h>
+#include <zypp/base/IOStream.h>
+#include <zypp/base/InputStream.h>
+#include <zypp/base/ProvideNumericId.h>
+#include <zypp/base/Flags.h>
+#include <zypp/AutoDispose.h>
 
-using std::endl;
-using std::cout;
+#include "zypp/ResPoolProxy.h"
 
-namespace boost
+#include "zypp/ZYppCallbacks.h"
+#include "zypp/ResPool.h"
+#include "zypp/ResFilters.h"
+#include "zypp/ResObjects.h"
+#include "zypp/Digest.h"
+#include "zypp/PackageKeyword.h"
+#include "zypp/TmpPath.h"
+#include "zypp/ManagedFile.h"
+#include "zypp/NameKindProxy.h"
+#include "zypp/pool/GetResolvablesToInsDel.h"
+
+#include "zypp/RepoManager.h"
+#include "zypp/Repository.h"
+#include "zypp/RepoInfo.h"
+
+#include "zypp/repo/PackageProvider.h"
+
+#include "zypp/ResPoolProxy.h"
+
+#include "zypp/sat/Pool.h"
+#include "zypp/sat/LocaleSupport.h"
+#include "zypp/sat/LookupAttr.h"
+#include "zypp/sat/SolvableSet.h"
+#include "zypp/sat/SolvIterMixin.h"
+#include "zypp/sat/detail/PoolImpl.h"
+#include "zypp/sat/WhatObsoletes.h"
+#include "zypp/PoolQuery.h"
+#include "zypp/ServiceInfo.h"
+
+#include "zypp/parser/ProductConfReader.h"
+
+#include <boost/mpl/int.hpp>
+
+using namespace std;
+using namespace zypp;
+using namespace zypp::functor;
+using namespace zypp::ui;
+
+///////////////////////////////////////////////////////////////////
+
+static const Pathname sysRoot( getenv("SYSROOT") ? getenv("SYSROOT") : "/Local/ROOT" );
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+
+bool queryInstalledEditionHelper( const std::string & name_r,
+                                  const Edition &     ed_r,
+                                  const Arch &        arch_r )
+{
+  if ( ed_r == Edition::noedition )
+    return true;
+  if ( name_r == "kernel-default" && ed_r == Edition("2.6.22.5-10") )
+    return true;
+  if ( name_r == "update-test-affects-package-manager" && ed_r == Edition("1.1-6") )
+    return true;
+
+  return false;
+}
+
+
+ManagedFile repoProvidePackage( const PoolItem & pi )
+{
+  ResPool _pool( getZYpp()->pool() );
+  repo::RepoMediaAccess _access;
+
+  // Redirect PackageProvider queries for installed editions
+  // (in case of patch/delta rpm processing) to rpmDb.
+  repo::PackageProviderPolicy packageProviderPolicy;
+  packageProviderPolicy.queryInstalledCB( queryInstalledEditionHelper );
+
+  Package::constPtr p = asKind<Package>(pi.resolvable());
+
+  // Build a repository list for repos
+  // contributing to the pool
+  repo::DeltaCandidates deltas( repo::makeDeltaCandidates( _pool.knownRepositoriesBegin(),
+                                                           _pool.knownRepositoriesEnd() ) );
+  repo::PackageProvider pkgProvider( _access, p, deltas, packageProviderPolicy );
+  return pkgProvider.providePackage();
+}
+
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+namespace zypp
 {
-  template<class Tp>
-      std::ostream & operator<<( std::ostream & str, const signal<Tp> & obj )
+  template <class _LIterator, class _RIterator, class _Function>
+      inline int invokeOnEach( _LIterator lbegin_r, _LIterator lend_r,
+                               _RIterator rbegin_r, _RIterator rend_r,
+                               _Function fnc_r )
+      {
+        int cnt = 0;
+        for ( _LIterator lit = lbegin_r; lit != lend_r; ++lit )
+        {
+          for ( _RIterator rit = rbegin_r; rit != rend_r; ++rit )
+          {
+            ++cnt;
+            if ( ! fnc_r( *lit, *rit ) )
+              return -cnt;
+          }
+        }
+        return cnt;
+      }
+}
+
+
+void dbgDu( Selectable::Ptr sel )
+{
+  if ( sel->installedObj() )
   {
-    return str << "Connected slots: " << obj.num_slots();
+    DBG << "i: " << sel->installedObj() << endl
+        << sel->installedObj()->diskusage() << endl;
   }
+  if ( sel->candidateObj() )
+  {
+    DBG << "c: " << sel->candidateObj() << endl
+        << sel->candidateObj()->diskusage() << endl;
+  }
+  INT << sel << endl
+      << getZYpp()->diskUsage() << endl;
+}
+
+///////////////////////////////////////////////////////////////////
 
-  namespace signals
+std::ostream & testDump( std::ostream & str, const PoolItem & pi )
+{
+  str << pi << endl;
+  Package::constPtr p( asKind<Package>(pi) );
+  if ( p )
   {
-    std::ostream & operator<<( std::ostream & str, const connection & obj )
-    {
-      return str << "Connection: "
-          << ( obj.connected() ? '*' : '_' )
-          << ( obj.blocked()   ? 'B' : '_' )
-          ;
-    }
+#define OUTS(V) str << str::form("%-25s: ",#V) << p->V() << endl
+    Locale l( "de" );
+    str << str::form("%-25s: ",l.code().c_str()) << p->summary(l) << endl;
+    l = Locale( "fr" );
+    str << str::form("%-25s: ",l.code().c_str()) << p->summary(l) << endl;
+    l = Locale( "dsdf" );
+    str << str::form("%-25s: ",l.code().c_str()) << p->summary(l) << endl;
+    OUTS( summary );
+    OUTS( installsize );
+    OUTS( downloadSize );
+    OUTS( sourcePkgName );
+    OUTS( sourcePkgEdition );
+    OUTS( checksum );
+    OUTS( location );
+#undef OUTS
+
+
   }
+  return str;
 }
 
-using namespace zypp;
+struct Xprint
+{
+  bool operator()( const PoolItem & obj_r )
+  {
+    //MIL << obj_r << endl;
+    //DBG << " -> " << obj_r->satSolvable() << endl;
 
-using boost::signal;
-using boost::signals::connection;
-using boost::signals::trackable;
+    return true;
+  }
+
+  bool operator()( const sat::Solvable & obj_r )
+  {
+    //dumpOn( MIL, obj_r ) << endl;
+    return true;
+  }
+};
 
-struct HelloWorld
+///////////////////////////////////////////////////////////////////
+struct SetTransactValue
 {
-  HelloWorld() {++i;}
-  HelloWorld(const HelloWorld &) {++i;}
-  ~HelloWorld() { --i;}
+  SetTransactValue( ResStatus::TransactValue newVal_r, ResStatus::TransactByValue causer_r )
+  : _newVal( newVal_r )
+  , _causer( causer_r )
+  {}
+
+  ResStatus::TransactValue   _newVal;
+  ResStatus::TransactByValue _causer;
 
-  void operator()(unsigned) const
+  bool operator()( const PoolItem & pi ) const
   {
-    USR << "Hello, World! " << i << std::endl;
+    bool ret = pi.status().setTransactValue( _newVal, _causer );
+    if ( ! ret )
+      ERR << _newVal <<  _causer << " " << pi << endl;
+    return ret;
   }
+};
 
-  static int i;
+struct StatusReset : public SetTransactValue
+{
+  StatusReset()
+  : SetTransactValue( ResStatus::KEEP_STATE, ResStatus::USER )
+  {}
 };
 
-int HelloWorld::i = 0;
+struct StatusInstall : public SetTransactValue
+{
+  StatusInstall()
+  : SetTransactValue( ResStatus::TRANSACT, ResStatus::USER )
+  {}
+};
+
+inline bool g( const NameKindProxy & nkp, Arch arch = Arch() )
+{
+  if ( nkp.availableEmpty() )
+  {
+    ERR << "No Item to select: " << nkp << endl;
+    return false;
+    ZYPP_THROW( Exception("No Item to select") );
+  }
+
+  if ( arch != Arch() )
+  {
+    typeof( nkp.availableBegin() ) it =  nkp.availableBegin();
+    for ( ; it != nkp.availableEnd(); ++it )
+    {
+      if ( (*it)->arch() == arch )
+       return (*it).status().setTransact( true, ResStatus::USER );
+    }
+  }
+
+  return nkp.availableBegin()->status().setTransact( true, ResStatus::USER );
+}
+
+///////////////////////////////////////////////////////////////////
 
-struct M
+bool solve()
 {
-  void ping() const
+  bool rres = false;
   {
-    static unsigned i = 0;
-    ++i;
-    MIL << i << " -> " << _sigA << endl;
-    _sigA( i );
+    //zypp::base::LogControl::TmpLineWriter shutUp;
+    rres = getZYpp()->resolver()->resolvePool();
   }
+  if ( ! rres )
+  {
+    ERR << "resolve " << rres << endl;
+    getZYpp()->resolver()->problems();
+    return false;
+  }
+  MIL << "resolve " << rres << endl;
+  return true;
+}
 
-  typedef signal<void(unsigned)> SigA;
+bool install()
+{
+  ZYppCommitPolicy pol;
+  pol.dryRun(true);
+  pol.rpmInstFlags( pol.rpmInstFlags().setFlag( target::rpm::RPMINST_JUSTDB ) );
+  SEC << getZYpp()->commit( pol ) << endl;
+  return true;
+}
 
-  SigA & siga() const { return _sigA; }
+void testcase()
+{
+  getZYpp()->resolver()->createSolverTestcase( "./solverTestcase" );
+}
+
+///////////////////////////////////////////////////////////////////
 
-  mutable SigA _sigA;
+struct DigestReceive : public callback::ReceiveReport<DigestReport>
+{
+  DigestReceive()
+  {
+    connect();
+  }
+
+  virtual bool askUserToAcceptNoDigest( const zypp::Pathname &file )
+  {
+    USR << endl;
+    return false;
+  }
+  virtual bool askUserToAccepUnknownDigest( const Pathname &file, const std::string &name )
+  {
+    USR << endl;
+    return false;
+  }
+  virtual bool askUserToAcceptWrongDigest( const Pathname &file, const std::string &requested, const std::string &found )
+  {
+    USR << "fle " << PathInfo(file) << endl;
+    USR << "req " << requested << endl;
+    USR << "fnd " << found << endl;
+    return false;
+  }
 };
 
-struct X : public trackable
+struct KeyRingSignalsReceive : public callback::ReceiveReport<KeyRingSignals>
 {
-  X() {_s=++s;}
-  X( const X & ) {_s=++s;}
-  X& operator=( const X & ) { return *this; }
-  virtual ~X() {_s=-_s;}
-  static int s;
-  int _s;
+  KeyRingSignalsReceive()
+  {
+    connect();
+  }
+  virtual void trustedKeyAdded( const PublicKey &/*key*/ )
+  {
+    USR << endl;
+  }
+  virtual void trustedKeyRemoved( const PublicKey &/*key*/ )
+  {
+    USR << endl;
+  }
+};
+
+///////////////////////////////////////////////////////////////////
 
-  void pong( unsigned i ) const
+struct MediaChangeReceive : public callback::ReceiveReport<media::MediaChangeReport>
+{
+  virtual Action requestMedia( Url & source
+                               , unsigned mediumNr
+                               , const std::string & label
+                               , Error error
+                               , const std::string & description
+                               , const std::vector<std::string> & devices
+                               , unsigned int & dev_current )
   {
-    DBG << _s << ' ' << i << endl;
+    SEC << __FUNCTION__ << endl
+    << "  " << source << endl
+    << "  " << mediumNr << endl
+    << "  " << label << endl
+    << "  " << error << endl
+    << "  " << description << endl
+    << "  " << devices << endl
+    << "  " << dev_current << endl;
+    return IGNORE;
   }
 };
 
-int X::s;
+///////////////////////////////////////////////////////////////////
+
+namespace container
+{
+  template<class _Tp>
+    bool isIn( const std::set<_Tp> & cont, const typename std::set<_Tp>::value_type & val )
+    { return cont.find( val ) != cont.end(); }
+}
+///////////////////////////////////////////////////////////////////
+
+void itCmp( const sat::Pool::SolvableIterator & l, const sat::Pool::SolvableIterator & r )
+{
+  SEC << *l << " - " << *r << endl;
+  INT << "== " << (l==r) << endl;
+  INT << "!= " << (l!=r) << endl;
+}
+
+bool isTrue()  { return true; }
+bool isFalse() { return false; }
+
+void dumpIdStr()
+{
+  for ( int i = -3; i < 30; ++i )
+  {
+    DBG << i << '\t' << IdString( i ) << endl;
+  }
+}
+
+void ttt( const char * lhs, const char * rhs )
+{
+  DBG << lhs << " <=> " << rhs << " --> " << ::strcmp( lhs, rhs ) << endl;
+}
+
+namespace zypp
+{
+namespace filter
+{
+  template <class _MemFun, class _Value>
+  class HasValue
+  {
+    public:
+      HasValue( _MemFun fun_r, _Value val_r )
+      : _fun( fun_r ), _val( val_r )
+      {}
+      template <class _Tp>
+      bool operator()( const _Tp & obj_r ) const
+      { return( _fun && (obj_r.*_fun)() == _val ); }
+    private:
+      _MemFun _fun;
+      _Value  _val;
+  };
+
+  template <class _MemFun, class _Value>
+  HasValue<_MemFun, _Value> byValue( _MemFun fun_r, _Value val_r )
+  { return HasValue<_MemFun, _Value>( fun_r, val_r ); }
+}
+
+}
+
+template <class L>
+struct _TestO { _TestO( const L & lhs ) : _lhs( lhs ) {} const L & _lhs; };
+
+template <class L>
+std::ostream & operator<<( std::ostream & str, const _TestO<L> & obj )
+{ const L & lhs( obj._lhs); return str << (lhs?'_':'*') << (lhs.empty()?'e':'_') << "'" << lhs << "'"; }
+
+template <class L>
+_TestO<L> testO( const L & lhs )
+{ return _TestO<L>( lhs ); }
+
+template <class L, class R>
+void testCMP( const L & lhs, const R & rhs )
+{
+  MIL << "LHS " << testO(lhs) << endl;
+  MIL << "RHS " << rhs << endl;
+
+#define OUTS(S) DBG << #S << ": " << (S) << endl
+  OUTS( lhs.compare(rhs) );
+  OUTS( lhs != rhs );
+  OUTS( lhs <  rhs );
+  OUTS( lhs <= rhs );
+  OUTS( lhs == rhs );
+  OUTS( lhs >= rhs );
+  OUTS( lhs >  rhs );
+#undef OUTS
+}
+
+inline bool useRepo( RepoInfo & repo )
+{
+  return repo.alias()  == "matest";
+  return repo.enabled();
+}
 
 /******************************************************************
 **
 **      FUNCTION NAME : main
 **      FUNCTION TYPE : int
 */
-int main( int argc, const char * argv[] )
-{
-  --argc; ++argv; // skip arg 0
+int main( int argc, char * argv[] )
+try {
+  --argc;
+  ++argv;
+  zypp::base::LogControl::instance().logToStdErr();
+  INT << "===[START]==========================================" << endl;
+  ZConfig::instance();
 
-  M m;
-  m.ping();
-  X xx;
-  m.siga().connect( boost::bind( &X::pong, &xx, _1 ) );
-  m.ping();
+  ResPool   pool( ResPool::instance() );
+  sat::Pool satpool( sat::Pool::instance() );
 
+  if ( 0 )
   {
-    X x;
-    m.siga().connect( boost::bind( &X::pong, boost::ref(x), _1 ) );
-    m.ping();
+    Measure x( "INIT TARGET" );
+    {
+      {
+        zypp::base::LogControl::TmpLineWriter shutUp;
+        getZYpp()->initializeTarget( sysRoot );
+      }
+      getZYpp()->target()->load();
+      USR << getZYpp()->target()->targetDistribution() << endl;
+      USR << getZYpp()->target()->targetDistributionRelease() << endl;
+    }
+  }
+
+  if ( 1 )
+  {
+    RepoManager repoManager( makeRepoManager( sysRoot ) );
+    RepoInfoList repos = repoManager.knownRepositories();
+
+    // launch repos
+    for ( RepoInfoList::iterator it = repos.begin(); it != repos.end(); ++it )
+    {
+      RepoInfo & nrepo( *it );
+      SEC << nrepo << endl;
+
+      if ( ! useRepo( nrepo ) )
+        continue;
+
+      if ( ! repoManager.isCached( nrepo ) || nrepo.type() == repo::RepoType::RPMPLAINDIR )
+      {
+        if ( repoManager.isCached( nrepo ) )
+        {
+          SEC << "cleanCache" << endl;
+          repoManager.cleanCache( nrepo );
+        }
+        SEC << "refreshMetadata" << endl;
+        //repoManager.refreshMetadata( nrepo );
+        SEC << "buildCache" << endl;
+        repoManager.buildCache( nrepo );
+      }
+    }
 
-    X y;
-    m.siga().connect( boost::bind( &X::pong, &y, _1 ) );
-    m.ping();
+    // create from cache:
+    {
+      Measure x( "CREATE FROM CACHE" );
+      for ( RepoInfoList::iterator it = repos.begin(); it != repos.end(); ++it )
+      {
+        RepoInfo & nrepo( *it );
+        if ( ! useRepo( nrepo ) )
+          continue;
+
+        Measure x( "CREATE FROM CACHE "+nrepo.alias() );
+        try
+        {
+          repoManager.loadFromCache( nrepo );
+        }
+        catch ( const Exception & exp )
+        {
+          MIL << "Try to rebuild cache..." << endl;
+          SEC << "cleanCache" << endl;
+          repoManager.cleanCache( nrepo );
+          SEC << "buildCache" << endl;
+          repoManager.buildCache( nrepo );
+          SEC << "Create from cache" << endl;
+          repoManager.loadFromCache( nrepo );
+        }
+
+        USR << "pool: " << pool << endl;
+      }
+    }
+  }
 
+  dumpRange( USR, satpool.reposBegin(), satpool.reposEnd() );
+  USR << "pool: " << pool << endl;
+
+  ///////////////////////////////////////////////////////////////////
+
+  if ( 0 )
+  {
+    Measure x( "Upgrade" );
+    UpgradeStatistics u;
+    getZYpp()->resolver()->doUpgrade( u );
   }
 
-  m.ping();
+  ///////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+//  UNTh_(2)product:openSUSE-11.1.x86_64(openSUSE-dvd-11.1)
+//  U_Th_(583)yast2-ntp-client-2.17.1-1.26.noarch(openSUSE-dvd-11.1)
+//  U_Th_(1652)kernel-default-2.6.27-7.2.x86_64(openSUSE-dvd-11.1)
+//  U_Th_(2490)ntp-4.2.4p5-1.6.x86_64(openSUSE-dvd-11.1)
+//  UNTh_(2545)openSUSE-release-11.1-1.4.x86_64(openSUSE-dvd-11.1)
+//  USTh_(3462)pattern:base-11.1-46.1.x86_64(openSUSE-dvd-11.1)
+//  USTh_(3672)pattern:x11-11.1-46.1.x86_64(openSUSE-dvd-11.1)
+//  USTu_(3680)pattern:xfce-11.1-46.1.x86_64(openSUSE-dvd-11.1)
+
+
+  getZYpp()->resolver()->addRequire( Capability("product:openSUSE") );
+  getZYpp()->resolver()->addRequire( Capability("yast2-ntp-client") );
+  getZYpp()->resolver()->addRequire( Capability("kernel-default") );
+  getZYpp()->resolver()->addRequire( Capability("ntp") );
+  getZYpp()->resolver()->addRequire( Capability("openSUSE-release") );
+  getZYpp()->resolver()->addRequire( Capability("pattern:base") );
+  getZYpp()->resolver()->addRequire( Capability("pattern:x11") );
+  getZYpp()->resolver()->addRequire( Capability("pattern:xfce") );
 
-  ///////////////////////////////////////////
+  solve();
 
-  INT << "---STOP" << endl;
+  vdumpPoolStats( USR << "Transacting:"<< endl,
+                  make_filter_begin<resfilter::ByTransact>(pool),
+                  make_filter_end<resfilter::ByTransact>(pool) ) << endl;
+
+  ByteCount sze;
+  ByteCount dusze;
+  DiskUsageCounter ducounter( DiskUsageCounter::justRootPartition() );
+  for_( it, make_filter_begin<resfilter::ByTransact>(pool), make_filter_end<resfilter::ByTransact>(pool) )
+  {
+    USR << *it << endl;
+    ByteCount csze( ducounter.disk_usage( *it ).begin()->commitDiff() );
+    sze += (*it)->installSize();
+    dusze += csze;
+    DBG <<(*it)->installSize() << " vs. " << csze << " | " << ByteCount( dusze-sze ) << endl;
+
+  }
+  SEC << sze << endl;
+  SEC << dusze << endl;
+
+  SEC << zypp::getZYpp()->diskUsage() << endl;
+
+  ///////////////////////////////////////////////////////////////////
+  INT << "===[END]============================================" << endl << endl;
+  zypp::base::LogControl::instance().logNothing();
   return 0;
 }
+catch ( const Exception & exp )
+{
+  INT << exp << endl << exp.historyAsString();
+}
+catch (...)
+{}
+
 
index e0812b9..fb6c048 100644 (file)
@@ -443,22 +443,6 @@ try {
   INT << "===[START]==========================================" << endl;
   ZConfig::instance();
 
-  {
-  Capability cap("flavor(dvd9)");
-  DBG << cap.detail().isSimple() << endl;
-  DBG << cap.detail().isNamed() << endl;
-  DBG << cap.detail().name() << endl;
-  std::string capstr = str::stripPrefix( cap.asString(), "flavor(" );
-  DBG << capstr << endl;
-  capstr.erase(capstr.size()-1);
-  DBG << capstr << endl;
-  }
-
-
-  ///////////////////////////////////////////////////////////////////
-  INT << "===[END]============================================" << endl << endl;
-  zypp::base::LogControl::instance().logNothing();
-  return 0;
 
 #if 0
 
@@ -510,7 +494,7 @@ try {
   ResPool   pool( ResPool::instance() );
   sat::Pool satpool( sat::Pool::instance() );
 
-  if ( 1 )
+  if ( 0 )
   {
     Measure x( "INIT TARGET" );
     {
@@ -629,13 +613,11 @@ try {
     }
   }
 
-
-  PoolItem pi ( getPi<Package>("amarok") );
-  MIL << pi << endl;
-  MIL << pi->asKind<Package>() << endl;
-  MIL << pi->asKind<Product>() << endl;
-  if ( pi->isKind<Package>() )
-    SEC << pi->asKind<Package>() << endl;
+  getZYpp()->resolver()->addRequire( Capability("amarok") );
+  solve();
+  vdumpPoolStats( USR << "Transacting:"<< endl,
+                  make_filter_begin<resfilter::ByTransact>(pool),
+                  make_filter_end<resfilter::ByTransact>(pool) ) << endl;
 
  //////////////////////////////////////////////////////////////////
   INT << "===[END]============================================" << endl << endl;
index 81a47e8..3306b9d 100644 (file)
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Tue Sep 30 17:23:48 CEST 2008 - ma@suse.de
+
+- Allow computation of disk usage per solvable.
+- revision 11218
+
+-------------------------------------------------------------------
 Mon Sep 29 23:59:10 CEST 2008 - dmacvicar@suse.de
 
 - Merge aria2c Media handler code from Google SOC 2008
index 159f3c0..4b2afa6 100644 (file)
@@ -31,71 +31,110 @@ using std::endl;
 namespace zypp
 { /////////////////////////////////////////////////////////////////
 
-  DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( const ResPool & pool_r )
-  {
-    DiskUsageCounter::MountPointSet result = mps;
+  ///////////////////////////////////////////////////////////////////
+  namespace
+  { /////////////////////////////////////////////////////////////////
 
-    if ( result.empty() )
+    struct SatMap : private base::NonCopyable
     {
-      // partitioning is not set
-      return result;
-    }
+      SatMap( unsigned capacity_r = 1 )
+      {
+        ::map_init( &_installedmap, sat::Pool::instance().capacity() );
+      }
 
-    sat::Pool satpool( sat::Pool::instance() );
-    if ( ! satpool.findSystemRepo() )
-    {
-      // take care we have at least an empty stystem repo.
-      // ::pool_calc_duchanges requires it.
-      satpool.systemRepo();
-      satpool.prepare();
-    }
+      void add( sat::Solvable solv_r )
+      {
+        MAPSET( &_installedmap, solv_r.id() );
+      }
+
+      void add( const PoolItem & pi_r )
+      { add( pi_r->satSolvable() ); }
 
-    // init satsolver result vector with mountpoints
-    static const ::DUChanges _initdu = { 0, 0, 0 };
-    std::vector< ::DUChanges> duchanges( result.size(), _initdu );
+      void add( const ResObject::constPtr & obj_r )
+      { add( obj_r->satSolvable() ); }
+
+      mutable ::Map _installedmap;
+    };
+
+    DiskUsageCounter::MountPointSet calcDiskUsage( const DiskUsageCounter::MountPointSet & mps_r, const SatMap & installedmap_r )
     {
-      unsigned idx = 0;
-      for_( it, result.begin(), result.end() )
+      DiskUsageCounter::MountPointSet result = mps_r;
+
+      if ( result.empty() )
       {
-        duchanges[idx].path = it->dir.c_str();
-        ++idx;
+        // partitioning is not set
+        return result;
       }
-    }
 
-    // build installedmap (installed != transact)
-    // stays installed or gets installed
-    ::Map installedmap;
-    ::map_init( &installedmap, satpool.capacity() );
-    for_( it, pool_r.begin(), pool_r.end() )
-    {
-      if ( it->status().isInstalled() != it->status().transacts() )
+      sat::Pool satpool( sat::Pool::instance() );
+      if ( ! satpool.findSystemRepo() )
       {
-        MAPSET( &installedmap, it->satSolvable().id() );
+        // take care we have at least an empty stystem repo.
+        // ::pool_calc_duchanges requires it.
+        satpool.systemRepo();
+        satpool.prepare();
       }
+
+      // init satsolver result vector with mountpoints
+      static const ::DUChanges _initdu = { 0, 0, 0 };
+      std::vector< ::DUChanges> duchanges( result.size(), _initdu );
+      {
+        unsigned idx = 0;
+        for_( it, result.begin(), result.end() )
+        {
+          duchanges[idx].path = it->dir.c_str();
+          ++idx;
+        }
+      }
+
+      // now calc...
+      ::pool_calc_duchanges( satpool.get(),
+                             satpool.systemRepo().get(),
+                             &installedmap_r._installedmap,
+                             &duchanges[0],
+                             duchanges.size() );
+
+      // and process the result
+      {
+        unsigned idx = 0;
+        for_( it, result.begin(), result.end() )
+        {
+          static const ByteCount blockAdjust( 2, ByteCount::K ); // (files * blocksize) / (2 * 1K)
+
+          it->pkg_size = it->used_size          // current usage
+                       + duchanges[idx].kbytes  // package data size
+                       + ( duchanges[idx].files * it->block_size / blockAdjust ); // half block per file
+          ++idx;
+        }
+      }
+
+      return result;
     }
 
-    // now calc...
-    ::pool_calc_duchanges( satpool.get(),
-                           satpool.systemRepo().get(),
-                           &installedmap,
-                           &duchanges[0],
-                           duchanges.size() );
+    /////////////////////////////////////////////////////////////////
+  } // namespace
+  ///////////////////////////////////////////////////////////////////
 
-    // and process the result
+  DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( const ResPool & pool_r )
+  {
+    SatMap installedmap( sat::Pool::instance().capacity() );
+    // build installedmap (installed != transact)
+    // stays installed or gets installed
+    for_( it, pool_r.begin(), pool_r.end() )
     {
-      unsigned idx = 0;
-      for_( it, result.begin(), result.end() )
+      if ( it->status().isInstalled() != it->status().transacts() )
       {
-        static const ByteCount blockAdjust( 2, ByteCount::K ); // (files * blocksize) / (2 * 1K)
-
-        it->pkg_size = it->used_size          // current usage
-                     + duchanges[idx].kbytes  // package data size
-                     + ( duchanges[idx].files * it->block_size / blockAdjust ); // half block per file
-        ++idx;
+        installedmap.add( *it );
       }
     }
+    return calcDiskUsage( mps, installedmap );
+  }
 
-    return result;
+  DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( sat::Solvable solv_r )
+  {
+    SatMap installedmap;
+    installedmap.add( solv_r );
+    return calcDiskUsage( mps, installedmap );
   }
 
   DiskUsageCounter::MountPointSet DiskUsageCounter::detectMountPoints(const std::string &rootdir)
@@ -237,15 +276,23 @@ namespace zypp
     return ret;
   }
 
+  DiskUsageCounter::MountPointSet DiskUsageCounter::justRootPartition()
+  {
+    DiskUsageCounter::MountPointSet ret;
+    ret.insert( DiskUsageCounter::MountPoint() );
+    return ret;
+  }
+
   std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPoint & obj )
   {
-    str << "dir:[" << obj.dir << "] [ bs: " << obj.block_size
-        << " ts: " << obj.total_size
-        << " us: " << obj.used_size
-        << " (+-: " << (obj.pkg_size-obj.used_size)
+     str << "dir:[" << obj.dir << "] [ bs: " << obj.blockSize()
+        << " ts: " << obj.totalSize()
+        << " us: " << obj.usedSize()
+        << " (+-: " << obj.commitDiff()
         << ")]";
     return str;
   }
 
+  /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////
index 64ccc4d..553f48a 100644 (file)
@@ -48,12 +48,12 @@ namespace zypp
       long long total_size;
 
       /**
-       * Used size in  (1024)
+       * Used size in K (1024)
        **/
       long long used_size;
 
       /**
-       * Used size after commiting the pool (in kB)
+       * Used size after commiting the pool (in K)
        **/
       mutable long long pkg_size;
 
@@ -63,36 +63,80 @@ namespace zypp
        * Ctor - initialize directory and package size
        **/
       MountPoint(std::string d = "/", long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL, bool ro=false) :
-        dir(d), block_size(bs), total_size(total), used_size(used), pkg_size(pkg), readonly(ro) {}
+        dir(d), block_size(bs), total_size(total), used_size(used), pkg_size(pkg), readonly(ro)
+      {}
 
       // sort by directory name
       bool operator<( const MountPoint & rhs ) const
       {
         return dir < rhs.dir;
       }
+
+      ByteCount blockSize() const
+      { return ByteCount( block_size, ByteCount::B ); }
+
+      ByteCount totalSize() const
+      { return ByteCount( total_size, ByteCount::K ); }
+
+      ByteCount usedSize() const
+      { return ByteCount( used_size, ByteCount::K ); }
+
+      ByteCount freeSize() const
+      { return ByteCount( total_size-used_size, ByteCount::K ); }
+
+      ByteCount usedAfterCommit() const
+      { return ByteCount( pkg_size, ByteCount::K ); }
+
+      ByteCount freeAfterCommit() const
+      { return ByteCount( total_size-pkg_size, ByteCount::K ); }
+
+      ByteCount commitDiff() const
+      { return ByteCount( pkg_size-used_size, ByteCount::K ); }
     };
 
     typedef std::set<MountPoint> MountPointSet;
 
-    DiskUsageCounter() {}
+    DiskUsageCounter()
+    {}
 
-    bool setMountPoints(const MountPointSet &m)
+    DiskUsageCounter( const MountPointSet & m )
+    : mps( m )
+    {}
+
+    bool setMountPoints( const MountPointSet & m )
     {
        mps = m;
        return true;
     }
 
-    MountPointSet getMountPoints() const
+    const MountPointSet & getMountPoints() const
     {
        return mps;
     }
 
     static MountPointSet detectMountPoints(const std::string &rootdir = "/");
 
+    static MountPointSet justRootPartition();
+
     /**
      * Compute disk usage of the pool
      **/
-    MountPointSet disk_usage(const ResPool &pool);
+    MountPointSet disk_usage( const ResPool & pool );
+
+    /**
+     * Compute disk usage of one solvable
+     */
+    MountPointSet disk_usage( sat::Solvable solv_r );
+    /** \overload */
+    MountPointSet disk_usage( const PoolItem & pi_r  )
+    { return disk_usage( pi_r.satSolvable() ); }
+    /** \overload */
+    MountPointSet disk_usage( const ResObject::constPtr & obj_r )
+    {
+      if ( ! obj_r )
+        return MountPointSet();
+      return disk_usage( obj_r->satSolvable() );
+    }
 
   private: