From $ROOTSYS/tutorials/proof/ProcFileElements.C

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// ProcFileElements                                                     //
//                                                                      //
// This class holds information about the processed elements of a file. //
// Used for testing.                                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "ProcFileElements.h"
#include "TCollection.h"

//_______________________________________________________________________
Int_t ProcFileElements::ProcFileElement::Compare(const TObject *o) const
{
   // Compare this element with 'e'.
   // Return
   //          -1      this should come first
   //           0      same
   //           1      e should come first

   const ProcFileElements::ProcFileElement *e =
      dynamic_cast<const ProcFileElements::ProcFileElement *>(o);
   if (!e) return -1;

   if (fFirst == e->fFirst) {
      // They start at the same point 
      return 0;
   } else if (fFirst < e->fFirst) {
      // This starts first
      return -1;
   } else {
      // e starts first
      return 1;
   }
}

//_______________________________________________________________________
Int_t ProcFileElements::ProcFileElement::Overlapping(ProcFileElement *e)
{
   // Check overlapping status of this element with 'e'.
   // Return
   //          -1      not overlapping
   //           0      adjacent
   //           1      overlapping

   if (!e) return -1;

   if (fFirst == 0 && fLast == -1) {
      // We cover the full range, so we overlap
      return 1;
   }

   if (fFirst < e->fFirst) {
      if (fLast >= 0) {
         if (fLast < e->fFirst - 1) {
            // Disjoint
            return -1;
         } else {
            // We somehow overlap
            if (fLast == e->fFirst - 1) {
               // Just adjacent
               return 0;
            } else {
               // Real overlap
               return 1;
            }
         }
      } else {
         // Always overlapping
         return 1;
      }
   } else if (fFirst == e->fFirst) {
      // Overlapping or adjacent
      if (fFirst == fLast || e->fFirst == e->fLast) return 0;
      return 1;
   } else {
      // The other way around
      if (e->fLast >= 0) {
         if (e->fLast < fFirst - 1) {
            // Disjoint
            return -1;
         } else {
            // We somehow overlap
            if (e->fLast == fFirst - 1) {
               // Just adjacent
               return 0;
            } else {
               // Real overlap
               return 1;
            }
         }
      } else {
         // Always overlapping
         return 1;
      }
   }

   // Should never be here
   Warning("Overlapping", "should never be here!");
   return -1;
}

//_______________________________________________________________________
Int_t ProcFileElements::ProcFileElement::MergeElement(ProcFileElement *e)
{
   // Merge this element with element 'e'.
   // Return -1 if it cannot be done, i.e. thei are disjoint; 0 otherwise

   // Check if it can be done
   if (Overlapping(e) < 0) return -1;
   
   // Ok, we can merge: set the lower bound
   if (e->fFirst < fFirst) fFirst = e->fFirst;
   
   // Set the upper bound
   if (fLast == -1 || e->fLast == -1) {
      fLast = -1;
   } else {
      if (fLast < e->fLast) fLast = e->fLast;
   }
   // Done
   return 0;
}

//_______________________________________________________________________
void ProcFileElements::ProcFileElement::Print(Option_t *) const
{
   // Print range of this element

   Printf("\tfirst: %lld\t last: %lld", fFirst, fLast);
}

//_______________________________________________________________________
Int_t ProcFileElements::Add(Long64_t fst, Long64_t lst)
{
   // Add a new element to the list 
   // Return 1 if a new element has been added, 0 if it has been merged
   // with an existing one, -1 in case of error

   if (!fElements) fElements = new TSortedList;
   if (!fElements) {
      Error("Add", "could not create internal list!");
      return -1;
   }
   
   // Create (temporary element)
   ProcFileElements::ProcFileElement *ne =
      new ProcFileElements::ProcFileElement(fst, lst);

   // Check if if it is adjacent or overlapping with an existing one
   TIter nxe(fElements);
   ProcFileElements::ProcFileElement *e = 0;
   while ((e = (ProcFileElements::ProcFileElement *)nxe())) {
      if (e->MergeElement(ne) == 0) break;
   }
   
   Int_t rc = 0;
   // Remove and re-add the merged element to sort correctly its possibly new position
   if (e) {
      fElements->Remove(e);
      fElements->Add(e);
      SafeDelete(ne);
   } else {
      // Add the new element
      fElements->Add(ne);
      rc = 1;
   }

   // Make sure that all what can be merged is merged (because of the order, some elements
   // which could be merged are not merged, making the determination of fFirst and fLast below
   // to give incorrect values)
   
   ProcFileElements::ProcFileElement *ep = 0, *en = 0;
   TObjLink *olp = fElements->FirstLink(), *oln = 0;
   while (olp && (ep = (ProcFileElements::ProcFileElement *) olp->GetObject())) {
      oln = olp->Next();
      while (oln) {
         if ((en = (ProcFileElements::ProcFileElement *) oln->GetObject())) {
            if (ep->MergeElement(en) == 0) {
               fElements->Remove(en);
               delete en;
            }
         }
         oln = oln->Next();
      }
      olp = olp->Next();
   }

   // New overall ranges
   if ((e = (ProcFileElements::ProcFileElement *) fElements->First())) fFirst = e->fFirst;
   if ((e = (ProcFileElements::ProcFileElement *) fElements->Last())) fLast = e->fLast;
   
   // Done
   return rc;
}

//_______________________________________________________________________
void ProcFileElements::Print(Option_t *) const
{
   // Print info about this processed file

   Printf("--- ProcFileElements ----------------------------------------");
   Printf(" File: %s", fName.Data());
   Printf(" # proc elements: %d", fElements ? fElements->GetSize() : 0);
   TIter nxe(fElements);
   ProcFileElements::ProcFileElement *e = 0;
   while ((e = (ProcFileElements::ProcFileElement *)nxe())) { e->Print(); }
   Printf(" Raw overall range: [%lld, %lld]", fFirst, fLast);
   Printf("-------------------------------------------------------------");
}

//_______________________________________________________________________
Int_t ProcFileElements::Merge(TCollection *li)
{
   // Merge this object with those in the list
   // Return number of elements added

   if (!li) return -1;
   
   if (li->GetSize() <= 0) return 0;

   Int_t nadd = 0;
   TIter nxo(li);
   ProcFileElements *pfe = 0;
   while ((pfe = (ProcFileElements *) nxo())) {
      if (strcmp(GetName(), pfe->GetName()))
         Warning("Merge", "merging objects of different name! ('%s' != '%s')",
                          GetName(),  pfe->GetName());
      TIter nxe(pfe->GetListOfElements());
      ProcFileElements::ProcFileElement *e = 0;
      while ((e = (ProcFileElements::ProcFileElement *)nxe())) {
         Int_t rc = Add(e->fFirst, e->fLast);
         if (rc == 1) nadd++;
      }
   }
   // Done
   return nadd;
}
 ProcFileElements.C:1
 ProcFileElements.C:2
 ProcFileElements.C:3
 ProcFileElements.C:4
 ProcFileElements.C:5
 ProcFileElements.C:6
 ProcFileElements.C:7
 ProcFileElements.C:8
 ProcFileElements.C:9
 ProcFileElements.C:10
 ProcFileElements.C:11
 ProcFileElements.C:12
 ProcFileElements.C:13
 ProcFileElements.C:14
 ProcFileElements.C:15
 ProcFileElements.C:16
 ProcFileElements.C:17
 ProcFileElements.C:18
 ProcFileElements.C:19
 ProcFileElements.C:20
 ProcFileElements.C:21
 ProcFileElements.C:22
 ProcFileElements.C:23
 ProcFileElements.C:24
 ProcFileElements.C:25
 ProcFileElements.C:26
 ProcFileElements.C:27
 ProcFileElements.C:28
 ProcFileElements.C:29
 ProcFileElements.C:30
 ProcFileElements.C:31
 ProcFileElements.C:32
 ProcFileElements.C:33
 ProcFileElements.C:34
 ProcFileElements.C:35
 ProcFileElements.C:36
 ProcFileElements.C:37
 ProcFileElements.C:38
 ProcFileElements.C:39
 ProcFileElements.C:40
 ProcFileElements.C:41
 ProcFileElements.C:42
 ProcFileElements.C:43
 ProcFileElements.C:44
 ProcFileElements.C:45
 ProcFileElements.C:46
 ProcFileElements.C:47
 ProcFileElements.C:48
 ProcFileElements.C:49
 ProcFileElements.C:50
 ProcFileElements.C:51
 ProcFileElements.C:52
 ProcFileElements.C:53
 ProcFileElements.C:54
 ProcFileElements.C:55
 ProcFileElements.C:56
 ProcFileElements.C:57
 ProcFileElements.C:58
 ProcFileElements.C:59
 ProcFileElements.C:60
 ProcFileElements.C:61
 ProcFileElements.C:62
 ProcFileElements.C:63
 ProcFileElements.C:64
 ProcFileElements.C:65
 ProcFileElements.C:66
 ProcFileElements.C:67
 ProcFileElements.C:68
 ProcFileElements.C:69
 ProcFileElements.C:70
 ProcFileElements.C:71
 ProcFileElements.C:72
 ProcFileElements.C:73
 ProcFileElements.C:74
 ProcFileElements.C:75
 ProcFileElements.C:76
 ProcFileElements.C:77
 ProcFileElements.C:78
 ProcFileElements.C:79
 ProcFileElements.C:80
 ProcFileElements.C:81
 ProcFileElements.C:82
 ProcFileElements.C:83
 ProcFileElements.C:84
 ProcFileElements.C:85
 ProcFileElements.C:86
 ProcFileElements.C:87
 ProcFileElements.C:88
 ProcFileElements.C:89
 ProcFileElements.C:90
 ProcFileElements.C:91
 ProcFileElements.C:92
 ProcFileElements.C:93
 ProcFileElements.C:94
 ProcFileElements.C:95
 ProcFileElements.C:96
 ProcFileElements.C:97
 ProcFileElements.C:98
 ProcFileElements.C:99
 ProcFileElements.C:100
 ProcFileElements.C:101
 ProcFileElements.C:102
 ProcFileElements.C:103
 ProcFileElements.C:104
 ProcFileElements.C:105
 ProcFileElements.C:106
 ProcFileElements.C:107
 ProcFileElements.C:108
 ProcFileElements.C:109
 ProcFileElements.C:110
 ProcFileElements.C:111
 ProcFileElements.C:112
 ProcFileElements.C:113
 ProcFileElements.C:114
 ProcFileElements.C:115
 ProcFileElements.C:116
 ProcFileElements.C:117
 ProcFileElements.C:118
 ProcFileElements.C:119
 ProcFileElements.C:120
 ProcFileElements.C:121
 ProcFileElements.C:122
 ProcFileElements.C:123
 ProcFileElements.C:124
 ProcFileElements.C:125
 ProcFileElements.C:126
 ProcFileElements.C:127
 ProcFileElements.C:128
 ProcFileElements.C:129
 ProcFileElements.C:130
 ProcFileElements.C:131
 ProcFileElements.C:132
 ProcFileElements.C:133
 ProcFileElements.C:134
 ProcFileElements.C:135
 ProcFileElements.C:136
 ProcFileElements.C:137
 ProcFileElements.C:138
 ProcFileElements.C:139
 ProcFileElements.C:140
 ProcFileElements.C:141
 ProcFileElements.C:142
 ProcFileElements.C:143
 ProcFileElements.C:144
 ProcFileElements.C:145
 ProcFileElements.C:146
 ProcFileElements.C:147
 ProcFileElements.C:148
 ProcFileElements.C:149
 ProcFileElements.C:150
 ProcFileElements.C:151
 ProcFileElements.C:152
 ProcFileElements.C:153
 ProcFileElements.C:154
 ProcFileElements.C:155
 ProcFileElements.C:156
 ProcFileElements.C:157
 ProcFileElements.C:158
 ProcFileElements.C:159
 ProcFileElements.C:160
 ProcFileElements.C:161
 ProcFileElements.C:162
 ProcFileElements.C:163
 ProcFileElements.C:164
 ProcFileElements.C:165
 ProcFileElements.C:166
 ProcFileElements.C:167
 ProcFileElements.C:168
 ProcFileElements.C:169
 ProcFileElements.C:170
 ProcFileElements.C:171
 ProcFileElements.C:172
 ProcFileElements.C:173
 ProcFileElements.C:174
 ProcFileElements.C:175
 ProcFileElements.C:176
 ProcFileElements.C:177
 ProcFileElements.C:178
 ProcFileElements.C:179
 ProcFileElements.C:180
 ProcFileElements.C:181
 ProcFileElements.C:182
 ProcFileElements.C:183
 ProcFileElements.C:184
 ProcFileElements.C:185
 ProcFileElements.C:186
 ProcFileElements.C:187
 ProcFileElements.C:188
 ProcFileElements.C:189
 ProcFileElements.C:190
 ProcFileElements.C:191
 ProcFileElements.C:192
 ProcFileElements.C:193
 ProcFileElements.C:194
 ProcFileElements.C:195
 ProcFileElements.C:196
 ProcFileElements.C:197
 ProcFileElements.C:198
 ProcFileElements.C:199
 ProcFileElements.C:200
 ProcFileElements.C:201
 ProcFileElements.C:202
 ProcFileElements.C:203
 ProcFileElements.C:204
 ProcFileElements.C:205
 ProcFileElements.C:206
 ProcFileElements.C:207
 ProcFileElements.C:208
 ProcFileElements.C:209
 ProcFileElements.C:210
 ProcFileElements.C:211
 ProcFileElements.C:212
 ProcFileElements.C:213
 ProcFileElements.C:214
 ProcFileElements.C:215
 ProcFileElements.C:216
 ProcFileElements.C:217
 ProcFileElements.C:218
 ProcFileElements.C:219
 ProcFileElements.C:220
 ProcFileElements.C:221
 ProcFileElements.C:222
 ProcFileElements.C:223
 ProcFileElements.C:224
 ProcFileElements.C:225
 ProcFileElements.C:226
 ProcFileElements.C:227
 ProcFileElements.C:228
 ProcFileElements.C:229
 ProcFileElements.C:230
 ProcFileElements.C:231
 ProcFileElements.C:232
 ProcFileElements.C:233
 ProcFileElements.C:234
 ProcFileElements.C:235
 ProcFileElements.C:236
 ProcFileElements.C:237
 ProcFileElements.C:238
 ProcFileElements.C:239
 ProcFileElements.C:240