Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / DiskUsageCounter.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/DiskUsageCounter.h
10  *
11 */
12 #ifndef ZYPP_DISKUSAGE_COUNTER_H
13 #define ZYPP_DISKUSAGE_COUNTER_H
14
15 #include <set>
16 #include <string>
17 #include <iosfwd>
18
19 #include "zypp/ResPool.h"
20 #include "zypp/Bitmap.h"
21 #include "zypp/base/Flags.h"
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26
27   ///////////////////////////////////////////////////////////////////
28   /// \class DiskUsageCounter
29   /// \brief Compute disk space occupied by packages across partitions/directories
30   ///////////////////////////////////////////////////////////////////
31   class DiskUsageCounter
32   {
33
34   public:
35     ///////////////////////////////////////////////////////////////////
36     /// \class MountPoint
37     /// \brief Mount point description
38     /// If \ref block_size is set \ref DiskUsageCoutner will assume
39     /// half a block_size is wasted per file, in case a package
40     /// provides detailed isk usage information.
41     ///////////////////////////////////////////////////////////////////
42     struct MountPoint
43     {
44       friend std::ostream & operator<<( std::ostream & str, const MountPoint & obj );
45       std::string dir;                  ///< Directory name
46       std::string fstype;               ///< Filesystem type  (provided by \ref detectMountPoints)
47       long long block_size;             ///< Block size of the filesystem in B (0 if you don't care)
48       long long total_size;             ///< Total size of the filesystem in KiB (0 if you don't care)
49       long long used_size;              ///< Used size of the filesystem in KiB (0 if you don't care)
50       mutable long long pkg_size;       ///< Used size after installation in KiB (computed by \ref DiskUsageCoutner)
51       // hint bits:
52       bool readonly:1;                  ///< hint for readonly partitions
53       bool growonly:1;                  ///< hint for growonly partitions (e.g. snapshotting btrfs)
54
55
56       /** HinFlags for ctor */
57       enum Hint
58       {
59         NoHint          = 0,
60         Hint_readonly   = (1<<0),       ///< readonly partitions
61         Hint_growonly   = (1<<1),       ///< growonly partitions (e.g. snapshotting btrfs)
62       };
63       ZYPP_DECLARE_FLAGS(HintFlags,Hint);
64
65       /** Ctor initialize directory, fstype and sizes */
66       MountPoint( const std::string & d = "/",
67                   const std::string & f = std::string(),
68                   long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL,
69                   HintFlags hints = NoHint )
70         : dir(d), fstype(f)
71         , block_size(bs), total_size(total), used_size(used), pkg_size(pkg)
72         , readonly(hints.testFlag(Hint_readonly))
73         , growonly(hints.testFlag(Hint_growonly))
74       {}
75        /** \overload <tt>const char *</tt> to allow e.g. initiailzer lists
76        * \code
77        *   MountPointSet( { "/", "/usr", "/var" } )
78        * \endcode
79        */
80       MountPoint( const char * d,
81                   const std::string & f = std::string(),
82                   long long bs = 0LL, long long total = 0LL, long long used = 0LL, long long pkg = 0LL,
83                   HintFlags hints = NoHint )
84         : MountPoint( std::string(d?d:""), f, bs, total, used, pkg, hints )
85       {}
86
87
88       /** Ctor initialize directory and sizes */
89       MountPoint( const std::string & d,
90                   long long bs, long long total = 0LL, long long used = 0LL, long long pkg = 0LL,
91                   HintFlags hints = NoHint )
92         : MountPoint( d, std::string(), bs, total, used, pkg, hints )
93       {}
94       /** \overload <tt>const char *</tt> */
95       MountPoint( const char * d,
96                   long long bs, long long total = 0LL, long long used = 0LL, long long pkg = 0LL,
97                   HintFlags hints = NoHint )
98         : MountPoint( std::string(d?d:""), bs, total, used, pkg, hints )
99       {}
100
101
102       /** Ctor just name and hints, all sizes 0 */
103       MountPoint( const std::string & d, HintFlags hints )
104         : MountPoint( d, std::string(), 0LL, 0LL, 0LL, 0LL, hints )
105       {}
106       /** \overload <tt>const char *</tt> */
107       MountPoint( const char * d, HintFlags hints )
108         : MountPoint( std::string(d?d:""), hints )
109       {}
110       /** \overload to prevent propagation Hint -> long long */
111       MountPoint( const std::string & d, Hint hint )
112         : MountPoint( d, HintFlags(hint) )
113       {}
114       /** \overload to prevent propagation Hint -> long long */
115       MountPoint( const char * d, Hint hint )
116         : MountPoint( std::string(d?d:""), HintFlags(hint) )
117       {}
118
119       /** Sort by directory name */
120       bool operator<( const MountPoint & rhs ) const
121       { return dir < rhs.dir; }
122
123       /** Block size of the filesystem as \ref ByteCount for convenience. */
124       ByteCount blockSize() const
125       { return ByteCount( block_size, ByteCount::B ); }
126
127       /** Total size of the filesystem as \ref ByteCount for convenience. */
128       ByteCount totalSize() const
129       { return ByteCount( total_size, ByteCount::K ); }
130
131       /** Used size of the filesystem as \ref ByteCount for convenience. */
132       ByteCount usedSize() const
133       { return ByteCount( used_size, ByteCount::K ); }
134
135       /** Free size of the filesystem as \ref ByteCount for convenience. */
136       ByteCount freeSize() const
137       { return ByteCount( total_size-used_size, ByteCount::K ); }
138
139       /** Used size after installation as \ref ByteCount for convenience. */
140       ByteCount usedAfterCommit() const
141       { return ByteCount( pkg_size, ByteCount::K ); }
142
143       /** Free size after installation as \ref ByteCount for convenience. */
144       ByteCount freeAfterCommit() const
145       { return ByteCount( total_size-pkg_size, ByteCount::K ); }
146
147       /** Size change due to installation as \ref ByteCount for convenience. */
148       ByteCount commitDiff() const
149       { return ByteCount( pkg_size-used_size, ByteCount::K ); }
150     };
151     ///////////////////////////////////////////////////////////////////
152
153     typedef std::set<MountPoint> MountPointSet;
154
155     DiskUsageCounter()
156     {}
157
158     /** Ctor taking the MountPointSet to compute */
159     DiskUsageCounter( const MountPointSet & mps_r )
160     : _mps( mps_r )
161     {}
162
163     /** Set a MountPointSet to compute */
164     void setMountPoints( const MountPointSet & mps_r )
165     { _mps = mps_r; }
166
167     /** Get the current MountPointSet */
168     const MountPointSet & getMountPoints() const
169     { return _mps; }
170
171     /** Get mountpoints of system below \a rootdir
172      * If we happen to detect snapshotting btrfs partitions, the MountPoint::growonly
173      * hint is set. Disk usage computation will assume that deleted packages will not
174      * free any space (kept in a snapshot).
175      */
176     static MountPointSet detectMountPoints( const std::string & rootdir = "/" );
177
178     /** Only one entry for "/" to collect total sizes */
179     static MountPointSet justRootPartition();
180
181
182     /** Compute disk usage if the current transaction woud be commited. */
183     MountPointSet disk_usage( const ResPool & pool ) const;
184
185     /** Compute disk usage of a single Solvable */
186     MountPointSet disk_usage( sat::Solvable solv_r ) const;
187     /** \overload for PoolItem */
188     MountPointSet disk_usage( const PoolItem & pi_r  ) const
189     { return disk_usage( sat::asSolvable()( pi_r ) ); }
190     /** \overload for ResObject */
191     MountPointSet disk_usage( const ResObject::constPtr & obj_r ) const
192     { return disk_usage( sat::asSolvable()( obj_r ) ); }
193
194     /** Compute disk usage of a collection defined by a solvable bitmap. */
195     MountPointSet disk_usage( const Bitmap & bitmap_r ) const;
196
197     /** Compute disk usage of a collection (convertible by \ref asSolvable). */
198     template<class Iterator>
199     MountPointSet disk_usage( Iterator begin_r, Iterator end_r ) const
200     {
201       Bitmap bitmap( Bitmap::poolSize );
202       for_( it, begin_r, end_r )
203         bitmap.set( sat::asSolvable()( *it ).id() );
204       return disk_usage( bitmap );
205     }
206
207   private:
208     MountPointSet _mps;
209   };
210   ///////////////////////////////////////////////////////////////////
211
212   ZYPP_DECLARE_OPERATORS_FOR_FLAGS(DiskUsageCounter::MountPoint::HintFlags);
213
214   /** \relates DiskUsageCounter::MountPoint Stream output */
215   std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPoint & obj );
216
217   /** \relates DiskUsageCounter::MountPointSet Stream output */
218   std::ostream & operator<<( std::ostream & str, const DiskUsageCounter::MountPointSet & obj );
219
220   /** \relates DiskUsageCounter Stream output */
221   inline std::ostream & operator<<( std::ostream & str, const DiskUsageCounter & obj )
222   { return str << obj.getMountPoints(); }
223
224   /////////////////////////////////////////////////////////////////
225 } // namespace zypp
226 ///////////////////////////////////////////////////////////////////
227 #endif // ZYPP_DISKUSAGE_COUNTER_H