1 //*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 
22     /// \file statistics.hpp
23     /// \brief handle the statistic structure that gives a summary of treated files after each operatio
24     /// \ingroup API
25 
26 #ifndef STATISTICS_HPP
27 #define STATISTICS_HPP
28 
29 #include "../my_config.h"
30 
31 #include "infinint.hpp"
32 #include "user_interaction.hpp"
33 
34 extern "C"
35 {
36 #if MUTEX_WORKS
37 #if HAVE_PTHREAD_H
38 #include <pthread.h>
39 #endif
40 #endif
41 }
42 
43     /// \addtogroup Private
44     /// @{
45 
46 #if MUTEX_WORKS
47 #define LOCK_IN pthread_mutex_lock(&lock_mutex)
48 #define LOCK_OUT pthread_mutex_unlock(&lock_mutex)
49 #define LOCK_IN_CONST pthread_mutex_lock(const_cast<pthread_mutex_t *>(&lock_mutex))
50 #define LOCK_OUT_CONST pthread_mutex_unlock(const_cast<pthread_mutex_t *>(&lock_mutex))
51 #else
52 #define LOCK_IN //
53 #define LOCK_OUT //
54 #define LOCK_IN_CONST //
55 #define LOCK_OUT_CONST //
56 #endif
57 
58 namespace libdar
59 {
60 
61 	/// structure returned by libdar call to give a summary of the operation done in term of file treated
62 
63 	/// the different fields are used for backup, restoration and other operation
64 	/// their meaning changes a bit depending on the operation. Some operation may
65 	/// not use all fields. To have a detailed view of what fields get used and what
66 	// are their meaning see the archive class constructor and methods documentation
67 	/// \ingroup API
68     class statistics
69     {
70     public:
71 	    /// constructor
72 
73 	    /// \param[in] lock whether to use mutex to manipulate (read or write) variables of that object
74 	    /// \note using a statistics object built without lock (false given as argument to the constructor) may
75 	    /// lead to application crash if several threads are accessing at the same object at the same time when
76 	    /// at least one thread is modifying this object, unless you really know what you are doing, it is better
77 	    /// to always use the default value for this constructor or to explicitely give "true" as argument.
statistics(bool lock=true)78 	statistics(bool lock = true) { init(lock); clear(); };
statistics(const statistics & ref)79 	statistics(const statistics & ref) { copy_from(ref); };
operator =(const statistics & ref)80 	const statistics & operator = (const statistics & ref) { detruit(); copy_from(ref); return *this; };
81 
82 	    /// destructor
~statistics()83 	~statistics() { detruit(); };
84 
85 	    /// reset counters to zero
86         void clear();
87 
88 	    /// total number of file treated
89         infinint total() const;
90 
incr_treated()91 	void incr_treated() { (this->*increment)(&treated); };       ///< increment by one the treated counter
incr_hard_links()92 	void incr_hard_links() { (this->*increment)(&hard_links); }; ///< increment by one the hard_links counter
incr_skipped()93 	void incr_skipped() { (this->*increment)(&skipped); };       ///< increment by one the skipped counter
incr_ignored()94 	void incr_ignored() { (this->*increment)(&ignored); };       ///< increment by one the ignored counter
incr_tooold()95 	void incr_tooold() { (this->*increment)(&tooold); };         ///< increment by one the tooold counter
incr_errored()96 	void incr_errored() { (this->*increment)(&errored); };       ///< increment by one the errored counter
incr_deleted()97 	void incr_deleted() { (this->*increment)(&deleted); };       ///< increment by one the deleted counter
incr_ea_treated()98 	void incr_ea_treated() { (this->*increment)(&ea_treated); }; ///< increment by one the ea_treated counter
incr_fsa_treated()99 	void incr_fsa_treated() { (this->*increment)(&fsa_treated); }; ///< increment by one the fsa treated counter
100 
add_to_ignored(const infinint & val)101 	void add_to_ignored(const infinint & val) { (this->*add_to)(&ignored, val); };  ///< increment the ignored counter by a given value
add_to_errored(const infinint & val)102 	void add_to_errored(const infinint & val) { (this->*add_to)(&errored, val); };  ///< increment the errored counter by a given value
add_to_deleted(const infinint & val)103 	void add_to_deleted(const infinint & val) { (this->*add_to)(&deleted, val); };  ///< increment the deleted counter by a given value
add_to_byte_amount(const infinint & val)104 	void add_to_byte_amount(const infinint & val) { (this->*add_to)(&byte_amount, val); }; ///< increment the byte amount counter by a given value
105 
sub_from_treated(const infinint & val)106 	void sub_from_treated(const infinint & val) { (this->*sub_from)(&treated, val); };
sub_from_ea_treated(const infinint & val)107 	void sub_from_ea_treated(const infinint & val) { (this->*sub_from)(&ea_treated, val); };
sub_from_hard_links(const infinint & val)108 	void sub_from_hard_links(const infinint & val) { (this->*sub_from)(&hard_links, val); };
sub_from_fsa_treated(const infinint & val)109 	void sub_from_fsa_treated(const infinint & val) { (this->*sub_from)(&fsa_treated, val); };
110 
get_treated() const111 	infinint get_treated() const { return (this->*returned)(&treated); };     ///< returns the current value of the treated counter
get_hard_links() const112 	infinint get_hard_links() const { return (this->*returned)(&hard_links); }; ///< returns the current value of the hard_links counter
get_skipped() const113 	infinint get_skipped() const { return (this->*returned)(&skipped); };     ///< returns the current value of the skipped counter
get_ignored() const114 	infinint get_ignored() const { return (this->*returned)(&ignored); };     ///< returns the current value of the ignored counter
get_tooold() const115 	infinint get_tooold() const { return (this->*returned)(&tooold); };       ///< returns the current value of the tooold counter
get_errored() const116 	infinint get_errored() const { return (this->*returned)(&errored); };     ///< returns the current value of the errored counter
get_deleted() const117 	infinint get_deleted() const { return (this->*returned)(&deleted); };     ///< returns the current value of the deleted counter
get_ea_treated() const118 	infinint get_ea_treated() const { return (this->*returned)(&ea_treated); };  ///< returns the current value of the ea_treated counter
get_byte_amount() const119 	infinint get_byte_amount() const { return (this->*returned)(&byte_amount); };  ///< returns the current value of the byte_amount counter
get_fsa_treated() const120 	infinint get_fsa_treated() const { return (this->*returned)(&fsa_treated); }; ///< returns the current value of the fsa_treated counter
121 
decr_treated()122 	void decr_treated() { (this->*decrement)(&treated); };        ///< decrement by one the treated counter
decr_hard_links()123 	void decr_hard_links() { (this->*decrement)(&hard_links); };  ///< decrement by one the hard_links counter
decr_skipped()124 	void decr_skipped() { (this->*decrement)(&skipped); };        ///< decrement by one the skipped counter
decr_ignored()125 	void decr_ignored() { (this->*decrement)(&ignored); };        ///< decrement by one the ignored counter
decr_tooold()126 	void decr_tooold() { (this->*decrement)(&tooold); };          ///< decrement by one the toold counter
decr_errored()127 	void decr_errored() { (this->*decrement)(&errored); };        ///< decrement by one the errored counter
decr_deleted()128 	void decr_deleted() { (this->*decrement)(&deleted); };        ///< decrement by one the deleted counter
decr_ea_treated()129 	void decr_ea_treated() { (this->*decrement)(&ea_treated); };  ///< decrement by one the ea_treated counter
decr_fsa_treated()130 	void decr_fsa_treated() { (this->*decrement)(&fsa_treated); };///< decrement by one the fsa_treated counter
131 
set_byte_amount(const infinint & val)132 	void set_byte_amount(const infinint & val) { (this->*set_to)(&byte_amount, val); }; ///< set to the given value the byte_amount counter
133 
134 	    // debuging method
135 	void dump(user_interaction & dialog) const;
136 
137     private:
138 #if MUTEX_WORKS
139 	pthread_mutex_t lock_mutex;   ///< lock the access to the private variable of the curent object
140 #endif
141 	bool locking;           ///< whether we use locking or not
142 
143         infinint treated;       ///< number of inode treated (saved, restored, etc.) [all operations]
144         infinint hard_links;    ///< number of hard linked inodes treated (including those ignored by filters)
145         infinint skipped;       ///< files not changed since last backup / file not restored because not saved in backup
146         infinint ignored;       ///< ignored files due to filters
147         infinint tooold;        ///< ignored files because less recent than the filesystem entry [restoration] / modfied during backup
148         infinint errored;       ///< files that could not be saved / files that could not be restored (filesystem access right)
149         infinint deleted;       ///< deleted file seen / number of files deleted during the operation [restoration]
150         infinint ea_treated;    ///< number of EA saved / number of EA restored
151 	infinint byte_amount;   ///< auxilliary counter, holds the wasted bytes due to repeat on change feature for example.
152 	infinint fsa_treated;   ///< number of FSA saved / number of FSA restored
153 
154 
155 	void (statistics::*increment)(infinint * var);                    ///< generic method for incrementing a variable
156 	void (statistics::*add_to)(infinint * var, const infinint & val); ///< generic method for add a value to a variable
157  	infinint (statistics::*returned)(const infinint * var) const;     ///< generic method for obtaining the value of a variable
158 	void (statistics::*decrement)(infinint * var);                    ///< generic method for decrementing a variable
159 	void (statistics::*set_to)(infinint * var, const infinint & val); ///< generic method for setting a variable to a given value
160 	void (statistics::*sub_from)(infinint *var, const infinint & val);///< generic method for substracting to a variable
161 
increment_locked(infinint * var)162 	void increment_locked(infinint * var)
163 	{
164 	    LOCK_IN;
165 	    (*var)++;
166 	    LOCK_OUT;
167 	};
168 
increment_unlocked(infinint * var)169 	void increment_unlocked(infinint * var)
170 	{
171 	    (*var)++;
172 	}
173 
add_to_locked(infinint * var,const infinint & val)174 	void add_to_locked(infinint * var, const infinint & val)
175 	{
176 	    LOCK_IN;
177 	    (*var) += val;
178 	    LOCK_OUT;
179 	}
180 
add_to_unlocked(infinint * var,const infinint & val)181 	void add_to_unlocked(infinint *var, const infinint & val)
182 	{
183 	    (*var) += val;
184 	}
185 
returned_locked(const infinint * var) const186 	infinint returned_locked(const infinint * var) const
187 	{
188 	    infinint ret;
189 
190 	    LOCK_IN_CONST;
191 	    ret = *var;
192 	    LOCK_OUT_CONST;
193 
194 	    return ret;
195 	};
196 
returned_unlocked(const infinint * var) const197 	infinint returned_unlocked(const infinint * var) const
198 	{
199 	    return *var;
200 	};
201 
decrement_locked(infinint * var)202 	void decrement_locked(infinint * var)
203 	{
204 	    LOCK_IN;
205 	    (*var)--;
206 	    LOCK_OUT;
207 	}
208 
decrement_unlocked(infinint * var)209 	void decrement_unlocked(infinint * var)
210 	{
211 	    (*var)--;
212 	}
213 
set_to_locked(infinint * var,const infinint & val)214 	void set_to_locked(infinint *var, const infinint & val)
215 	{
216 	    LOCK_IN;
217 	    (*var) = val;
218 	    LOCK_OUT;
219 	}
220 
set_to_unlocked(infinint * var,const infinint & val)221 	void set_to_unlocked(infinint *var, const infinint & val)
222 	{
223 	    *var = val;
224 	}
225 
sub_from_unlocked(infinint * var,const infinint & val)226 	void sub_from_unlocked(infinint *var, const infinint & val)
227 	{
228 	    *var -= val;
229 	}
230 
sub_from_locked(infinint * var,const infinint & val)231 	void sub_from_locked(infinint *var, const infinint & val)
232 	{
233 	    LOCK_IN;
234 	    *var -= val;
235 	    LOCK_OUT;
236 	}
237 
238 
239 	void init(bool lock); // set locking & mutex
240 	void detruit();       // release and free the mutex
241 	void copy_from(const statistics & ref); // reset mutex and copy data from the object of reference
242 
243     };
244 
245 } // end of namespace
246 
247     /// @}
248 
249 #endif
250