00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "TSeqCollection.h"
00022 #include "TCollection.h"
00023 #include "TVirtualMutex.h"
00024 #include "TClass.h"
00025 #include "TMethodCall.h"
00026
00027 ClassImp(TSeqCollection)
00028
00029
00030 Int_t TSeqCollection::IndexOf(const TObject *obj) const
00031 {
00032
00033
00034
00035 Int_t idx = 0;
00036 TIter next(this);
00037 TObject *ob;
00038
00039 while ((ob = next())) {
00040 if (ob->IsEqual(obj)) return idx;
00041 idx++;
00042 }
00043 return -1;
00044 }
00045
00046
00047 Int_t TSeqCollection::ObjCompare(TObject *a, TObject *b)
00048 {
00049
00050
00051 if (a == 0 && b == 0) return 0;
00052 if (a == 0) return 1;
00053 if (b == 0) return -1;
00054 return a->Compare(b);
00055 }
00056
00057
00058 void TSeqCollection::QSort(TObject **a, Int_t first, Int_t last)
00059 {
00060
00061
00062
00063
00064
00065 R__LOCKGUARD2(gCollectionMutex);
00066
00067 static TObject *tmp;
00068 static int i;
00069 int j;
00070
00071 while (last - first > 1) {
00072 i = first;
00073 j = last;
00074 for (;;) {
00075 while (++i < last && ObjCompare(a[i], a[first]) < 0)
00076 ;
00077 while (--j > first && ObjCompare(a[j], a[first]) > 0)
00078 ;
00079 if (i >= j)
00080 break;
00081
00082 tmp = a[i];
00083 a[i] = a[j];
00084 a[j] = tmp;
00085 }
00086 if (j == first) {
00087 ++first;
00088 continue;
00089 }
00090 tmp = a[first];
00091 a[first] = a[j];
00092 a[j] = tmp;
00093 if (j - first < last - (j + 1)) {
00094 QSort(a, first, j);
00095 first = j + 1;
00096 } else {
00097 QSort(a, j + 1, last);
00098 last = j;
00099 }
00100 }
00101 }
00102
00103
00104 void TSeqCollection::QSort(TObject **a, Int_t nBs, TObject ***b, Int_t first, Int_t last)
00105 {
00106
00107
00108
00109
00110
00111
00112
00113 R__LOCKGUARD2(gCollectionMutex);
00114
00115 static TObject *tmp1, **tmp2;
00116 static int i;
00117 int j,k;
00118
00119 static int depth = 0;
00120 if (depth == 0 && nBs > 0) tmp2 = new TObject*[nBs];
00121 depth++;
00122
00123 while (last - first > 1) {
00124 i = first;
00125 j = last;
00126 for (;;) {
00127 while (++i < last && ObjCompare(a[i], a[first]) < 0) {}
00128 while (--j > first && ObjCompare(a[j], a[first]) > 0) {}
00129 if (i >= j) break;
00130
00131 tmp1 = a[i]; for(k=0;k<nBs;k++) tmp2[k] = b[k][i];
00132 a[i] = a[j]; for(k=0;k<nBs;k++) b[k][i] = b[k][j];
00133 a[j] = tmp1; for(k=0;k<nBs;k++) b[k][j] = tmp2[k];
00134 }
00135 if (j == first) {
00136 ++first;
00137 continue;
00138 }
00139 tmp1 = a[first]; for(k=0;k<nBs;k++) tmp2[k] = b[k][first];
00140 a[first] = a[j]; for(k=0;k<nBs;k++) b[k][first] = b[k][j];
00141 a[j] = tmp1; for(k=0;k<nBs;k++) b[k][j] = tmp2[k];
00142 if (j - first < last - (j + 1)) {
00143 QSort(a, nBs, b, first, j);
00144 first = j + 1;
00145 } else {
00146 QSort(a, nBs, b, j + 1, last);
00147 last = j;
00148 }
00149 }
00150 depth--;
00151
00152 if (depth == 0 && nBs > 0) delete [] tmp2;
00153 }
00154
00155
00156 Long64_t TSeqCollection::Merge(TCollection *list)
00157 {
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 Long64_t nmerged = 0;
00177 if (IsEmpty() || !list) {
00178 Warning("Merge", "list is empty - nothing to merge");
00179 return 0;
00180 }
00181 if (list->IsEmpty()) {
00182 Warning("Merge", "input list is empty - nothing to merge with");
00183 return 0;
00184 }
00185 TIter nextobject(this);
00186 TIter nextlist(list);
00187 TObject *object;
00188 TObject *objtomerge;
00189 TObject *collcrt;
00190 TSeqCollection *templist;
00191 TMethodCall callEnv;
00192 Int_t indobj = 0;
00193 while ((object = nextobject())) {
00194
00195 if (!object->IsA()) {
00196 indobj++;
00197 continue;
00198 }
00199 callEnv.InitWithPrototype(object->IsA(), "Merge", "TCollection*");
00200 if (!callEnv.IsValid()) {
00201 indobj++;
00202 continue;
00203 }
00204
00205 templist = (TSeqCollection*)IsA()->New();
00206 nextlist.Reset();
00207 Int_t indcoll = 0;
00208 while ((collcrt = nextlist())) {
00209 if (!collcrt->InheritsFrom(TSeqCollection::Class())) {
00210 Error("Merge", "some objects in the input list are not collections - merging aborted");
00211 delete templist;
00212 return 0;
00213 }
00214
00215
00216 objtomerge = ((TSeqCollection*)collcrt)->At(indobj);
00217 if (!objtomerge) {
00218 Warning("Merge", "Object of type %s (position %d in list) not found in list %d. Continuing...", object->ClassName(), indobj, indcoll);
00219 continue;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 if (object->IsA() != objtomerge->IsA()) {
00231 Error("Merge", "object of type %s at index %d not matching object of type %s in input list",
00232 object->ClassName(), indobj, objtomerge->ClassName());
00233 delete templist;
00234 return 0;
00235 }
00236
00237 templist->Add(objtomerge);
00238 nmerged++;
00239 }
00240
00241 callEnv.SetParam((Long_t) templist);
00242 callEnv.Execute(object);
00243 delete templist;
00244 indobj++;
00245 }
00246 return nmerged;
00247 }