Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ProcFileElements.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_ProcFileElements
3///
4/// Class to hold information about the processed elements of a file
5///
6/// \macro_code
7///
8/// \author Gerardo Ganis (gerardo.ganis@cern.ch)
9
10#include "ProcFileElements.h"
11#include "TCollection.h"
12
13//_______________________________________________________________________
14Int_t ProcFileElements::ProcFileElement::Compare(const TObject *o) const
15{
16 // Compare this element with 'e'.
17 // Return
18 // -1 this should come first
19 // 0 same
20 // 1 e should come first
21
22 const ProcFileElements::ProcFileElement *e =
23 dynamic_cast<const ProcFileElements::ProcFileElement *>(o);
24 if (!e) return -1;
25
26 if (fFirst == e->fFirst) {
27 // They start at the same point
28 return 0;
29 } else if (fFirst < e->fFirst) {
30 // This starts first
31 return -1;
32 } else {
33 // e starts first
34 return 1;
35 }
36}
37
38//_______________________________________________________________________
39Int_t ProcFileElements::ProcFileElement::Overlapping(ProcFileElement *e)
40{
41 // Check overlapping status of this element with 'e'.
42 // Return
43 // -1 not overlapping
44 // 0 adjacent
45 // 1 overlapping
46
47 if (!e) return -1;
48
49 if (fFirst == 0 && fLast == -1) {
50 // We cover the full range, so we overlap
51 return 1;
52 }
53
54 if (fFirst < e->fFirst) {
55 if (fLast >= 0) {
56 if (fLast < e->fFirst - 1) {
57 // Disjoint
58 return -1;
59 } else {
60 // We somehow overlap
61 if (fLast == e->fFirst - 1) {
62 // Just adjacent
63 return 0;
64 } else {
65 // Real overlap
66 return 1;
67 }
68 }
69 } else {
70 // Always overlapping
71 return 1;
72 }
73 } else if (fFirst == e->fFirst) {
74 // Overlapping or adjacent
75 if (fFirst == fLast || e->fFirst == e->fLast) return 0;
76 return 1;
77 } else {
78 // The other way around
79 if (e->fLast >= 0) {
80 if (e->fLast < fFirst - 1) {
81 // Disjoint
82 return -1;
83 } else {
84 // We somehow overlap
85 if (e->fLast == fFirst - 1) {
86 // Just adjacent
87 return 0;
88 } else {
89 // Real overlap
90 return 1;
91 }
92 }
93 } else {
94 // Always overlapping
95 return 1;
96 }
97 }
98
99 // Should never be here
100 Warning("Overlapping", "should never be here!");
101 return -1;
102}
103
104//_______________________________________________________________________
105Int_t ProcFileElements::ProcFileElement::MergeElement(ProcFileElement *e)
106{
107 // Merge this element with element 'e'.
108 // Return -1 if it cannot be done, i.e. thei are disjoint; 0 otherwise
109
110 // Check if it can be done
111 if (Overlapping(e) < 0) return -1;
112
113 // Ok, we can merge: set the lower bound
114 if (e->fFirst < fFirst) fFirst = e->fFirst;
115
116 // Set the upper bound
117 if (fLast == -1 || e->fLast == -1) {
118 fLast = -1;
119 } else {
120 if (fLast < e->fLast) fLast = e->fLast;
121 }
122 // Done
123 return 0;
124}
125
126//_______________________________________________________________________
127void ProcFileElements::ProcFileElement::Print(Option_t *) const
128{
129 // Print range of this element
130
131 Printf("\tfirst: %lld\t last: %lld", fFirst, fLast);
132}
133
134//_______________________________________________________________________
135Int_t ProcFileElements::Add(Long64_t fst, Long64_t lst)
136{
137 // Add a new element to the list
138 // Return 1 if a new element has been added, 0 if it has been merged
139 // with an existing one, -1 in case of error
140
141 if (!fElements) fElements = new TSortedList;
142 if (!fElements) {
143 Error("Add", "could not create internal list!");
144 return -1;
145 }
146
147 // Create (temporary element)
148 ProcFileElements::ProcFileElement *ne =
149 new ProcFileElements::ProcFileElement(fst, lst);
150
151 // Check if if it is adjacent or overlapping with an existing one
152 TIter nxe(fElements);
153 ProcFileElements::ProcFileElement *e = nullptr;
154 while ((e = (ProcFileElements::ProcFileElement *)nxe())) {
155 if (e->MergeElement(ne) == 0) break;
156 }
157
158 Int_t rc = 0;
159 // Remove and re-add the merged element to sort correctly its possibly new position
160 if (e) {
161 fElements->Remove(e);
162 fElements->Add(e);
163 SafeDelete(ne);
164 } else {
165 // Add the new element
166 fElements->Add(ne);
167 rc = 1;
168 }
169
170 // Make sure that all what can be merged is merged (because of the order, some elements
171 // which could be merged are not merged, making the determination of fFirst and fLast below
172 // to give incorrect values)
173
174 ProcFileElements::ProcFileElement *ep = nullptr, *en = nullptr;
175 TObjLink *olp = fElements->FirstLink(), *oln = nullptr;
176 while (olp && (ep = (ProcFileElements::ProcFileElement *) olp->GetObject())) {
177 oln = olp->Next();
178 while (oln) {
179 if ((en = (ProcFileElements::ProcFileElement *) oln->GetObject())) {
180 if (ep->MergeElement(en) == 0) {
181 fElements->Remove(en);
182 delete en;
183 }
184 }
185 oln = oln->Next();
186 }
187 olp = olp->Next();
188 }
189
190 // New overall ranges
191 if ((e = (ProcFileElements::ProcFileElement *) fElements->First())) fFirst = e->fFirst;
192 if ((e = (ProcFileElements::ProcFileElement *) fElements->Last())) fLast = e->fLast;
193
194 // Done
195 return rc;
196}
197
198//_______________________________________________________________________
199void ProcFileElements::Print(Option_t *) const
200{
201 // Print info about this processed file
202
203 Printf("--- ProcFileElements ----------------------------------------");
204 Printf(" File: %s", fName.Data());
205 Printf(" # proc elements: %d", fElements ? fElements->GetSize() : 0);
206 TIter nxe(fElements);
207 ProcFileElements::ProcFileElement *e = nullptr;
208 while ((e = (ProcFileElements::ProcFileElement *)nxe())) { e->Print(); }
209 Printf(" Raw overall range: [%lld, %lld]", fFirst, fLast);
210 Printf("-------------------------------------------------------------");
211}
212
213//_______________________________________________________________________
214Int_t ProcFileElements::Merge(TCollection *li)
215{
216 // Merge this object with those in the list
217 // Return number of elements added
218
219 if (!li) return -1;
220
221 if (li->GetSize() <= 0) return 0;
222
223 Int_t nadd = 0;
224 TIter nxo(li);
225 ProcFileElements *pfe = nullptr;
226 while ((pfe = (ProcFileElements *) nxo())) {
227 if (strcmp(GetName(), pfe->GetName()))
228 Warning("Merge", "merging objects of different name! ('%s' != '%s')",
229 GetName(), pfe->GetName());
230 TIter nxe(pfe->GetListOfElements());
231 ProcFileElements::ProcFileElement *e = nullptr;
232 while ((e = (ProcFileElements::ProcFileElement *)nxe())) {
233 Int_t rc = Add(e->fFirst, e->fLast);
234 if (rc == 1) nadd++;
235 }
236 }
237 // Done
238 return nadd;
239}
Class to hold information about the processed elements of a file.
#define SafeDelete(p)
Definition RConfig.hxx:542
#define e(i)
Definition RSha256.hxx:103
int Int_t
Definition RtypesCore.h:45
long long Long64_t
Definition RtypesCore.h:80
const char Option_t
Definition RtypesCore.h:66
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2503
T1 fFirst
Definition X11Events.mm:86
Collection abstract base class.
Definition TCollection.h:65
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Mother of all ROOT objects.
Definition TObject.h:41
A sorted doubly linked list.
Definition TSortedList.h:28
TMatrixT< Element > & Add(TMatrixT< Element > &target, Element scalar, const TMatrixT< Element > &source)
Modify addition: target += scalar * source.