CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/FWCore/MessageLogger/src/ELmap.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 //
00003 // ELmap.cc
00004 //
00005 // Change History:
00006 //   99-06-10   mf      correction in sense of comparison between timespan
00007 //                      and diff (now, lastTime)
00008 //              mf      ELcountTRACE made available
00009 //   99-06-11   mf      Corrected logic for suppressing output when n > limit
00010 //                      but not but a factor of 2**K
00011 //   06-05-16   mf      Added code to establish interval and to use skipped
00012 //                      and interval when determinine in add() whehter to react
00013 //   06-05-19   wmtan   Bug fix.  skipped = 0, not skipped == 0.
00014 //                      and interval when determinine in add() whehter to react
00015 //   09-04-15   wmtan   Use smart pointers with new, not bare pointers
00016 //
00017 // ----------------------------------------------------------------------
00018 
00019 
00020 #include "FWCore/MessageLogger/interface/ELmap.h"
00021 
00022 // Possible traces
00023 //#include <iostream>
00024 //#define ELcountTRACE
00025 // #define ELmapDumpTRACE
00026 
00027 
00028 namespace edm
00029 {
00030 
00031 
00032 // ----------------------------------------------------------------------
00033 // LimitAndTimespan:
00034 // ----------------------------------------------------------------------
00035 
00036 LimitAndTimespan::LimitAndTimespan( int lim, int ts, int ivl )
00037 : limit   ( lim )
00038 , timespan( ts )
00039 , interval( ivl )
00040 { }
00041 
00042 
00043 // ----------------------------------------------------------------------
00044 // CountAndLimit:
00045 // ----------------------------------------------------------------------
00046 
00047 CountAndLimit::CountAndLimit( int lim, int ts, int ivl )
00048 : n         ( 0 )
00049 , aggregateN( 0 )
00050 , lastTime  ( time(0) )
00051 , limit     ( lim )
00052 , timespan  ( ts  )
00053 , interval  ( ivl )
00054 , skipped   ( ivl-1 )  // So that the FIRST of the prescaled messages emerges
00055 { }
00056 
00057 
00058 bool  CountAndLimit::add()  {
00059 
00060   time_t  now = time(0);
00061 
00062 #ifdef ELcountTRACE
00063   std::cerr << "&&&--- CountAndLimit::add \n";
00064   std::cerr << "&&&    Time now  is " << now << "\n";
00065   std::cerr << "&&&    Last time is " << lastTime << "\n";
00066   std::cerr << "&&&    timespan  is " << timespan << "\n";
00067   std::cerr << "&&&    difftime  is " << difftime( now, lastTime ) << "\n"
00068                                 << std::flush;
00069 #endif
00070 
00071   // Has it been so long that we should restart counting toward the limit?
00072   if ( (timespan >= 0)
00073             &&
00074         (difftime(now, lastTime) >= timespan) )  {
00075      n = 0;
00076      if ( interval > 0 ) {
00077        skipped = interval - 1; // So this message will be reacted to
00078      } else {
00079        skipped = 0;
00080      }
00081   }
00082 
00083   lastTime = now;
00084 
00085   ++n;  
00086   ++aggregateN;
00087   ++skipped;  
00088 
00089 #ifdef ELcountTRACE
00090   std::cerr << "&&&       n is " << n << "-- limit is    " << limit    << "\n";
00091   std::cerr << "&&& skipped is " << skipped 
00092                                       << "-- interval is " << interval << "\n";
00093 #endif
00094   
00095   if (skipped < interval) return false;
00096 
00097   if ( limit == 0 ) return false;        // Zero limit - never react to this
00098   if ( (limit < 0)  || ( n <= limit )) {
00099     skipped = 0;
00100     return true;
00101   }
00102   
00103   // Now we are over the limit - have we exceeded limit by 2^N * limit?
00104   long  diff = n - limit;
00105   long  r = diff/limit;
00106   if ( r*limit != diff ) { // Not a multiple of limit - don't react
00107     return false;
00108   }  
00109   if ( r == 1 )   {     // Exactly twice limit - react
00110     skipped = 0;
00111     return true;
00112   }
00113 
00114   while ( r > 1 )  {
00115     if ( (r & 1) != 0 )  return false;  // Not 2**n times limit - don't react
00116     r >>= 1;
00117   }
00118   // If you never get an odd number till one, r is 2**n so react
00119   
00120   skipped = 0;
00121   return true;
00122 
00123 }  // add()
00124 
00125 
00126 // ----------------------------------------------------------------------
00127 // StatsCount:
00128 // ----------------------------------------------------------------------
00129 
00130 StatsCount::StatsCount()
00131 : n          ( 0 )
00132 , aggregateN ( 0 )
00133 , ignoredFlag( false )
00134 , context1   ( "" )
00135 , context2   ( "" )
00136 , contextLast( "" )
00137 { }
00138 
00139 
00140 void  StatsCount::add( const ELstring & context, bool reactedTo )  {
00141 
00142   ++n;  ++aggregateN;
00143 
00144   ( (1 == n) ? context1
00145   : (2 == n) ? context2
00146   :            contextLast
00147   )                        = ELstring( context, 0, 16 );
00148 
00149   if ( ! reactedTo )
00150     ignoredFlag = true;
00151 
00152 }  // add()
00153 
00154 
00155 // ----------------------------------------------------------------------
00156 
00157 #ifdef ELmapDumpTRACE
00158 // ----------------------------------------------------------------------
00159 // Global Dump methods (useful for debugging)
00160 // ----------------------------------------------------------------------
00161 
00162 #include <sstream>
00163 #include <string.h>
00164 
00165 boost::shared_array<char> ELmapDump ( ELmap_limits m )  {
00166 
00167   std::ostringstream s;
00168   s << "**** ELmap_limits Dump **** \n";
00169 
00170   ELmap_limits::const_iterator i;
00171   for ( i = m.begin();  i != m.end();  ++i )  {
00172     LimitAndTimespan lt = (*i).second;
00173     s << "     " << (*i).first << ":  " << lt.limit << ", " <<
00174                 lt.timespan << "\n";
00175   }
00176   s << "--------------------------------------------\n";
00177 
00178   boost::shared_array<char> dump(new char[s.str().size()+1]);
00179   strcpy( dump.get(), s.str().c_str() );
00180 
00181   return dump;
00182 
00183 }
00184 #endif
00185 
00186 } // end of namespace edm  */