// @(#)root/proofplayer:$Id$
// Author: Maarten Ballintijn   7/06/2004

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TStatus                                                              //
//                                                                      //
// This class holds the status of an ongoing operation and collects     //
// error messages. It provides a Merge() operation allowing it to       //
// be used in PROOF to monitor status in the slaves.                    //
// No messages indicates success.                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TStatus.h"
#include "Riostream.h"
#include "TClass.h"
#include "TProofDebug.h"

ClassImp(TStatus)

//______________________________________________________________________________
TStatus::TStatus() : fIter(&fMsgs), fExitStatus(-1),
                     fVirtMemMax(-1), fResMemMax(-1),
                     fVirtMaxMst(-1), fResMaxMst(-1)
{
   // Default constructor.

   SetName("PROOF_Status");
   fMsgs.SetOwner(kTRUE);
   fInfoMsgs.SetOwner(kTRUE);
   ResetBit(TStatus::kNotOk);
}

//______________________________________________________________________________
void TStatus::Add(const char *mesg)
{
   // Add an error message.

   fMsgs.Add(new TObjString(mesg));
   SetBit(TStatus::kNotOk);
   Reset();
}

//______________________________________________________________________________
void TStatus::AddInfo(const char *mesg)
{
   // Add an info message.

   fInfoMsgs.Add(new TObjString(mesg));
}

//______________________________________________________________________________
Int_t TStatus::Merge(TCollection *li)
{
   // PROOF Merge() function.

   TIter stats(li);
   PDB(kOutput,1)
      Info("Merge", "start: max virtual memory: %.2f MB \tmax resident memory: %.2f MB ",
                    GetVirtMemMax()/1024., GetResMemMax()/1024.);
   while (TObject *obj = stats()) {
      TStatus *s = dynamic_cast<TStatus*>(obj);
      if (s == 0) continue;

      TObjString *os = 0;
      // Errors
      TIter nxem(&(s->fMsgs));
      while ((os = (TObjString *) nxem())) {
         Add(os->GetName());
      }

      // Infos (no duplications)
      TIter nxwm(&(s->fInfoMsgs));
      while ((os = (TObjString *) nxwm())) {
         if (!fInfoMsgs.FindObject(os->GetName()))
            AddInfo(os->GetName());
      }

      SetMemValues(s->GetVirtMemMax(), s->GetResMemMax());
      // Check the master values (relevantt if merging submaster info)
      SetMemValues(s->GetVirtMemMax(kTRUE), s->GetResMemMax(kTRUE), kTRUE);
      PDB(kOutput,1)
         Info("Merge", "during: max virtual memory: %.2f MB \t"
                       "max resident memory: %.2f MB ",
                       GetVirtMemMax()/1024., GetResMemMax()/1024.);
      if (GetVirtMemMax(kTRUE) > 0) {
         PDB(kOutput,1)
            Info("Merge", "during: max master virtual memory: %.2f MB \t"
                        "max master resident memory: %.2f MB ",
                        GetVirtMemMax(kTRUE)/1024., GetResMemMax(kTRUE)/1024.);
      }
   }

   return fMsgs.GetSize();
}

//______________________________________________________________________________
void TStatus::Print(Option_t * /*option*/) const
{
   // Standard print function.

   Printf("OBJ: %s\t%s\t%s", IsA()->GetName(), GetName(), (IsOk() ? "OK" : "ERROR"));

   TObjString *os = 0;
   // Errors first
   if (fMsgs.GetSize() > 0) {
      Printf("\n   Errors:");
      TIter nxem(&fMsgs);
      while ((os = (TObjString *) nxem()))
         Printf("\t%s",os->GetName());
      Printf(" ");
   }

   // Infos
   if (fInfoMsgs.GetSize() > 0) {
      Printf("\n   Infos:");
      TIter nxem(&fInfoMsgs);
      while ((os = (TObjString *) nxem()))
         Printf("\t%s",os->GetName());
      Printf(" ");
   }

   Printf(" Max worker virtual memory: %.2f MB \tMax worker resident memory: %.2f MB ",
          GetVirtMemMax()/1024., GetResMemMax()/1024.);
   Printf(" Max master virtual memory: %.2f MB \tMax master resident memory: %.2f MB ",
          GetVirtMemMax(kTRUE)/1024., GetResMemMax(kTRUE)/1024.);
}

//______________________________________________________________________________
void TStatus::Reset()
{
   // Reset the iterator on the messages.

   fIter.Reset();
}

//______________________________________________________________________________
const char *TStatus::NextMesg()
{
   // Return the next message or 0.

   TObjString *os = (TObjString *) fIter();
   if (os) return os->GetName();
   return 0;
}

//______________________________________________________________________________
void TStatus::SetMemValues(Long_t vmem, Long_t rmem, Bool_t master)
{
   // Set max memory values

   if (master) {
      if (vmem > 0. && (fVirtMaxMst < 0. || vmem > fVirtMaxMst)) fVirtMaxMst = vmem;
      if (rmem > 0. && (fResMaxMst < 0. || rmem > fResMaxMst)) fResMaxMst = rmem;
   } else {
      if (vmem > 0. && (fVirtMemMax < 0. || vmem > fVirtMemMax)) fVirtMemMax = vmem;
      if (rmem > 0. && (fResMemMax < 0. || rmem > fResMemMax)) fResMemMax = rmem;
   }
}

//______________________________________________________________________________
void TStatus::Streamer(TBuffer &R__b)
{
   // Stream an object of class TStatus.
   if (R__b.IsReading()) {
      UInt_t R__s, R__c;
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
      if (R__v > 4) {
         R__b.ReadClassBuffer(TStatus::Class(), this, R__v, R__s, R__c);
      } else {
         // For version <= 4 masters we need a special streamer
         TNamed::Streamer(R__b);
         std::set<std::string> msgs;
         TClass *cl = TClass::GetClass("set<string>");
         if (cl) {
            UInt_t SS__s = 0, SS__c = 0;
            UInt_t SS__v = cl->GetClassVersion();
            R__b.ReadClassBuffer(cl, &msgs, SS__v, SS__s, SS__c);
         } else {
            Error("Streamer", "no info found for 'set<string>' - skip");
            return;
         }
         std::set<std::string>::const_iterator it;
         for (it = msgs.begin(); it != msgs.end(); it++) {
            fMsgs.Add(new TObjString((*it).c_str()));
         }
         if (R__v > 2) {
            R__b >> fExitStatus;
         }
         if (R__v > 1) {
            R__b >> fVirtMemMax;
            R__b >> fResMemMax;
         }
         if (R__v > 3) {
            R__b >> fVirtMaxMst;
            R__b >> fResMaxMst;
         }
      }
   } else {
      R__b.WriteClassBuffer(TStatus::Class(),this);
   }
}


 TStatus.cxx:1
 TStatus.cxx:2
 TStatus.cxx:3
 TStatus.cxx:4
 TStatus.cxx:5
 TStatus.cxx:6
 TStatus.cxx:7
 TStatus.cxx:8
 TStatus.cxx:9
 TStatus.cxx:10
 TStatus.cxx:11
 TStatus.cxx:12
 TStatus.cxx:13
 TStatus.cxx:14
 TStatus.cxx:15
 TStatus.cxx:16
 TStatus.cxx:17
 TStatus.cxx:18
 TStatus.cxx:19
 TStatus.cxx:20
 TStatus.cxx:21
 TStatus.cxx:22
 TStatus.cxx:23
 TStatus.cxx:24
 TStatus.cxx:25
 TStatus.cxx:26
 TStatus.cxx:27
 TStatus.cxx:28
 TStatus.cxx:29
 TStatus.cxx:30
 TStatus.cxx:31
 TStatus.cxx:32
 TStatus.cxx:33
 TStatus.cxx:34
 TStatus.cxx:35
 TStatus.cxx:36
 TStatus.cxx:37
 TStatus.cxx:38
 TStatus.cxx:39
 TStatus.cxx:40
 TStatus.cxx:41
 TStatus.cxx:42
 TStatus.cxx:43
 TStatus.cxx:44
 TStatus.cxx:45
 TStatus.cxx:46
 TStatus.cxx:47
 TStatus.cxx:48
 TStatus.cxx:49
 TStatus.cxx:50
 TStatus.cxx:51
 TStatus.cxx:52
 TStatus.cxx:53
 TStatus.cxx:54
 TStatus.cxx:55
 TStatus.cxx:56
 TStatus.cxx:57
 TStatus.cxx:58
 TStatus.cxx:59
 TStatus.cxx:60
 TStatus.cxx:61
 TStatus.cxx:62
 TStatus.cxx:63
 TStatus.cxx:64
 TStatus.cxx:65
 TStatus.cxx:66
 TStatus.cxx:67
 TStatus.cxx:68
 TStatus.cxx:69
 TStatus.cxx:70
 TStatus.cxx:71
 TStatus.cxx:72
 TStatus.cxx:73
 TStatus.cxx:74
 TStatus.cxx:75
 TStatus.cxx:76
 TStatus.cxx:77
 TStatus.cxx:78
 TStatus.cxx:79
 TStatus.cxx:80
 TStatus.cxx:81
 TStatus.cxx:82
 TStatus.cxx:83
 TStatus.cxx:84
 TStatus.cxx:85
 TStatus.cxx:86
 TStatus.cxx:87
 TStatus.cxx:88
 TStatus.cxx:89
 TStatus.cxx:90
 TStatus.cxx:91
 TStatus.cxx:92
 TStatus.cxx:93
 TStatus.cxx:94
 TStatus.cxx:95
 TStatus.cxx:96
 TStatus.cxx:97
 TStatus.cxx:98
 TStatus.cxx:99
 TStatus.cxx:100
 TStatus.cxx:101
 TStatus.cxx:102
 TStatus.cxx:103
 TStatus.cxx:104
 TStatus.cxx:105
 TStatus.cxx:106
 TStatus.cxx:107
 TStatus.cxx:108
 TStatus.cxx:109
 TStatus.cxx:110
 TStatus.cxx:111
 TStatus.cxx:112
 TStatus.cxx:113
 TStatus.cxx:114
 TStatus.cxx:115
 TStatus.cxx:116
 TStatus.cxx:117
 TStatus.cxx:118
 TStatus.cxx:119
 TStatus.cxx:120
 TStatus.cxx:121
 TStatus.cxx:122
 TStatus.cxx:123
 TStatus.cxx:124
 TStatus.cxx:125
 TStatus.cxx:126
 TStatus.cxx:127
 TStatus.cxx:128
 TStatus.cxx:129
 TStatus.cxx:130
 TStatus.cxx:131
 TStatus.cxx:132
 TStatus.cxx:133
 TStatus.cxx:134
 TStatus.cxx:135
 TStatus.cxx:136
 TStatus.cxx:137
 TStatus.cxx:138
 TStatus.cxx:139
 TStatus.cxx:140
 TStatus.cxx:141
 TStatus.cxx:142
 TStatus.cxx:143
 TStatus.cxx:144
 TStatus.cxx:145
 TStatus.cxx:146
 TStatus.cxx:147
 TStatus.cxx:148
 TStatus.cxx:149
 TStatus.cxx:150
 TStatus.cxx:151
 TStatus.cxx:152
 TStatus.cxx:153
 TStatus.cxx:154
 TStatus.cxx:155
 TStatus.cxx:156
 TStatus.cxx:157
 TStatus.cxx:158
 TStatus.cxx:159
 TStatus.cxx:160
 TStatus.cxx:161
 TStatus.cxx:162
 TStatus.cxx:163
 TStatus.cxx:164
 TStatus.cxx:165
 TStatus.cxx:166
 TStatus.cxx:167
 TStatus.cxx:168
 TStatus.cxx:169
 TStatus.cxx:170
 TStatus.cxx:171
 TStatus.cxx:172
 TStatus.cxx:173
 TStatus.cxx:174
 TStatus.cxx:175
 TStatus.cxx:176
 TStatus.cxx:177
 TStatus.cxx:178
 TStatus.cxx:179
 TStatus.cxx:180
 TStatus.cxx:181
 TStatus.cxx:182
 TStatus.cxx:183
 TStatus.cxx:184
 TStatus.cxx:185
 TStatus.cxx:186
 TStatus.cxx:187
 TStatus.cxx:188
 TStatus.cxx:189
 TStatus.cxx:190
 TStatus.cxx:191
 TStatus.cxx:192
 TStatus.cxx:193
 TStatus.cxx:194
 TStatus.cxx:195
 TStatus.cxx:196
 TStatus.cxx:197
 TStatus.cxx:198
 TStatus.cxx:199
 TStatus.cxx:200
 TStatus.cxx:201
 TStatus.cxx:202
 TStatus.cxx:203
 TStatus.cxx:204
 TStatus.cxx:205
 TStatus.cxx:206
 TStatus.cxx:207
 TStatus.cxx:208
 TStatus.cxx:209
 TStatus.cxx:210
 TStatus.cxx:211
 TStatus.cxx:212
 TStatus.cxx:213