audit_scoped.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2008 The FLWOR Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus