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