00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "RooFit.h"
00030 #include "Riostream.h"
00031
00032 #include "RooLinkedList.h"
00033 #include "RooLinkedListIter.h"
00034 #include "RooHashTable.h"
00035 #include "RooAbsArg.h"
00036 #include "RooMsgService.h"
00037
00038
00039
00040 ClassImp(RooLinkedList)
00041 ;
00042
00043
00044
00045 RooLinkedList::RooLinkedList(Int_t htsize) :
00046 _hashThresh(htsize), _size(0), _first(0), _last(0), _htableName(0), _htableLink(0)
00047 {
00048
00049
00050 }
00051
00052
00053
00054
00055
00056 RooLinkedList::RooLinkedList(const RooLinkedList& other) :
00057 TObject(other), _hashThresh(other._hashThresh), _size(0), _first(0), _last(0), _htableName(0), _htableLink(0), _name(other._name)
00058 {
00059
00060
00061 if (other._htableName) _htableName = new RooHashTable(other._htableName->size()) ;
00062 if (other._htableLink) _htableLink = new RooHashTable(other._htableLink->size(),RooHashTable::Pointer) ;
00063 RooLinkedListElem* elem = other._first ;
00064 while(elem) {
00065 Add(elem->_arg, elem->_refCount) ;
00066 elem = elem->_next ;
00067 }
00068 }
00069
00070
00071
00072
00073 RooLinkedList& RooLinkedList::operator=(const RooLinkedList& other)
00074 {
00075
00076
00077
00078 if (&other==this) return *this ;
00079
00080
00081 RooLinkedListElem* elem = other._first ;
00082 while(elem) {
00083 Add(elem->_arg) ;
00084 elem = elem->_next ;
00085 }
00086
00087 return *this ;
00088 }
00089
00090
00091
00092
00093 void RooLinkedList::setHashTableSize(Int_t size)
00094 {
00095
00096
00097
00098 if (size<0) {
00099 coutE(InputArguments) << "RooLinkedList::setHashTable() ERROR size must be positive" << endl ;
00100 return ;
00101 }
00102 if (size==0) {
00103 if (!_htableName) {
00104
00105 return ;
00106 } else {
00107
00108 delete _htableName ;
00109 delete _htableLink ;
00110 _htableName = 0 ;
00111 _htableLink = 0 ;
00112 }
00113 } else {
00114
00115
00116 if (_htableName) delete _htableName ;
00117 _htableName = new RooHashTable(size) ;
00118
00119 if (_htableLink) delete _htableLink ;
00120 _htableLink = new RooHashTable(size,RooHashTable::Pointer) ;
00121
00122
00123 RooLinkedListElem* ptr = _first ;
00124 while(ptr) {
00125 _htableName->add(ptr->_arg) ;
00126 _htableLink->add((TObject*)ptr,ptr->_arg) ;
00127 ptr = ptr->_next ;
00128 }
00129 }
00130 }
00131
00132
00133
00134
00135
00136 RooLinkedList::~RooLinkedList()
00137 {
00138
00139
00140 if (_htableName) {
00141 delete _htableName ;
00142 _htableName=0 ;
00143 }
00144 if (_htableLink) {
00145 delete _htableLink ;
00146 _htableLink=0 ;
00147 }
00148
00149 Clear() ;
00150 }
00151
00152
00153
00154
00155 RooLinkedListElem* RooLinkedList::findLink(const TObject* arg) const
00156 {
00157
00158
00159 if (_htableLink) {
00160 return _htableLink->findLinkTo(arg) ;
00161 }
00162
00163 RooLinkedListElem* ptr = _first;
00164 while(ptr) {
00165 if (ptr->_arg == arg) {
00166 return ptr ;
00167 }
00168 ptr = ptr->_next ;
00169 }
00170 return 0 ;
00171
00172 }
00173
00174
00175
00176
00177 void RooLinkedList::Add(TObject* arg, Int_t refCount)
00178 {
00179
00180
00181 if (!arg) return ;
00182
00183
00184 if (_htableName) {
00185
00186
00187 if (_size > _htableName->size()) {
00188 setHashTableSize(_size*2) ;
00189 }
00190
00191 } else if (_hashThresh>0 && _size>_hashThresh) {
00192
00193 setHashTableSize(_hashThresh) ;
00194 }
00195
00196 if (_last) {
00197
00198 _last = new RooLinkedListElem(arg,_last) ;
00199 } else {
00200
00201 _last = new RooLinkedListElem(arg) ;
00202 _first=_last ;
00203 }
00204
00205 if (_htableName){
00206
00207 _htableName->add(arg) ;
00208 _htableLink->add((TObject*)_last,arg) ;
00209 }
00210
00211 _size++ ;
00212 _last->_refCount = refCount ;
00213
00214 }
00215
00216
00217
00218
00219
00220 Bool_t RooLinkedList::Remove(TObject* arg)
00221 {
00222
00223
00224
00225 RooLinkedListElem* elem = findLink(arg) ;
00226 if (!elem) return kFALSE ;
00227
00228
00229 if (_htableName) {
00230 _htableName->remove(arg) ;
00231 }
00232 if (_htableLink) {
00233 _htableLink->remove((TObject*)elem,arg) ;
00234 }
00235
00236
00237 if (elem==_first) _first=elem->_next ;
00238 if (elem==_last) _last=elem->_prev ;
00239
00240
00241 _size-- ;
00242 delete elem ;
00243 return kTRUE ;
00244 }
00245
00246
00247
00248
00249
00250 TObject* RooLinkedList::At(Int_t index) const
00251 {
00252
00253
00254
00255
00256 if (index<0 || index>=_size) return 0 ;
00257
00258
00259
00260 RooLinkedListElem* ptr = _first;
00261 while(index--) ptr = ptr->_next ;
00262
00263
00264 return ptr->_arg ;
00265 }
00266
00267
00268
00269
00270
00271 Bool_t RooLinkedList::Replace(const TObject* oldArg, const TObject* newArg)
00272 {
00273
00274
00275
00276
00277 RooLinkedListElem* elem = findLink(oldArg) ;
00278 if (!elem) return kFALSE ;
00279
00280 if (_htableName) {
00281 _htableName->replace(oldArg,newArg) ;
00282 }
00283 if (_htableLink) {
00284
00285 _htableLink->remove((TObject*)elem,(TObject*)oldArg) ;
00286 _htableLink->add((TObject*)elem,(TObject*)newArg) ;
00287 }
00288
00289 elem->_arg = (TObject*)newArg ;
00290 return kTRUE ;
00291 }
00292
00293
00294
00295
00296 TObject* RooLinkedList::FindObject(const char* name) const
00297 {
00298
00299
00300
00301 return find(name) ;
00302 }
00303
00304
00305
00306
00307 TObject* RooLinkedList::FindObject(const TObject* obj) const
00308 {
00309
00310
00311
00312 RooLinkedListElem *elem = findLink((TObject*)obj) ;
00313 return elem ? elem->_arg : 0 ;
00314 }
00315
00316
00317
00318
00319 void RooLinkedList::Clear(Option_t *)
00320 {
00321
00322
00323 RooLinkedListElem* elem = _first;
00324 while(elem) {
00325 RooLinkedListElem* next = elem->_next ;
00326 delete elem ;
00327 elem = next ;
00328 }
00329 _first = 0 ;
00330 _last = 0 ;
00331 _size = 0 ;
00332
00333 if (_htableName) {
00334 Int_t hsize = _htableName->size() ;
00335 delete _htableName ;
00336 _htableName = new RooHashTable(hsize) ;
00337 }
00338 if (_htableLink) {
00339 Int_t hsize = _htableLink->size() ;
00340 delete _htableLink ;
00341 _htableLink = new RooHashTable(hsize,RooHashTable::Pointer) ;
00342 }
00343 }
00344
00345
00346
00347
00348 void RooLinkedList::Delete(Option_t *)
00349 {
00350
00351
00352
00353
00354 RooLinkedListElem* elem = _first;
00355 while(elem) {
00356 RooLinkedListElem* next = elem->_next ;
00357 delete elem->_arg ;
00358 delete elem ;
00359 elem = next ;
00360 }
00361 _first = 0 ;
00362 _last = 0 ;
00363 _size = 0 ;
00364
00365 if (_htableName) {
00366 Int_t hsize = _htableName->size() ;
00367 delete _htableName ;
00368 _htableName = new RooHashTable(hsize) ;
00369 }
00370 if (_htableLink) {
00371 Int_t hsize = _htableLink->size() ;
00372 delete _htableLink ;
00373 _htableLink = new RooHashTable(hsize,RooHashTable::Pointer) ;
00374 }
00375 }
00376
00377
00378
00379
00380
00381 TObject* RooLinkedList::find(const char* name) const
00382 {
00383
00384
00385
00386 if (_htableName) return _htableName->find(name) ;
00387
00388 RooLinkedListElem* ptr = _first ;
00389 while(ptr) {
00390 if (!strcmp(ptr->_arg->GetName(),name)) {
00391 return ptr->_arg ;
00392 }
00393 ptr = ptr->_next ;
00394 }
00395 return 0 ;
00396 }
00397
00398
00399
00400
00401 Int_t RooLinkedList::IndexOf(const TObject* arg) const
00402 {
00403
00404
00405
00406 RooLinkedListElem* ptr = _first;
00407 Int_t idx(0) ;
00408 while(ptr) {
00409 if (ptr->_arg==arg) return idx ;
00410 ptr = ptr->_next ;
00411 idx++ ;
00412 }
00413 return -1 ;
00414 }
00415
00416
00417
00418
00419 Int_t RooLinkedList::IndexOf(const char* name) const
00420 {
00421
00422
00423
00424 RooLinkedListElem* ptr = _first;
00425 Int_t idx(0) ;
00426 while(ptr) {
00427 if (strcmp(ptr->_arg->GetName(),name)==0) return idx ;
00428 ptr = ptr->_next ;
00429 idx++ ;
00430 }
00431 return -1 ;
00432 }
00433
00434
00435
00436
00437 void RooLinkedList::Print(const char* opt) const
00438 {
00439
00440
00441 RooLinkedListElem* elem = _first ;
00442 while(elem) {
00443 cout << elem->_arg << " : " ;
00444 elem->_arg->Print(opt) ;
00445 elem = elem->_next ;
00446 }
00447 }
00448
00449
00450
00451
00452 TIterator* RooLinkedList::MakeIterator(Bool_t dir) const
00453 {
00454
00455 return new RooLinkedListIter(this,dir) ;
00456 }
00457
00458
00459
00460 RooLinkedListIter RooLinkedList::iterator(Bool_t dir) const
00461 {
00462
00463 return RooLinkedListIter(this,dir) ;
00464 }
00465
00466
00467
00468
00469 void RooLinkedList::Sort(Bool_t ascend)
00470 {
00471
00472
00473
00474
00475 if (_size<2) return ;
00476
00477 Bool_t working(kTRUE) ;
00478 while(working) {
00479 working = kFALSE ;
00480 RooLinkedListElem* ptr = _first;
00481 while(ptr && ptr->_next) {
00482 if ((ascend && ptr->_arg->Compare(ptr->_next->_arg)>0) ||
00483 (!ascend && ptr->_arg->Compare(ptr->_next->_arg)<0)) {
00484 swapWithNext(ptr) ;
00485 working = kTRUE ;
00486 }
00487 ptr = ptr->_next ;
00488 }
00489 }
00490
00491 return ;
00492 }
00493
00494
00495
00496
00497 void RooLinkedList::swapWithNext(RooLinkedListElem* elemB)
00498 {
00499
00500
00501 RooLinkedListElem* elemA = elemB->_prev ;
00502 RooLinkedListElem* elemC = elemB->_next ;
00503 if (!elemC) return ;
00504
00505 RooLinkedListElem* elemD = elemC->_next ;
00506
00507 if (elemA) {
00508 elemA->_next = elemC ;
00509 } else {
00510 _first = elemC ;
00511 }
00512 elemB->_prev = elemC ;
00513 elemB->_next = elemD ;
00514 elemC->_prev = elemA ;
00515 elemC->_next = elemB ;
00516 if (elemD) {
00517 elemD->_prev = elemB ;
00518 } else {
00519 _last = elemB ;
00520 }
00521 return ;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 void RooLinkedList::Streamer(TBuffer &R__b)
00541 {
00542
00543
00544 if (R__b.IsReading()) {
00545
00546 Version_t v = R__b.ReadVersion();
00547
00548 TObject::Streamer(R__b);
00549
00550 Int_t size ;
00551 TObject* arg ;
00552
00553 R__b >> size ;
00554 while(size--) {
00555 R__b >> arg ;
00556 Add(arg) ;
00557 }
00558
00559 if (v>1) {
00560 R__b >> _name ;
00561 }
00562
00563 } else {
00564 R__b.WriteVersion(RooLinkedList::IsA());
00565 TObject::Streamer(R__b);
00566 R__b << _size ;
00567
00568 RooLinkedListElem* ptr = _first;
00569 while(ptr) {
00570 R__b << ptr->_arg ;
00571 ptr = ptr->_next ;
00572 }
00573
00574 R__b << _name ;
00575 }
00576 }
00577