CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/Utilities/StorageFactory/src/StorageAccount.cc

Go to the documentation of this file.
00001 #include "Utilities/StorageFactory/interface/StorageAccount.h"
00002 #include <boost/thread/mutex.hpp>
00003 #include <sstream>
00004 #include <unistd.h>
00005 
00006 boost::mutex                 s_mutex;
00007 StorageAccount::StorageStats s_stats;
00008 
00009 static double timeRealNanoSecs (void) {
00010 #if _POSIX_TIMERS > 0
00011   struct timespec tm;
00012   if (clock_gettime(CLOCK_REALTIME, &tm) == 0)
00013     return tm.tv_sec * 1e9 + tm.tv_nsec;
00014 #else
00015   struct timeval tm;
00016   if (gettimeofday(&tm, 0) == 0)
00017     return tm.tv_sec * 1e9 + tm.tv_usec * 1e3;
00018 #endif
00019   return 0;
00020 }
00021 
00022 static std::string i2str(int i) {
00023   std::ostringstream t;
00024   t << i;
00025   return t.str();
00026 }
00027 
00028 static std::string d2str(double d) {
00029   std::ostringstream t;
00030   t << d;
00031   return t.str();
00032 }
00033 
00034 std::string
00035 StorageAccount::summaryText (bool banner /*=false*/) {
00036   bool first = true;
00037   std::ostringstream os;
00038   if (banner)
00039     os << "stats: class/operation/attempts/successes/amount/time-total/time-min/time-max\n";
00040   for (StorageStats::iterator i = s_stats.begin (); i != s_stats.end(); ++i)
00041     for (OperationStats::iterator j = i->second->begin (); j != i->second->end (); ++j, first = false)
00042       os << (first ? "" : "; ")
00043          << i->first << '/'
00044          << j->first << '='
00045          << j->second.attempts << '/'
00046          << j->second.successes << '/'
00047          << (j->second.amount / 1024 / 1024) << "MB/"
00048          << (j->second.timeTotal / 1000 / 1000) << "ms/"
00049          << (j->second.timeMin / 1000 / 1000) << "ms/"
00050          << (j->second.timeMax / 1000 / 1000) << "ms";
00051  
00052   return os.str ();
00053 }
00054 
00055 std::string
00056 StorageAccount::summaryXML (void) {
00057   std::ostringstream os;
00058   os << "<storage-timing-summary>\n";
00059   for (StorageStats::iterator i = s_stats.begin (); i != s_stats.end(); ++i)
00060     for (OperationStats::iterator j = i->second->begin (); j != i->second->end (); ++j)
00061       os << " <counter-value subsystem='" << i->first
00062          << "' counter-name='" << j->first
00063          << "' num-operations='" << j->second.attempts
00064          << "' num-successful-operations='" << j->second.successes
00065          << "' total-megabytes='" << (j->second.amount / 1024 / 1024)
00066          << "' total-msecs='" << (j->second.timeTotal / 1000 / 1000)
00067          << "' min-msecs='" << (j->second.timeMin / 1000 / 1000)
00068          << "' max-msecs='" << (j->second.timeMax / 1000 / 1000) << "'/>\n";
00069   os << "</storage-timing-summary>";
00070   return os.str ();
00071 }
00072 
00073 void
00074 StorageAccount::fillSummary(std::map<std::string, std::string>& summary) {
00075   int const oneM = 1000 * 1000;
00076   int const oneMeg = 1024 * 1024;
00077   for (StorageStats::iterator i = s_stats.begin (); i != s_stats.end(); ++i) {
00078     for (OperationStats::iterator j = i->second->begin(); j != i->second->end(); ++j) {
00079       std::ostringstream os;
00080       os << "Timing-" << i->first << "-" << j->first << "-";
00081       summary.insert(std::make_pair(os.str() + "numOperations", i2str(j->second.attempts)));
00082       summary.insert(std::make_pair(os.str() + "numSuccessfulOperations", i2str(j->second.successes)));
00083       summary.insert(std::make_pair(os.str() + "totalMegabytes", d2str(j->second.amount / oneMeg)));
00084       summary.insert(std::make_pair(os.str() + "totalMsecs", d2str(j->second.timeTotal / oneM)));
00085       summary.insert(std::make_pair(os.str() + "minMsecs", d2str(j->second.timeMin / oneM)));
00086       summary.insert(std::make_pair(os.str() + "maxMsecs", d2str(j->second.timeMax / oneM)));
00087     }
00088   }
00089 }
00090 
00091 const StorageAccount::StorageStats&
00092 StorageAccount::summary (void)
00093 { return s_stats; }
00094 
00095 StorageAccount::Counter&
00096 StorageAccount::counter (const std::string &storageClass, const std::string &operation) {
00097   boost::mutex::scoped_lock lock (s_mutex);
00098   boost::shared_ptr<OperationStats> &opstats = s_stats [storageClass];
00099   if (!opstats) opstats.reset(new OperationStats);
00100 
00101   OperationStats::iterator pos = opstats->find (operation);
00102   if (pos == opstats->end ()) {
00103     Counter x = { 0, 0, 0, 0, 0, 0, 0 };
00104     pos = opstats->insert (OperationStats::value_type (operation, x)).first;
00105   }
00106 
00107   return pos->second;
00108 }
00109 
00110 StorageAccount::Stamp::Stamp (Counter &counter)
00111   : m_counter (counter),
00112     m_start (timeRealNanoSecs ())
00113 {
00114   boost::mutex::scoped_lock lock (s_mutex);
00115   m_counter.attempts++;
00116 }
00117 
00118 void
00119 StorageAccount::Stamp::tick (double amount, int64_t count) const
00120 {
00121   boost::mutex::scoped_lock lock (s_mutex);
00122   double elapsed = timeRealNanoSecs () - m_start;
00123   m_counter.successes++;
00124 
00125   m_counter.vector_count += count;
00126   m_counter.vector_square += count*count;
00127   m_counter.amount += amount;
00128   m_counter.amount_square += amount*amount;
00129 
00130   m_counter.timeTotal += elapsed;
00131   if (elapsed < m_counter.timeMin || m_counter.successes == 1)
00132     m_counter.timeMin = elapsed;
00133   if (elapsed > m_counter.timeMax)
00134     m_counter.timeMax = elapsed;
00135 }