#include "AliCodeTimer.h"
#include <TMap.h>
#include <TObjString.h>
#include <TStopwatch.h>
#include <Riostream.h>
using std::endl;
using std::cout;
ClassImp(AliCodeTimer)
ClassImp(AliCodeTimer::AliPair)
AliCodeTimer* AliCodeTimer::fgInstance(0x0);
void
AliCodeTimer::AliPair::Print(Option_t* opt) const
{
cout << opt << Form("%s R:%.4fs C:%.4fs (%d slices)",
Name().Data(),Timer()->RealTime(),
Timer()->CpuTime(),Timer()->Counter()-1) << endl;
}
AliCodeTimer::AliCodeTimer() : TObject(), fTimers(new TMap)
{
fTimers->SetOwner(kTRUE);
}
AliCodeTimer::~AliCodeTimer()
{
Reset();
delete fTimers;
}
AliCodeTimer*
AliCodeTimer::Instance()
{
if (!fgInstance) fgInstance = new AliCodeTimer;
return fgInstance;
}
void AliCodeTimer::Continue(const char* classname, const char* methodname,
const char* message)
{
TStopwatch* t = Stopwatch(classname,methodname,message);
if (t)
{
t->Continue();
}
else
{
AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
}
}
Double_t AliCodeTimer::CpuTime(const char* classname,
const char* methodname,
const char* message) const
{
TStopwatch* t = Stopwatch(classname,methodname,message);
if (t)
{
return t->CpuTime();
}
else
{
return 0;
}
}
TMap*
AliCodeTimer::MethodMap(const char* classname) const
{
return static_cast<TMap*>(fTimers->GetValue(classname));
}
TObjArray*
AliCodeTimer::MessageArray(const char* classname, const char* methodname) const
{
TMap* m = MethodMap(classname);
if ( m )
{
return static_cast<TObjArray*>(m->GetValue(methodname));
}
return 0;
}
void AliCodeTimer::PrintMethod(const char* classname, const char* methodname) const
{
TObjArray* messages = MessageArray(classname,methodname);
messages->Sort();
cout << " " << methodname << " ";
if ( messages->GetLast() == 0 )
{
AliPair* p = static_cast<AliPair*>(messages->First());
p->Print();
}
else
{
cout << endl;
TIter next(messages);
AliPair* p;
while ( ( p = static_cast<AliPair*>(next()) ) )
{
p->Print(" ");
}
}
}
void AliCodeTimer::PrintClass(const char* classname) const
{
TMap* methods = MethodMap(classname);
TIter next(methods);
TObjString* methodname;
TObjArray methodNameArray;
while ( ( methodname = static_cast<TObjString*>(next()) ) )
{
methodNameArray.Add(methodname);
}
cout << classname << endl;
methodNameArray.Sort();
TIter mnext(&methodNameArray);
while ( ( methodname = static_cast<TObjString*>(mnext()) ) )
{
PrintMethod(classname,methodname->String().Data());
}
}
void AliCodeTimer::Print(Option_t* ) const
{
TIter next(fTimers);
TObjString* classname;
TObjArray classNameArray;
while ( ( classname = static_cast<TObjString*>(next()) ) )
{
classNameArray.Add(classname);
}
classNameArray.Sort();
TIter cnext(&classNameArray);
while ( ( classname = static_cast<TObjString*>(cnext()) ) )
{
PrintClass(classname->String().Data());
}
}
Double_t
AliCodeTimer::RealTime(const char* classname, const char* methodname,
const char* message) const
{
TStopwatch* t = Stopwatch(classname,methodname,message);
if (t)
{
return t->RealTime();
}
else
{
return 0;
}
}
void
AliCodeTimer::Reset()
{
TIter next(fTimers);
TObjString* classname;
while ( ( classname = static_cast<TObjString*>(next()) ) )
{
TMap* m = static_cast<TMap*>(fTimers->GetValue(classname->String().Data()));
m->DeleteAll();
}
fTimers->DeleteAll();
}
void
AliCodeTimer::Start(const char* classname, const char* methodname,
const char* message)
{
TStopwatch* t = Stopwatch(classname,methodname,message);
if (!t)
{
TMap* m = MethodMap(classname);
if (!m)
{
m = new TMap;
m->SetOwner(kTRUE);
fTimers->Add(new TObjString(classname),m);
}
TObjArray* messages = MessageArray(classname,methodname);
if (!messages)
{
messages = new TObjArray;
messages->SetOwner(kTRUE);
m->Add(new TObjString(methodname),messages);
}
t = new TStopwatch;
t->Start(kTRUE);
t->Stop();
messages->Add(new AliPair(new TObjString(message),t));
}
t->Start(kFALSE);
}
void
AliCodeTimer::Stop(const char* classname, const char* methodname,
const char* message)
{
TStopwatch* t = Stopwatch(classname,methodname,message);
if (!t)
{
AliError(Form("No timer for %s/%s/%s",classname,methodname,message));
}
else
{
t->Stop();
}
}
TStopwatch*
AliCodeTimer::Stopwatch(const char* classname, const char* methodname,
const char* message) const
{
TObjArray* a = MessageArray(classname,methodname);
if ( a )
{
if (message)
{
TIter next(a);
AliPair* p;
while ( ( p = static_cast<AliPair*>(next()) ) )
{
TString s = p->Name();
if ( s == TString(message) )
{
return p->Timer();
}
}
}
else
{
return static_cast<TStopwatch*>(a->First());
}
}
return 0x0;
}