From 44dd1dd3fa1189e3b7ebe87a4fc2be5d8809237d Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Fri, 13 Dec 2013 19:28:53 +0100 Subject: [PATCH] Polish DiskUsageCounter --- zypp/DiskUsageCounter.cc | 53 +++++++---------- zypp/DiskUsageCounter.h | 150 ++++++++++++++++++++++++----------------------- zypp/ResObject.h | 28 +++++++-- 3 files changed, 123 insertions(+), 108 deletions(-) diff --git a/zypp/DiskUsageCounter.cc b/zypp/DiskUsageCounter.cc index 551af8f..0918b30 100644 --- a/zypp/DiskUsageCounter.cc +++ b/zypp/DiskUsageCounter.cc @@ -36,28 +36,7 @@ namespace zypp namespace { ///////////////////////////////////////////////////////////////// - struct SatMap : private base::NonCopyable - { - SatMap() - { - ::map_init( &_installedmap, sat::Pool::instance().capacity() ); - } - - void add( sat::Solvable solv_r ) - { - MAPSET( &_installedmap, solv_r.id() ); - } - - void add( const PoolItem & pi_r ) - { add( pi_r->satSolvable() ); } - - void add( const ResObject::constPtr & obj_r ) - { add( obj_r->satSolvable() ); } - - mutable ::Map _installedmap; - }; - - DiskUsageCounter::MountPointSet calcDiskUsage( DiskUsageCounter::MountPointSet result, const SatMap & installedmap_r ) + DiskUsageCounter::MountPointSet calcDiskUsage( DiskUsageCounter::MountPointSet result, const Bitmap & installedmap_r ) { if ( result.empty() ) { @@ -81,7 +60,7 @@ namespace zypp // now calc... ::pool_calc_duchanges( satpool.get(), - &installedmap_r._installedmap, + const_cast(installedmap_r), &duchanges[0], duchanges.size() ); @@ -105,34 +84,44 @@ namespace zypp } // namespace /////////////////////////////////////////////////////////////////// - DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( const ResPool & pool_r ) + DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( const ResPool & pool_r ) const { - SatMap installedmap; + Bitmap bitmap( Bitmap::poolSize ); + // build installedmap (installed != transact) // stays installed or gets installed for_( it, pool_r.begin(), pool_r.end() ) { if ( it->status().isInstalled() != it->status().transacts() ) { - installedmap.add( *it ); + bitmap.set( sat::asSolvable()(*it).id() ); } } - return calcDiskUsage( mps, installedmap ); + return calcDiskUsage( _mps, bitmap ); } - DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( sat::Solvable solv_r ) + DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( sat::Solvable solv_r ) const { - SatMap installedmap; - installedmap.add( solv_r ); + Bitmap bitmap( Bitmap::poolSize ); + bitmap.set( solv_r.id() ); // temp. unset @system Repo DtorReset tmp( sat::Pool::instance().get()->installed ); sat::Pool::instance().get()->installed = nullptr; - return calcDiskUsage( mps, installedmap ); + return calcDiskUsage( _mps, bitmap ); + } + + DiskUsageCounter::MountPointSet DiskUsageCounter::disk_usage( const Bitmap & bitmap_r ) const + { + // temp. unset @system Repo + DtorReset tmp( sat::Pool::instance().get()->installed ); + sat::Pool::instance().get()->installed = nullptr; + + return calcDiskUsage( _mps, bitmap_r ); } - DiskUsageCounter::MountPointSet DiskUsageCounter::detectMountPoints(const std::string &rootdir) + DiskUsageCounter::MountPointSet DiskUsageCounter::detectMountPoints( const std::string & rootdir ) { DiskUsageCounter::MountPointSet ret; diff --git a/zypp/DiskUsageCounter.h b/zypp/DiskUsageCounter.h index 439e78a..02f6f8d 100644 --- a/zypp/DiskUsageCounter.h +++ b/zypp/DiskUsageCounter.h @@ -12,135 +12,141 @@ #ifndef ZYPP_DISKUSAGE_COUNTER_H #define ZYPP_DISKUSAGE_COUNTER_H -#include "zypp/ResPool.h" - #include #include #include +#include "zypp/ResPool.h" +#include "zypp/Bitmap.h" + /////////////////////////////////////////////////////////////////// namespace zypp { ///////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + /// \class DiskUsageCounter + /// \brief Compute disk space occupied by packages across partitions/directories + /////////////////////////////////////////////////////////////////// class DiskUsageCounter { public: - - /** - * @short Mount point description - **/ + /////////////////////////////////////////////////////////////////// + /// \class MountPoint + /// \brief Mount point description + /// If \ref block_size is set \ref DiskUsageCoutner will assume + /// half a block_size is wasted per file, in case a package + /// provides detailed isk usage information. + /////////////////////////////////////////////////////////////////// struct MountPoint { - /** - * Directory name - **/ - std::string dir; - - /** - * Block size of the mount point - **/ - long long block_size; - - /** - * Total size in K (1024) - **/ - long long total_size; - - /** - * Used size in K (1024) - **/ - long long used_size; - - /** - * Used size after commiting the pool (in K) - **/ - mutable long long pkg_size; - - bool readonly; - - /** - * 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) + std::string dir; ///< Directory name + long long block_size; ///< Block size of the filesystem in B (0 if you don't care) + long long total_size; ///< Total size of the filesystem in KiB (0 if you don't care) + long long used_size; ///< Used size of the filesystem in KiB (0 if you don't care) + mutable long long pkg_size; ///< Used size after installation in KiB (computed by \ref DiskUsageCoutner) + bool readonly; ///< hint for readonly partitions + + /** Ctor initialize directory and sizes */ + MountPoint( const 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) + {} + /** \overload to allow e.g. initiailzer lists + * \code + * MountPointSet( { "/", "/usr", "/var" } ) + * \endcode + */ + MountPoint( const char * d, long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL, bool ro=false) + : dir(d?d:""), block_size(bs), total_size(total), used_size(used), pkg_size(pkg), readonly(ro) {} - // sort by directory name + /** Sort by directory name */ bool operator<( const MountPoint & rhs ) const - { - return dir < rhs.dir; - } + { return dir < rhs.dir; } + /** Block size of the filesystem as \ref ByteCount for convenience. */ ByteCount blockSize() const { return ByteCount( block_size, ByteCount::B ); } + /** Total size of the filesystem as \ref ByteCount for convenience. */ ByteCount totalSize() const { return ByteCount( total_size, ByteCount::K ); } + /** Used size of the filesystem as \ref ByteCount for convenience. */ ByteCount usedSize() const { return ByteCount( used_size, ByteCount::K ); } + /** Free size of the filesystem as \ref ByteCount for convenience. */ ByteCount freeSize() const { return ByteCount( total_size-used_size, ByteCount::K ); } + /** Used size after installation as \ref ByteCount for convenience. */ ByteCount usedAfterCommit() const { return ByteCount( pkg_size, ByteCount::K ); } + /** Free size after installation as \ref ByteCount for convenience. */ ByteCount freeAfterCommit() const { return ByteCount( total_size-pkg_size, ByteCount::K ); } + /** Size change due to installation as \ref ByteCount for convenience. */ ByteCount commitDiff() const { return ByteCount( pkg_size-used_size, ByteCount::K ); } }; + /////////////////////////////////////////////////////////////////// typedef std::set MountPointSet; DiskUsageCounter() {} - DiskUsageCounter( const MountPointSet & m ) - : mps( m ) + /** Ctor taking the MountPointSet to compute */ + DiskUsageCounter( const MountPointSet & mps_r ) + : _mps( mps_r ) {} - bool setMountPoints( const MountPointSet & m ) - { - mps = m; - return true; - } + /** Set a MountPointSet to compute */ + void setMountPoints( const MountPointSet & mps_r ) + { _mps = mps_r; } + /** Get the current MountPointSet */ const MountPointSet & getMountPoints() const - { - return mps; - } + { return _mps; } - static MountPointSet detectMountPoints(const std::string &rootdir = "/"); + /** Get mountpoints of system below \a rootdir */ + static MountPointSet detectMountPoints( const std::string & rootdir = "/" ); + + /** Only one entry for "/" to collect total sizes */ static MountPointSet justRootPartition(); - /** - * Compute disk usage of the 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 ) + + /** Compute disk usage if the current transaction woud be commited. */ + MountPointSet disk_usage( const ResPool & pool ) const; + + /** Compute disk usage of a single Solvable */ + MountPointSet disk_usage( sat::Solvable solv_r ) const; + /** \overload for PoolItem */ + MountPointSet disk_usage( const PoolItem & pi_r ) const + { return disk_usage( sat::asSolvable()( pi_r ) ); } + /** \overload for ResObject */ + MountPointSet disk_usage( const ResObject::constPtr & obj_r ) const + { return disk_usage( sat::asSolvable()( obj_r ) ); } + + /** Compute disk usage of a collection defined by a solvable bitmap. */ + MountPointSet disk_usage( const Bitmap & bitmap_r ) const; + + /** Compute disk usage of a collection (convertible by \ref asSolvable). */ + template + MountPointSet disk_usage( Iterator begin_r, Iterator end_r ) const { - if ( ! obj_r ) - return MountPointSet(); - return disk_usage( obj_r->satSolvable() ); + Bitmap bitmap( Bitmap::poolSize ); + for_( it, begin_r, end_r ) + bitmap.set( sat::asSolvable()( *it ).id() ); + return disk_usage( bitmap ); } private: - - MountPointSet mps; + MountPointSet _mps; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/ResObject.h b/zypp/ResObject.h index 71c0cec..77964af 100644 --- a/zypp/ResObject.h +++ b/zypp/ResObject.h @@ -130,13 +130,13 @@ namespace zypp std::string licenseToConfirm( const Locale & lang_r = Locale() ) const; /** - * \short Acceptance of Product License needed? + * \short Acceptance of Product License needed? * * Returns whether a product license has to be accepted * (no acceptance is needed for openSUSE) */ bool needToAcceptLicense() const; - + /** * \short Vendor * @@ -158,10 +158,30 @@ namespace zypp */ std::string cpeId() const; - /** Installed size. */ + /** Installed (unpacked) size. + * This is just a total number. Many objects provide even more detailed + * disk usage data. You can use \ref DiskUsageCounter to find out + * how objects data are distributed across partitions/directories. + * \code + * // Load directory set into ducounter + * DiskUsageCounter ducounter( { "/", "/usr", "/var" } ); + * + * // see how noch space the packages use + * for ( const PoolItem & pi : pool ) + * { + * cout << pi << ducounter.disk_usage( pi ) << endl; + * // I__s_(7)GeoIP-1.4.8-3.1.2.x86_64(@System) { + * // dir:[/] [ bs: 0 B ts: 0 B us: 0 B (+-: 1.0 KiB)] + * // dir:[/usr] [ bs: 0 B ts: 0 B us: 0 B (+-: 133.0 KiB)] + * // dir:[/var] [ bs: 0 B ts: 0 B us: 0 B (+-: 1.1 MiB)] + * // } + * } + * \endcode + * \see \ref DiskUsageCounter + */ ByteCount installSize() const; - /** Size of the rpm package. */ + /** Download size. */ ByteCount downloadSize() const; /** \see \ref sat::Solvable::repository */ -- 2.7.4