1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ZORBA_AUDIT_SCOPED_H 18 #define ZORBA_AUDIT_SCOPED_H 19 20 #include <iostream> 21 #include <sstream> 22 #include <cassert> 23 #include <zorba/audit.h> 24 #include <zorba/util/timer.h> 25 26 namespace zorba { 27 namespace audit { 28 29 class ZORBA_DLL_PUBLIC ScopedRecord { 30 public: ScopedRecord(Event * event)31 ScopedRecord(Event* event) 32 : theEvent(event ? event : Event::get()), 33 theRecord(0) { 34 assert(theEvent); 35 } 36 ~ScopedRecord()37 ~ScopedRecord() { 38 if (theRecord) { 39 theEvent->submitRecord(theRecord); 40 theRecord = 0; 41 } 42 } 43 getEvent()44 Event* getEvent() { 45 return theEvent; 46 } 47 getRecord()48 Record* getRecord() { 49 if (! theRecord) { 50 theRecord = theEvent->createRecord(); 51 } 52 return theRecord; 53 } 54 55 private: 56 Event* theEvent; 57 Record* theRecord; 58 }; 59 60 template <class T, unsigned char flags = 0> struct AuditorTraits { 61 }; 62 63 template <class T, unsigned char flags = 0> class ScopedAuditor { 64 public: ScopedAuditor(ScopedRecord & record,const Property & prop,T & value)65 ScopedAuditor(ScopedRecord& record, const Property& prop, T& value) 66 : theRecord(record), theProperty(prop), theValue(value) { 67 theNeedToAuditFlag = record.getEvent()->audit(prop); 68 if (theNeedToAuditFlag) { 69 AuditorTraits<T, flags>::start(value); 70 } 71 } 72 ScopedAuditor(ScopedRecord & record,const String & prop_name,T & value)73 ScopedAuditor(ScopedRecord& record, const String& prop_name, T& value) 74 : theRecord(record), 75 theProperty(*record.getEvent()->getDynamicProperty(prop_name)), 76 theValue(value) { 77 theNeedToAuditFlag = record.getEvent()->audit(prop_name); 78 if (theNeedToAuditFlag) { 79 AuditorTraits<T>::start(value); 80 } 81 } 82 ~ScopedAuditor()83 ~ScopedAuditor() { 84 now(); 85 } 86 now()87 void now() { 88 if (theNeedToAuditFlag) { 89 Record* rec = theRecord.getRecord(); 90 rec->add(theProperty, AuditorTraits<T, flags>::end(theValue)); 91 theNeedToAuditFlag = false; 92 } 93 } 94 95 private: ScopedAuditor()96 ScopedAuditor() {} ScopedAuditor(const ScopedAuditor &)97 ScopedAuditor(const ScopedAuditor&) {} 98 99 ScopedRecord& theRecord; 100 const Property& theProperty; 101 bool theNeedToAuditFlag; 102 T& theValue; 103 }; 104 105 typedef ScopedAuditor<const std::string> StringAuditor; 106 typedef ScopedAuditor<const int> IntAuditor; 107 typedef ScopedAuditor<zorba::time::Timer> DurationAuditor; 108 typedef ScopedAuditor<zorba::time::Timer, 0x1> TimestampAuditor; 109 typedef ScopedAuditor<zorba::time::Timer, 0x2> MicroDurationAuditor; 110 111 template<> struct AuditorTraits<const std::string> { 112 typedef const std::string value_type; 113 typedef const std::string audit_type; 114 static inline void start(value_type& value) { 115 } 116 static inline audit_type end(value_type& value) { 117 return value; 118 } 119 }; 120 121 template<> struct AuditorTraits<String> { 122 typedef String value_type; 123 typedef String audit_type; 124 static inline void start(value_type& value) { 125 } 126 static inline audit_type end(value_type& value) { 127 return value; 128 } 129 }; 130 131 template<> struct AuditorTraits<const int> { 132 typedef const int value_type; 133 typedef long long audit_type; 134 static inline void start(value_type& value) { 135 } 136 static inline audit_type end(value_type& value) { 137 return value; 138 } 139 }; 140 141 template<> struct AuditorTraits<const char*> { 142 typedef const char* value_type; 143 typedef const char* audit_type; 144 static inline void start(value_type& value) { 145 } 146 static inline audit_type end(value_type& value) { 147 return static_cast<audit_type>(value); 148 } 149 }; 150 151 template<> struct AuditorTraits< std::pair<std::streampos, std::istream*> > { 152 typedef std::pair<std::streampos, std::istream*> value_type; 153 typedef long long audit_type; 154 static inline void start(value_type& value) { 155 value.first = value.second->tellg(); 156 } 157 static inline audit_type end(value_type& value) { 158 return value.second->tellg() - value.first; 159 } 160 }; 161 162 template<> struct AuditorTraits< std::pair<std::streampos, std::ostream*> > { 163 typedef std::pair<std::streampos, std::ostream*> value_type; 164 typedef long long audit_type; 165 static inline void start(value_type& value) { 166 value.first = value.second->tellp(); 167 } 168 static inline audit_type end(value_type& value) { 169 return value.second->tellp() - value.first; 170 } 171 }; 172 173 template<> struct AuditorTraits<zorba::time::Timer> { 174 typedef zorba::time::Timer value_type; 175 typedef long long audit_type; 176 static inline void start(value_type& value) { 177 value.start(); 178 } 179 static inline audit_type end(value_type& value) { 180 return static_cast<audit_type>(value.elapsed()); 181 } 182 183 }; 184 185 template<> struct AuditorTraits<zorba::time::Timer, 0x1> { 186 typedef zorba::time::Timer value_type; 187 typedef long long audit_type; 188 static inline void start(value_type& value) { 189 value.start(); 190 } 191 static inline audit_type end(value_type& value) { 192 return static_cast<audit_type>(value.getStart()); 193 } 194 }; 195 196 template<> struct AuditorTraits<zorba::time::Timer, 0x2> { 197 typedef zorba::time::Timer value_type; 198 typedef long long audit_type; 199 static inline void start(value_type& value) { 200 value.start(); 201 } 202 static inline audit_type end(value_type& value) { 203 return static_cast<audit_type>(value.elapsed() * 1000); 204 } 205 206 }; 207 208 } 209 } 210 #endif 211 /* vim:set et sw=2 ts=2: */ 212