Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef ZORBA_AUDIT_SCOPED_H
00018 #define ZORBA_AUDIT_SCOPED_H
00019
00020 #include <iostream>
00021 #include <sstream>
00022 #include <cassert>
00023 #include <zorba/audit.h>
00024 #include <zorba/util/timer.h>
00025
00026 namespace zorba {
00027 namespace audit {
00028
00029 class ZORBA_DLL_PUBLIC ScopedRecord {
00030 public:
00031 ScopedRecord(Event* event)
00032 : theEvent(event ? event : Event::get()),
00033 theRecord(0) {
00034 assert(theEvent);
00035 }
00036
00037 ~ScopedRecord() {
00038 if (theRecord) {
00039 theEvent->submitRecord(theRecord);
00040 theRecord = 0;
00041 }
00042 }
00043
00044 Event* getEvent() {
00045 return theEvent;
00046 }
00047
00048 Record* getRecord() {
00049 if (! theRecord) {
00050 theRecord = theEvent->createRecord();
00051 }
00052 return theRecord;
00053 }
00054
00055 private:
00056 Event* theEvent;
00057 Record* theRecord;
00058 };
00059
00060 template <class T, unsigned char flags = 0> struct AuditorTraits {
00061 };
00062
00063 template <class T, unsigned char flags = 0> class ScopedAuditor {
00064 public:
00065 ScopedAuditor(ScopedRecord& record, const Property& prop, T& value)
00066 : theRecord(record), theProperty(prop), theValue(value) {
00067 theNeedToAuditFlag = record.getEvent()->audit(prop);
00068 if (theNeedToAuditFlag) {
00069 AuditorTraits<T, flags>::start(value);
00070 }
00071 }
00072
00073 ScopedAuditor(ScopedRecord& record, const String& prop_name, T& value)
00074 : theRecord(record),
00075 theProperty(*record.getEvent()->getDynamicProperty(prop_name)),
00076 theValue(value) {
00077 theNeedToAuditFlag = record.getEvent()->audit(prop_name);
00078 if (theNeedToAuditFlag) {
00079 AuditorTraits<T>::start(value);
00080 }
00081 }
00082
00083 ~ScopedAuditor() {
00084 now();
00085 }
00086
00087 void now() {
00088 if (theNeedToAuditFlag) {
00089 Record* rec = theRecord.getRecord();
00090 rec->add(theProperty, AuditorTraits<T, flags>::end(theValue));
00091 theNeedToAuditFlag = false;
00092 }
00093 }
00094
00095 private:
00096 ScopedAuditor() {}
00097 ScopedAuditor(const ScopedAuditor&) {}
00098
00099 ScopedRecord& theRecord;
00100 const Property& theProperty;
00101 bool theNeedToAuditFlag;
00102 T& theValue;
00103 };
00104
00105 typedef ScopedAuditor<const std::string> StringAuditor;
00106 typedef ScopedAuditor<const int> IntAuditor;
00107 typedef ScopedAuditor<zorba::time::Timer> DurationAuditor;
00108 typedef ScopedAuditor<zorba::time::Timer, 0x1> TimestampAuditor;
00109 typedef ScopedAuditor<zorba::time::Timer, 0x2> MicroDurationAuditor;
00110
00111 template<> struct AuditorTraits<const std::string> {
00112 typedef const std::string value_type;
00113 typedef const std::string audit_type;
00114 static inline void start(value_type& value) {
00115 }
00116 static inline audit_type end(value_type& value) {
00117 return value;
00118 }
00119 };
00120
00121 template<> struct AuditorTraits<String> {
00122 typedef String value_type;
00123 typedef String audit_type;
00124 static inline void start(value_type& value) {
00125 }
00126 static inline audit_type end(value_type& value) {
00127 return value;
00128 }
00129 };
00130
00131 template<> struct AuditorTraits<const int> {
00132 typedef const int value_type;
00133 typedef long long audit_type;
00134 static inline void start(value_type& value) {
00135 }
00136 static inline audit_type end(value_type& value) {
00137 return value;
00138 }
00139 };
00140
00141 template<> struct AuditorTraits<const char*> {
00142 typedef const char* value_type;
00143 typedef const char* audit_type;
00144 static inline void start(value_type& value) {
00145 }
00146 static inline audit_type end(value_type& value) {
00147 return static_cast<audit_type>(value);
00148 }
00149 };
00150
00151 template<> struct AuditorTraits< std::pair<std::streampos, std::istream*> > {
00152 typedef std::pair<std::streampos, std::istream*> value_type;
00153 typedef long long audit_type;
00154 static inline void start(value_type& value) {
00155 value.first = value.second->tellg();
00156 }
00157 static inline audit_type end(value_type& value) {
00158 return value.second->tellg() - value.first;
00159 }
00160 };
00161
00162 template<> struct AuditorTraits< std::pair<std::streampos, std::ostream*> > {
00163 typedef std::pair<std::streampos, std::ostream*> value_type;
00164 typedef long long audit_type;
00165 static inline void start(value_type& value) {
00166 value.first = value.second->tellp();
00167 }
00168 static inline audit_type end(value_type& value) {
00169 return value.second->tellp() - value.first;
00170 }
00171 };
00172
00173 template<> struct AuditorTraits<zorba::time::Timer> {
00174 typedef zorba::time::Timer value_type;
00175 typedef long long audit_type;
00176 static inline void start(value_type& value) {
00177 value.start();
00178 }
00179 static inline audit_type end(value_type& value) {
00180 return static_cast<audit_type>(value.elapsed());
00181 }
00182
00183 };
00184
00185 template<> struct AuditorTraits<zorba::time::Timer, 0x1> {
00186 typedef zorba::time::Timer value_type;
00187 typedef long long audit_type;
00188 static inline void start(value_type& value) {
00189 value.start();
00190 }
00191 static inline audit_type end(value_type& value) {
00192 return static_cast<audit_type>(value.getStart());
00193 }
00194 };
00195
00196 template<> struct AuditorTraits<zorba::time::Timer, 0x2> {
00197 typedef zorba::time::Timer value_type;
00198 typedef long long audit_type;
00199 static inline void start(value_type& value) {
00200 value.start();
00201 }
00202 static inline audit_type end(value_type& value) {
00203 return static_cast<audit_type>(value.elapsed() * 1000);
00204 }
00205
00206 };
00207
00208 }
00209 }
00210 #endif
00211