From a5b8ba4fab3addd34c106e9b9edae67e34988d41 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Tue, 30 Sep 2008 15:41:42 +0000 Subject: [PATCH] - Allow computation of disk usage per solvable. --- VERSION.cmake | 4 +- devel/devel.ma/MaTest.cc | 607 +++++++++++++++++++++++++++++++++++++++++----- devel/devel.ma/NewPool.cc | 30 +-- package/libzypp.changes | 6 + zypp/DiskUsageCounter.cc | 149 ++++++++---- zypp/DiskUsageCounter.h | 58 ++++- 6 files changed, 704 insertions(+), 150 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index c2f3c30..b4a7b1f 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -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) diff --git a/devel/devel.ma/MaTest.cc b/devel/devel.ma/MaTest.cc index 9b74140..6cda813 100644 --- a/devel/devel.ma/MaTest.cc +++ b/devel/devel.ma/MaTest.cc @@ -1,121 +1,596 @@ -#include +#include "Tools.h" -#include -#include +#include "zypp/PoolQueryResult.h" +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include -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 + +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(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 - std::ostream & operator<<( std::ostream & str, const signal & obj ) + template + 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(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 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 +{ + 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 { - 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 +{ + virtual Action requestMedia( Url & source + , unsigned mediumNr + , const std::string & label + , Error error + , const std::string & description + , const std::vector & 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 + 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 HasValue + { + public: + HasValue( _MemFun fun_r, _Value val_r ) + : _fun( fun_r ), _val( val_r ) + {} + template + bool operator()( const _Tp & obj_r ) const + { return( _fun && (obj_r.*_fun)() == _val ); } + private: + _MemFun _fun; + _Value _val; + }; + + template + HasValue<_MemFun, _Value> byValue( _MemFun fun_r, _Value val_r ) + { return HasValue<_MemFun, _Value>( fun_r, val_r ); } +} + +} + +template +struct _TestO { _TestO( const L & lhs ) : _lhs( lhs ) {} const L & _lhs; }; + +template +std::ostream & operator<<( std::ostream & str, const _TestO & obj ) +{ const L & lhs( obj._lhs); return str << (lhs?'_':'*') << (lhs.empty()?'e':'_') << "'" << lhs << "'"; } + +template +_TestO testO( const L & lhs ) +{ return _TestO( lhs ); } + +template +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(pool), + make_filter_end(pool) ) << endl; + + ByteCount sze; + ByteCount dusze; + DiskUsageCounter ducounter( DiskUsageCounter::justRootPartition() ); + for_( it, make_filter_begin(pool), make_filter_end(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 (...) +{} + diff --git a/devel/devel.ma/NewPool.cc b/devel/devel.ma/NewPool.cc index e0812b9..fb6c048 100644 --- a/devel/devel.ma/NewPool.cc +++ b/devel/devel.ma/NewPool.cc @@ -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("amarok") ); - MIL << pi << endl; - MIL << pi->asKind() << endl; - MIL << pi->asKind() << endl; - if ( pi->isKind() ) - SEC << pi->asKind() << endl; + getZYpp()->resolver()->addRequire( Capability("amarok") ); + solve(); + vdumpPoolStats( USR << "Transacting:"<< endl, + make_filter_begin(pool), + make_filter_end(pool) ) << endl; ////////////////////////////////////////////////////////////////// INT << "===[END]============================================" << endl << endl; diff --git a/package/libzypp.changes b/package/libzypp.changes index 81a47e8..3306b9d 100644 --- a/package/libzypp.changes +++ b/package/libzypp.changes @@ -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 diff --git a/zypp/DiskUsageCounter.cc b/zypp/DiskUsageCounter.cc index 159f3c0..4b2afa6 100644 --- a/zypp/DiskUsageCounter.cc +++ b/zypp/DiskUsageCounter.cc @@ -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 /////////////////////////////////////////////////////////////////// diff --git a/zypp/DiskUsageCounter.h b/zypp/DiskUsageCounter.h index 64ccc4d..553f48a 100644 --- a/zypp/DiskUsageCounter.h +++ b/zypp/DiskUsageCounter.h @@ -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 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: -- 2.7.4