ROOT logo

From $ROOTSYS/tutorials/net/parallelMergeServer.C

#include "TMessage.h"
#include "TBenchmark.h"
#include "TSocket.h"
#include "TH2.h"
#include "TTree.h"
#include "TMemFile.h"
#include "TRandom.h"
#include "TError.h"
#include "TFileMerger.h"

#include "TServerSocket.h"
#include "TPad.h"
#include "TCanvas.h"
#include "TMonitor.h"

#include "TFileCacheWrite.h"
#include "TSystem.h"
#include "THashTable.h"

#include "TMath.h"
#include "TTimeStamp.h"

const int kIncremental = 0;
const int kReplaceImmediately = 1;
const int kReplaceWait = 2;

#include "TKey.h"
static Bool_t R__NeedInitialMerge(TDirectory *dir)
{

   if (dir==0) return kFALSE;
   
   TIter nextkey(dir->GetListOfKeys());
   TKey *key;
   while( (key = (TKey*)nextkey()) ) {
      TClass *cl = TClass::GetClass(key->GetClassName());
      if (cl->InheritsFrom(TDirectory::Class())) {
         TDirectory *subdir = (TDirectory *)dir->GetList()->FindObject(key->GetName());
         if (!subdir) {
            subdir = (TDirectory *)key->ReadObj();
         }
         if (R__NeedInitialMerge(subdir)) {
            return kTRUE;
         }
      } else {
         if (0 != cl->GetResetAfterMerge()) {
            return kTRUE;
         }
      }
   }
   return kFALSE;
}

static void R__DeleteObject(TDirectory *dir, Bool_t withReset)
{
   if (dir==0) return;
   
   TIter nextkey(dir->GetListOfKeys());
   TKey *key;
   while( (key = (TKey*)nextkey()) ) {
      TClass *cl = TClass::GetClass(key->GetClassName());
      if (cl->InheritsFrom(TDirectory::Class())) {
         TDirectory *subdir = (TDirectory *)dir->GetList()->FindObject(key->GetName());
         if (!subdir) {
            subdir = (TDirectory *)key->ReadObj();
         }
         R__DeleteObject(subdir,withReset);
      } else {
         Bool_t todelete = kFALSE;
         if (withReset) {
            todelete = (0 != cl->GetResetAfterMerge());
         } else {
            todelete = (0 ==  cl->GetResetAfterMerge());
         }
         if (todelete) {
            key->Delete();
            dir->GetListOfKeys()->Remove(key);
            delete key;
         }
      }
   }
}

static void R__MigrateKey(TDirectory *destination, TDirectory *source)
{
   if (destination==0 || source==0) return;
   
   TIter nextkey(source->GetListOfKeys());
   TKey *key;
   while( (key = (TKey*)nextkey()) ) {
      TClass *cl = TClass::GetClass(key->GetClassName());
      if (cl->InheritsFrom(TDirectory::Class())) {
         TDirectory *source_subdir = (TDirectory *)source->GetList()->FindObject(key->GetName());
         if (!source_subdir) {
            source_subdir = (TDirectory *)key->ReadObj();
         }
         TDirectory *destination_subdir = destination->GetDirectory(key->GetName());
         if (!destination_subdir) {
            destination_subdir = destination->mkdir(key->GetName());
         }
         R__MigrateKey(destination,source);
      } else {
         TKey *oldkey = destination->GetKey(key->GetName());
         if (oldkey) {
            oldkey->Delete();
            delete oldkey;
         }
         TKey *newkey = new TKey(destination,*key,0 /* pidoffset */); // a priori the file are from the same client ..
         destination->GetFile()->SumBuffer(newkey->GetObjlen());
         newkey->WriteFile(0);
         if (destination->GetFile()->TestBit(TFile::kWriteError)) {
            return;
         }         
      }      
   }
   destination->SaveSelf();
}

struct ClientInfo
{
   TFile      *fFile;      // This object does *not* own the file, it will be own by the owner of the ClientInfo.
   TString    fLocalName;
   UInt_t     fContactsCount;
   TTimeStamp fLastContact;
   Double_t   fTimeSincePrevContact;
   
   ClientInfo() : fFile(0), fLocalName(), fContactsCount(0), fTimeSincePrevContact(0) {}
   ClientInfo(const char *filename, UInt_t clientId) : fFile(0), fContactsCount(0), fTimeSincePrevContact(0) {
      fLocalName.Form("%s-%d-%d",filename,clientId,gSystem->GetPid());
   }
   
   void Set(TFile *file)
   {
      // Register the new file as coming from this client.
      if (file != fFile) {
         // We need to keep any of the keys from the previous file that 
         // are not in the new file.
         if (fFile) {
            R__MigrateKey(fFile,file); 
            // delete the previous memory file (if any)
            delete file;
         } else {
            fFile = file;
         }
      }
      TTimeStamp now;
      fTimeSincePrevContact = now.AsDouble() - fLastContact.AsDouble();
      fLastContact = now;
      ++fContactsCount;
   }
};

struct ParallelFileMerger : public TObject
{
   typedef std::vector<ClientInfo> ClientColl_t;

   TString       fFilename;
   TBits         fClientsContact;       //
   UInt_t        fNClientsContact;      //
   ClientColl_t  fClients;
   TTimeStamp    fLastMerge;
   TFileMerger   fMerger;
   
   ParallelFileMerger(const char *filename, Bool_t writeCache = kFALSE) : fFilename(filename), fNClientsContact(0), fMerger(kFALSE,kTRUE)
   {
      // Default constructor.

      fMerger.SetPrintLevel(0);
      fMerger.OutputFile(filename,"RECREATE");
      if (writeCache) new TFileCacheWrite(fMerger.GetOutputFile(),32*1024*1024);
   }

   ~ParallelFileMerger() 
   {
      // Destructor.
   
      for(unsigned int f = 0 ; f < fClients.size(); ++f) {
         fprintf(stderr,"Client %d reported %u times\n",f,fClients[f].fContactsCount);
      }
      for( ClientColl_t::iterator iter = fClients.begin();
          iter != fClients.end();
          ++iter) 
      {
         delete iter->fFile;
      }
   }
   
   ULong_t  Hash() const 
   {
      // Return hash value for this object.
      return fFilename.Hash(); 
   }

   const char *GetName() const
   {
      // Return the name of the object which is the name of the output file.
      return fFilename;
   }
   
   Bool_t InitialMerge(TFile *input)
   {
      // Initial merge of the input to copy the resetable object (TTree) into the output
      // and remove them from the input file.
      
      fMerger.AddFile(input);
      
      Bool_t result = fMerger.PartialMerge(TFileMerger::kIncremental | TFileMerger::kResetable);
      
      R__DeleteObject(input,kTRUE);
      return result;
   }

   Bool_t Merge()
   {
      // Merge the current inputs into the output file.
      
      R__DeleteObject(fMerger.GetOutputFile(),kFALSE); // Remove object that can *not* be incrementally merge and will *not* be reset by the client code.
      for(unsigned int f = 0 ; f < fClients.size(); ++f) {
         fMerger.AddFile(fClients[f].fFile);
      }
      Bool_t result = fMerger.PartialMerge(TFileMerger::kAllIncremental);
      
      // Remove any 'resetable' object (like TTree) from the input file so that they will not 
      // be re-merged.  Keep only the object that always need to be re-merged (Histograms).
      for(unsigned int f = 0 ; f < fClients.size(); ++f) {
         if (fClients[f].fFile) {
            R__DeleteObject(fClients[f].fFile,kTRUE);
         } else {
            // We back up the file (probably due to memory constraint)
            TFile *file = TFile::Open(fClients[f].fLocalName,"UPDATE");
            R__DeleteObject(file,kTRUE); // Remove object that can be incrementally merge and will be reset by the client code.
            file->Write();
            delete file;
         }
      }
      fLastMerge = TTimeStamp();
      fNClientsContact = 0;
      fClientsContact.Clear();
      
      return result;
   }
   
   Bool_t NeedFinalMerge() 
   {
      // Return true, if there is any data that has not been merged.

      return fClientsContact.CountBits() > 0;
   }
   
   Bool_t NeedMerge(Float_t clientThreshold) 
   {
      // Return true, if enough client have reported
      
      if (fClients.size()==0) {
         return kFALSE;
      }

      // Calculate average and rms of the time between the last 2 contacts.
      Double_t sum = 0;
      Double_t sum2 = 0;
      for(unsigned int c = 0 ; c < fClients.size(); ++c) {
         sum += fClients[c].fTimeSincePrevContact;
         sum2 += fClients[c].fTimeSincePrevContact*fClients[c].fTimeSincePrevContact;
      }
      Double_t avg = sum / fClients.size();
      Double_t sigma = sum2 ? TMath::Sqrt( sum2 / fClients.size() - avg*avg) : 0;
      Double_t target = avg + 2*sigma;
      TTimeStamp now;
      if ( (now.AsDouble() - fLastMerge.AsDouble()) > target) {
//         Float_t cut = clientThreshold * fClients.size();
//         if (!(fClientsContact.CountBits() > cut )) {
//            for(unsigned int c = 0 ; c < fClients.size(); ++c) {
//               fprintf(stderr,"%d:%f ",c,fClients[c].fTimeSincePrevContact);
//            }
//            fprintf(stderr,"merge:%f avg:%f target:%f\n",(now.AsDouble() - fLastMerge.AsDouble()),avg,target);
//         }
         return kTRUE;
      }
      Float_t cut = clientThreshold * fClients.size();
      return fClientsContact.CountBits() > cut  || fNClientsContact > 2*cut;
   }
   
   void RegisterClient(UInt_t clientId, TFile *file)
   {
      // Register that a client has sent a file.

      ++fNClientsContact;
      fClientsContact.SetBitNumber(clientId);
      if (fClients.size() < clientId+1) {
         fClients.push_back( ClientInfo(fFilename,clientId) );
      }
      fClients[clientId].Set(file);
   }
   
   ClassDef(ParallelFileMerger,0);
};
                              
void parallelMergeServer(bool cache = false) {
   // This script shows how to make a simple iterative server that
   // can accept connections while handling currently open connections.
   // Compare this script to hserv.C that blocks on accept.
   // In this script a server socket is created and added to a monitor.
   // A monitor object is used to monitor connection requests on
   // the server socket. After accepting the connection
   // the new socket is added to the monitor and immediately ready
   // for use. Once two connections are accepted the server socket
   // is removed from the monitor and closed. The monitor continues
   // monitoring the sockets.
   //
   // To run this demo do the following:
   //   - Open three windows
   //   - Start ROOT in all three windows
   //   - Execute in the first window: .x hserv2.C
   //   - Execute in the second and third windows: .x hclient.C
   //Author: Fons Rademakers
   
   // Open a server socket looking for connections on a named service or
   // on a specified port.
   //TServerSocket *ss = new TServerSocket("rootserv", kTRUE);
   TServerSocket *ss = new TServerSocket(1095, kTRUE, 100);
   if (!ss->IsValid()) {
      return;
   }

   TMonitor *mon = new TMonitor;
   
   mon->Add(ss);

   UInt_t clientCount = 0;
   UInt_t clientIndex = 0;
   
   THashTable mergers;
 
   enum StatusKind {
      kStartConnection = 0,
      kProtocol = 1,
            
      kProtocolVersion = 1
   };

   printf("fastMergeServerHist ready to accept connections\n");
   while (1) {
      TMessage *mess;
      TSocket  *s;

      // NOTE: this needs to be update to handle the case where the client
      // dies.
      s = mon->Select();

      if (s->IsA() == TServerSocket::Class()) {
         if (clientCount > 100) {
            printf("only accept 100 clients connections\n");
            mon->Remove(ss);
            ss->Close();
         } else {
            TSocket *client = ((TServerSocket *)s)->Accept();
            client->Send(clientIndex, kStartConnection);
            client->Send(kProtocolVersion, kProtocol);
            ++clientCount;
            ++clientIndex;
            mon->Add(client);
            printf("Accept %d connections\n",clientCount);
         }
         continue;
      }
      
      s->Recv(mess);

      if (mess==0) {
         Error("fastMergeServer","The client did not send a message\n");
      } else if (mess->What() == kMESS_STRING) {
         char str[64];
         mess->ReadString(str, 64);
         printf("Client %d: %s\n", clientCount, str);
         mon->Remove(s);
         printf("Client %d: bytes recv = %d, bytes sent = %d\n", clientCount, s->GetBytesRecv(),
                s->GetBytesSent());
         s->Close();
         --clientCount;
         if (mon->GetActive() == 0 || clientCount == 0) {
            printf("No more active clients... stopping\n");
            break;
         }
      } else if (mess->What() == kMESS_ANY) {

         Long64_t length;
         TString filename;
         Int_t clientId;
         mess->ReadInt(clientId);
         mess->ReadTString(filename);
         mess->ReadLong64(length); // '*mess >> length;' is broken in CINT for Long64_t.

         // Info("fastMergeServerHist","Received input from client %d for %s",clientId,filename.Data());
         
         TMemFile *transient = new TMemFile(filename,mess->Buffer() + mess->Length(),length,"UPDATE"); // UPDATE because we need to remove the TTree after merging them.
         mess->SetBufferOffset(mess->Length()+length);
 
         const Float_t clientThreshold = 0.75; // control how often the histogram are merged.  Here as soon as half the clients have reported.

         ParallelFileMerger *info = (ParallelFileMerger*)mergers.FindObject(filename);
         if (!info) {
            info = new ParallelFileMerger(filename,cache);
            mergers.Add(info);
         }

         if (R__NeedInitialMerge(transient)) {
            info->InitialMerge(transient);
         }
         info->RegisterClient(clientId,transient);
         if (info->NeedMerge(clientThreshold)) {
            // Enough clients reported.
            Info("fastMergeServerHist","Merging input from %ld clients (%d)",info->fClients.size(),clientId);
            info->Merge();
         }
         transient = 0;
      } else if (mess->What() == kMESS_OBJECT) {
         printf("got object of class: %s\n", mess->GetClass()->GetName());
      } else {
         printf("*** Unexpected message ***\n");
      }

      delete mess;
   }
   
   TIter next(&mergers);
   ParallelFileMerger *info;
   while ( (info = (ParallelFileMerger*)next()) ) {
      if (info->NeedFinalMerge()) 
      {
         info->Merge();
      }
   }

   mergers.Delete();
   delete mon;
   delete ss;
}
 parallelMergeServer.C:1
 parallelMergeServer.C:2
 parallelMergeServer.C:3
 parallelMergeServer.C:4
 parallelMergeServer.C:5
 parallelMergeServer.C:6
 parallelMergeServer.C:7
 parallelMergeServer.C:8
 parallelMergeServer.C:9
 parallelMergeServer.C:10
 parallelMergeServer.C:11
 parallelMergeServer.C:12
 parallelMergeServer.C:13
 parallelMergeServer.C:14
 parallelMergeServer.C:15
 parallelMergeServer.C:16
 parallelMergeServer.C:17
 parallelMergeServer.C:18
 parallelMergeServer.C:19
 parallelMergeServer.C:20
 parallelMergeServer.C:21
 parallelMergeServer.C:22
 parallelMergeServer.C:23
 parallelMergeServer.C:24
 parallelMergeServer.C:25
 parallelMergeServer.C:26
 parallelMergeServer.C:27
 parallelMergeServer.C:28
 parallelMergeServer.C:29
 parallelMergeServer.C:30
 parallelMergeServer.C:31
 parallelMergeServer.C:32
 parallelMergeServer.C:33
 parallelMergeServer.C:34
 parallelMergeServer.C:35
 parallelMergeServer.C:36
 parallelMergeServer.C:37
 parallelMergeServer.C:38
 parallelMergeServer.C:39
 parallelMergeServer.C:40
 parallelMergeServer.C:41
 parallelMergeServer.C:42
 parallelMergeServer.C:43
 parallelMergeServer.C:44
 parallelMergeServer.C:45
 parallelMergeServer.C:46
 parallelMergeServer.C:47
 parallelMergeServer.C:48
 parallelMergeServer.C:49
 parallelMergeServer.C:50
 parallelMergeServer.C:51
 parallelMergeServer.C:52
 parallelMergeServer.C:53
 parallelMergeServer.C:54
 parallelMergeServer.C:55
 parallelMergeServer.C:56
 parallelMergeServer.C:57
 parallelMergeServer.C:58
 parallelMergeServer.C:59
 parallelMergeServer.C:60
 parallelMergeServer.C:61
 parallelMergeServer.C:62
 parallelMergeServer.C:63
 parallelMergeServer.C:64
 parallelMergeServer.C:65
 parallelMergeServer.C:66
 parallelMergeServer.C:67
 parallelMergeServer.C:68
 parallelMergeServer.C:69
 parallelMergeServer.C:70
 parallelMergeServer.C:71
 parallelMergeServer.C:72
 parallelMergeServer.C:73
 parallelMergeServer.C:74
 parallelMergeServer.C:75
 parallelMergeServer.C:76
 parallelMergeServer.C:77
 parallelMergeServer.C:78
 parallelMergeServer.C:79
 parallelMergeServer.C:80
 parallelMergeServer.C:81
 parallelMergeServer.C:82
 parallelMergeServer.C:83
 parallelMergeServer.C:84
 parallelMergeServer.C:85
 parallelMergeServer.C:86
 parallelMergeServer.C:87
 parallelMergeServer.C:88
 parallelMergeServer.C:89
 parallelMergeServer.C:90
 parallelMergeServer.C:91
 parallelMergeServer.C:92
 parallelMergeServer.C:93
 parallelMergeServer.C:94
 parallelMergeServer.C:95
 parallelMergeServer.C:96
 parallelMergeServer.C:97
 parallelMergeServer.C:98
 parallelMergeServer.C:99
 parallelMergeServer.C:100
 parallelMergeServer.C:101
 parallelMergeServer.C:102
 parallelMergeServer.C:103
 parallelMergeServer.C:104
 parallelMergeServer.C:105
 parallelMergeServer.C:106
 parallelMergeServer.C:107
 parallelMergeServer.C:108
 parallelMergeServer.C:109
 parallelMergeServer.C:110
 parallelMergeServer.C:111
 parallelMergeServer.C:112
 parallelMergeServer.C:113
 parallelMergeServer.C:114
 parallelMergeServer.C:115
 parallelMergeServer.C:116
 parallelMergeServer.C:117
 parallelMergeServer.C:118
 parallelMergeServer.C:119
 parallelMergeServer.C:120
 parallelMergeServer.C:121
 parallelMergeServer.C:122
 parallelMergeServer.C:123
 parallelMergeServer.C:124
 parallelMergeServer.C:125
 parallelMergeServer.C:126
 parallelMergeServer.C:127
 parallelMergeServer.C:128
 parallelMergeServer.C:129
 parallelMergeServer.C:130
 parallelMergeServer.C:131
 parallelMergeServer.C:132
 parallelMergeServer.C:133
 parallelMergeServer.C:134
 parallelMergeServer.C:135
 parallelMergeServer.C:136
 parallelMergeServer.C:137
 parallelMergeServer.C:138
 parallelMergeServer.C:139
 parallelMergeServer.C:140
 parallelMergeServer.C:141
 parallelMergeServer.C:142
 parallelMergeServer.C:143
 parallelMergeServer.C:144
 parallelMergeServer.C:145
 parallelMergeServer.C:146
 parallelMergeServer.C:147
 parallelMergeServer.C:148
 parallelMergeServer.C:149
 parallelMergeServer.C:150
 parallelMergeServer.C:151
 parallelMergeServer.C:152
 parallelMergeServer.C:153
 parallelMergeServer.C:154
 parallelMergeServer.C:155
 parallelMergeServer.C:156
 parallelMergeServer.C:157
 parallelMergeServer.C:158
 parallelMergeServer.C:159
 parallelMergeServer.C:160
 parallelMergeServer.C:161
 parallelMergeServer.C:162
 parallelMergeServer.C:163
 parallelMergeServer.C:164
 parallelMergeServer.C:165
 parallelMergeServer.C:166
 parallelMergeServer.C:167
 parallelMergeServer.C:168
 parallelMergeServer.C:169
 parallelMergeServer.C:170
 parallelMergeServer.C:171
 parallelMergeServer.C:172
 parallelMergeServer.C:173
 parallelMergeServer.C:174
 parallelMergeServer.C:175
 parallelMergeServer.C:176
 parallelMergeServer.C:177
 parallelMergeServer.C:178
 parallelMergeServer.C:179
 parallelMergeServer.C:180
 parallelMergeServer.C:181
 parallelMergeServer.C:182
 parallelMergeServer.C:183
 parallelMergeServer.C:184
 parallelMergeServer.C:185
 parallelMergeServer.C:186
 parallelMergeServer.C:187
 parallelMergeServer.C:188
 parallelMergeServer.C:189
 parallelMergeServer.C:190
 parallelMergeServer.C:191
 parallelMergeServer.C:192
 parallelMergeServer.C:193
 parallelMergeServer.C:194
 parallelMergeServer.C:195
 parallelMergeServer.C:196
 parallelMergeServer.C:197
 parallelMergeServer.C:198
 parallelMergeServer.C:199
 parallelMergeServer.C:200
 parallelMergeServer.C:201
 parallelMergeServer.C:202
 parallelMergeServer.C:203
 parallelMergeServer.C:204
 parallelMergeServer.C:205
 parallelMergeServer.C:206
 parallelMergeServer.C:207
 parallelMergeServer.C:208
 parallelMergeServer.C:209
 parallelMergeServer.C:210
 parallelMergeServer.C:211
 parallelMergeServer.C:212
 parallelMergeServer.C:213
 parallelMergeServer.C:214
 parallelMergeServer.C:215
 parallelMergeServer.C:216
 parallelMergeServer.C:217
 parallelMergeServer.C:218
 parallelMergeServer.C:219
 parallelMergeServer.C:220
 parallelMergeServer.C:221
 parallelMergeServer.C:222
 parallelMergeServer.C:223
 parallelMergeServer.C:224
 parallelMergeServer.C:225
 parallelMergeServer.C:226
 parallelMergeServer.C:227
 parallelMergeServer.C:228
 parallelMergeServer.C:229
 parallelMergeServer.C:230
 parallelMergeServer.C:231
 parallelMergeServer.C:232
 parallelMergeServer.C:233
 parallelMergeServer.C:234
 parallelMergeServer.C:235
 parallelMergeServer.C:236
 parallelMergeServer.C:237
 parallelMergeServer.C:238
 parallelMergeServer.C:239
 parallelMergeServer.C:240
 parallelMergeServer.C:241
 parallelMergeServer.C:242
 parallelMergeServer.C:243
 parallelMergeServer.C:244
 parallelMergeServer.C:245
 parallelMergeServer.C:246
 parallelMergeServer.C:247
 parallelMergeServer.C:248
 parallelMergeServer.C:249
 parallelMergeServer.C:250
 parallelMergeServer.C:251
 parallelMergeServer.C:252
 parallelMergeServer.C:253
 parallelMergeServer.C:254
 parallelMergeServer.C:255
 parallelMergeServer.C:256
 parallelMergeServer.C:257
 parallelMergeServer.C:258
 parallelMergeServer.C:259
 parallelMergeServer.C:260
 parallelMergeServer.C:261
 parallelMergeServer.C:262
 parallelMergeServer.C:263
 parallelMergeServer.C:264
 parallelMergeServer.C:265
 parallelMergeServer.C:266
 parallelMergeServer.C:267
 parallelMergeServer.C:268
 parallelMergeServer.C:269
 parallelMergeServer.C:270
 parallelMergeServer.C:271
 parallelMergeServer.C:272
 parallelMergeServer.C:273
 parallelMergeServer.C:274
 parallelMergeServer.C:275
 parallelMergeServer.C:276
 parallelMergeServer.C:277
 parallelMergeServer.C:278
 parallelMergeServer.C:279
 parallelMergeServer.C:280
 parallelMergeServer.C:281
 parallelMergeServer.C:282
 parallelMergeServer.C:283
 parallelMergeServer.C:284
 parallelMergeServer.C:285
 parallelMergeServer.C:286
 parallelMergeServer.C:287
 parallelMergeServer.C:288
 parallelMergeServer.C:289
 parallelMergeServer.C:290
 parallelMergeServer.C:291
 parallelMergeServer.C:292
 parallelMergeServer.C:293
 parallelMergeServer.C:294
 parallelMergeServer.C:295
 parallelMergeServer.C:296
 parallelMergeServer.C:297
 parallelMergeServer.C:298
 parallelMergeServer.C:299
 parallelMergeServer.C:300
 parallelMergeServer.C:301
 parallelMergeServer.C:302
 parallelMergeServer.C:303
 parallelMergeServer.C:304
 parallelMergeServer.C:305
 parallelMergeServer.C:306
 parallelMergeServer.C:307
 parallelMergeServer.C:308
 parallelMergeServer.C:309
 parallelMergeServer.C:310
 parallelMergeServer.C:311
 parallelMergeServer.C:312
 parallelMergeServer.C:313
 parallelMergeServer.C:314
 parallelMergeServer.C:315
 parallelMergeServer.C:316
 parallelMergeServer.C:317
 parallelMergeServer.C:318
 parallelMergeServer.C:319
 parallelMergeServer.C:320
 parallelMergeServer.C:321
 parallelMergeServer.C:322
 parallelMergeServer.C:323
 parallelMergeServer.C:324
 parallelMergeServer.C:325
 parallelMergeServer.C:326
 parallelMergeServer.C:327
 parallelMergeServer.C:328
 parallelMergeServer.C:329
 parallelMergeServer.C:330
 parallelMergeServer.C:331
 parallelMergeServer.C:332
 parallelMergeServer.C:333
 parallelMergeServer.C:334
 parallelMergeServer.C:335
 parallelMergeServer.C:336
 parallelMergeServer.C:337
 parallelMergeServer.C:338
 parallelMergeServer.C:339
 parallelMergeServer.C:340
 parallelMergeServer.C:341
 parallelMergeServer.C:342
 parallelMergeServer.C:343
 parallelMergeServer.C:344
 parallelMergeServer.C:345
 parallelMergeServer.C:346
 parallelMergeServer.C:347
 parallelMergeServer.C:348
 parallelMergeServer.C:349
 parallelMergeServer.C:350
 parallelMergeServer.C:351
 parallelMergeServer.C:352
 parallelMergeServer.C:353
 parallelMergeServer.C:354
 parallelMergeServer.C:355
 parallelMergeServer.C:356
 parallelMergeServer.C:357
 parallelMergeServer.C:358
 parallelMergeServer.C:359
 parallelMergeServer.C:360
 parallelMergeServer.C:361
 parallelMergeServer.C:362
 parallelMergeServer.C:363
 parallelMergeServer.C:364
 parallelMergeServer.C:365
 parallelMergeServer.C:366
 parallelMergeServer.C:367
 parallelMergeServer.C:368
 parallelMergeServer.C:369
 parallelMergeServer.C:370
 parallelMergeServer.C:371
 parallelMergeServer.C:372
 parallelMergeServer.C:373
 parallelMergeServer.C:374
 parallelMergeServer.C:375
 parallelMergeServer.C:376
 parallelMergeServer.C:377
 parallelMergeServer.C:378
 parallelMergeServer.C:379
 parallelMergeServer.C:380
 parallelMergeServer.C:381
 parallelMergeServer.C:382
 parallelMergeServer.C:383
 parallelMergeServer.C:384
 parallelMergeServer.C:385
 parallelMergeServer.C:386
 parallelMergeServer.C:387
 parallelMergeServer.C:388
 parallelMergeServer.C:389
 parallelMergeServer.C:390
 parallelMergeServer.C:391
 parallelMergeServer.C:392
 parallelMergeServer.C:393
 parallelMergeServer.C:394
 parallelMergeServer.C:395
 parallelMergeServer.C:396
 parallelMergeServer.C:397
 parallelMergeServer.C:398
 parallelMergeServer.C:399
 parallelMergeServer.C:400
 parallelMergeServer.C:401
 parallelMergeServer.C:402
 parallelMergeServer.C:403
 parallelMergeServer.C:404
 parallelMergeServer.C:405
 parallelMergeServer.C:406
 parallelMergeServer.C:407
 parallelMergeServer.C:408
 parallelMergeServer.C:409
 parallelMergeServer.C:410
 parallelMergeServer.C:411
 parallelMergeServer.C:412
 parallelMergeServer.C:413
 parallelMergeServer.C:414
 parallelMergeServer.C:415
 parallelMergeServer.C:416
 parallelMergeServer.C:417
 parallelMergeServer.C:418
 parallelMergeServer.C:419
 parallelMergeServer.C:420
 parallelMergeServer.C:421
 parallelMergeServer.C:422
 parallelMergeServer.C:423
 parallelMergeServer.C:424
 parallelMergeServer.C:425
 parallelMergeServer.C:426
 parallelMergeServer.C:427
 parallelMergeServer.C:428
 parallelMergeServer.C:429
 parallelMergeServer.C:430
 parallelMergeServer.C:431
 parallelMergeServer.C:432
 parallelMergeServer.C:433
 parallelMergeServer.C:434
 parallelMergeServer.C:435
 parallelMergeServer.C:436
 parallelMergeServer.C:437
 parallelMergeServer.C:438