1 // $Id: StObject.cxx,v 1.28 2015/08/28 19:54:18 perev Exp $ 2 // $Log: StObject.cxx,v $ 3 // Revision 1.28 2015/08/28 19:54:18 perev 4 // Add specific copy constructor to StObject. 5 // This ctr set zero to bit 1<<22. This boit means that object belongs 6 // to structured container. But copy obviously not. 7 // 8 // Revision 1.27 2012/06/11 15:08:41 fisyak 9 // std namespace, warn off for x64 10 // 11 // Revision 1.26 2012/02/21 18:50:46 perev 12 // bug #2281 fix 13 // 14 // Revision 1.22 2009/08/26 20:44:08 fine 15 // fix the compilation issues under SL5_64_bits gcc 4.3.2 16 // 17 // Revision 1.21 2006/08/10 03:34:38 perev 18 // Assert==>assert 19 // 20 // Revision 1.20 2005/10/21 21:13:52 perev 21 // test added to avoid copy to itself. Make walgrin happy 22 // 23 // Revision 1.19 2004/05/03 23:31:46 perev 24 // Possible non init WarnOff 25 // 26 // Revision 1.18 2003/09/02 17:59:24 perev 27 // gcc 3.2 updates + WarnOff 28 // 29 // Revision 1.17 2002/11/26 02:23:38 perev 30 // new ROOT adoptation 31 // 32 // Revision 1.16 2002/01/27 23:46:49 perev 33 // Zombie test added 34 // 35 // Revision 1.15 2001/05/30 17:46:41 perev 36 // StEvent branching 37 // 38 // Revision 1.14 2000/09/30 17:48:27 perev 39 // Zombies cons and loop for stru vector 40 // 41 // Revision 1.13 2000/09/15 15:11:58 perev 42 // Zombie for StEvent 43 // 44 // Revision 1.12 2000/07/30 01:49:03 perev 45 // StObject vers restored 46 // 47 // Revision 1.10 2000/06/19 01:28:26 perev 48 // STL StEvent 49 // 50 // Revision 1.9 2000/04/23 01:00:45 perev 51 // StEvent monolitic I/O 52 // 53 // Revision 1.8 2000/04/20 14:24:09 perev 54 // StArray fixes 55 // 56 // Revision 1.7 2000/04/18 02:57:25 perev 57 // StEvent browse 58 // 59 // Revision 1.6 1999/12/21 15:42:58 fine 60 // remove compilation warning 61 // 62 // Revision 1.5 1999/12/13 21:40:41 perev 63 // Remove warnings 64 // 65 // Revision 1.4 1999/11/17 14:22:10 perev 66 // bug in dtor fix 67 // 68 // Revision 1.3 1999/11/15 23:09:10 perev 69 // Streamer for StrArray and auto remove 70 // 71 // Revision 1.2 1999/06/23 20:31:04 perev 72 // StArray I/O + browser 73 // 74 // Revision 1.1 1999/04/30 13:15:55 fisyak 75 // Ad StObject, modification StArray for StRootEvent 76 // 77 #include "StObject.h" 78 #include "TDataSetIter.h" 79 #include "TROOT.h" 80 #include "TError.h" 81 #include "TMath.h" 82 #include "TBrowser.h" 83 #include "TClass.h" 84 #include "StArray.h" 85 #include "StAutoBrowse.h" 86 #include "TSystem.h" 87 88 StXRefManager *StXRefManager::fgManager=0; 89 UInt_t StObject::fgTally=0; 90 StXRefManagerList StXRefManager::fgManagerList; 91 int StXRefManager::fgRWmode=-1; 92 enum {kBelongs = (1<<22)}; 93 94 95 ClassImp(StObject) 96 //_____________________________________________________________________________ 97 StObject::StObject(const StObject &sto):TObject(sto) 98 { 99 SetBit(kBelongs,0); 100 } 101 //_____________________________________________________________________________ 102 StObject &StObject::operator=(const StObject &sto) 103 { 104 TObject::operator=(sto); 105 SetBit(kBelongs,0); return *this; 106 } 107 //_____________________________________________________________________________ 108 StObject::~StObject() 109 { 110 } 111 //_____________________________________________________________________________ 112 void StObject::Browse(TBrowser *tb) 113 { 114 StAutoBrowse::Browse(this,tb); 115 } 116 //_____________________________________________________________________________ 117 Bool_t StObject::IsFolder() const 118 { 119 return StAutoBrowse::Browse((TObject*)this,0); 120 } 121 //______________________________________________________________________________ 122 void StObject::Streamer(TBuffer &R__b) 123 { 124 // Stream an object of class StObject. 125 unsigned char uc=0; 126 127 if (R__b.IsReading()) { 128 Version_t R__v = R__b.ReadVersion(); 129 130 switch (R__v){ 131 case 1: TObject::Streamer(R__b); return; 132 case 2: R__b >> uc; if (uc) TObject::Streamer(R__b); return; 133 default: TObject::Streamer(R__b); return; 134 } 135 136 } else { 137 R__b.WriteVersion(StObject::Class()); 138 if (fgTally) { 139 UInt_t udx = GetUniqueID(); 140 if (!udx) { udx = ++fgTally; SetUniqueID(udx);} 141 } 142 TObject::Streamer(R__b); 143 } 144 } 145 //______________________________________________________________________________ 146 UInt_t StObject::Ztreamer(TBuffer &R__b) 147 { 148 UInt_t udx = GetUniqueID(); 149 if (!udx) { udx = ++fgTally; SetUniqueID(udx);} 150 R__b << udx; 151 return udx; 152 } 153 154 ClassImp(StUUId) 155 //_____________________________________________________________________________ 156 StUUId::StUUId() 157 { 158 memset(fID,0,16); 159 } 160 //_____________________________________________________________________________ 161 void StUUId::Generate() 162 { 163 static UInt_t uu[4] = {0,0,0,0}; 164 if (!uu[0]) { 165 uu[3] = TMath::Hash(gSystem->HostName()); 166 uu[3] ^= TMath::Hash(gSystem->WorkingDirectory()); 167 uu[2] = (gSystem->GetPid())<<16; 168 } 169 if (fID[0]) return; 170 fID[3] = uu[3]; 171 fID[2] = uu[2]++; 172 fID[1] = (UInt_t)((ULong_t)this); 173 #if ROOT_VERSION_CODE < 335105 /* ROOT_VERSION(5,29,1) */ 174 fID[0] = (UInt_t)((ULong_t)gSystem->Now()); 175 #else 176 fID[0] = (UInt_t)((ULong64_t)gSystem->Now()); 177 #endif 178 } 179 180 //_____________________________________________________________________________ 181 void StUUId::Streamer(TBuffer &R__b) 182 { 183 if (R__b.IsReading()) { 184 R__b.ReadFastArray (fID,4); 185 } else { 186 R__b.WriteFastArray(fID,4); 187 } 188 } 189 //_____________________________________________________________________________ 190 StUUId &StUUId::operator=(const StUUId &from) 191 { 192 if (this != &from) memcpy(fID,from.fID,sizeof(fID)); 193 return *this; 194 } 195 //_____________________________________________________________________________ 196 StUUId &StUUId::operator=(const char *from ) 197 { 198 memcpy(fID,from ,16); return *this; 199 } 200 //_____________________________________________________________________________ 201 int StUUId::Compare(const StUUId &u2) const 202 { 203 return memcmp(fID,u2.fID,16); 204 } 205 206 207 //_____________________________________________________________________________ 208 ClassImp(StXRef) 209 //_____________________________________________________________________________ 210 StXRef::StXRef(const char *brName, StXRefMain *evt,UInt_t tally) 211 : TDataSet(brName,evt) 212 { 213 SetMain(evt); 214 if (evt) SetUUId(evt->GetUUId()); 215 SetTally(tally); 216 217 } 218 //_____________________________________________________________________________ 219 StXRef::~StXRef() 220 { 221 } 222 223 //_____________________________________________________________________________ 224 void StXRef::Streamer(TBuffer &R__b) 225 { 226 UInt_t R__s,R__c; 227 228 if (R__b.IsReading() ) { //READ 229 StXRefManager::fgRWmode = 0; 230 Version_t R__v = R__b.ReadVersion(&R__s,&R__c); if (R__v){}; 231 fUUId.Streamer(R__b); 232 StXRefManager::Open(this); 233 TDataSet::Streamer(R__b); 234 R__b >> fTally; 235 StXRefManager::Close(this); 236 Synchro(1); 237 R__b.CheckByteCount(R__s,R__c,Class()); 238 239 } else { 240 StXRefManager::fgRWmode = 1; 241 assert(!fUUId.IsNull()); 242 Synchro(0); 243 R__c = R__b.WriteVersion(Class(),kTRUE); 244 fUUId.Streamer(R__b); 245 StXRefManager::Open(this); 246 TDataSet::Streamer(R__b); 247 StXRefManager::Close(this); 248 R__b << fTally; 249 R__b.SetByteCount(R__c,kTRUE); 250 } 251 } 252 //_____________________________________________________________________________ 253 StXRefMain *StXRef::GetMain() 254 { 255 if (!fMain) { 256 fMain = MakeMain(); 257 fMain->SetUUId(fUUId); 258 } 259 return fMain; 260 } 261 //_____________________________________________________________________________ 262 void StXRef::Add(TDataSet *ds) 263 { 264 if (ds == this) return; 265 if (ds->GetParent() == this) return; 266 TDataSet *os = FindByName(ds->GetName()); 267 if (os == ds) return; 268 if (os){ 269 assert(os->IsA()==ds->IsA()); 270 TDataSetIter Next(this); 271 StXRef *xr; 272 while((xr = (StXRef*)Next())) { 273 if (!xr->InheritsFrom(Class())) continue; 274 if (fUUId.Compare(xr->GetUUId()))continue; 275 Remove(xr); 276 } 277 } 278 if (ds->InheritsFrom(Class())) 279 assert(!fUUId.Compare(((StXRef*)ds)->GetUUId())); 280 ds->Shunt(0); TDataSet::Add(ds); 281 } 282 283 //_____________________________________________________________________________ 284 ClassImp(StXRefMain) 285 286 StXRefMain::~StXRefMain() 287 { 288 } 289 //______________________________________________________________________________ 290 void StXRefMain::Streamer(TBuffer &R__b) 291 { 292 StXRef::Streamer(R__b); 293 } 294 //_____________________________________________________________________________ 295 StXRefManager::StXRefManager(const StUUId &id) 296 { 297 fTally = 0; 298 fUpd = 0; 299 fUUId = id; 300 fMain=0; 301 fgManagerList.push_front(this); 302 fColList.push_front(0); 303 } 304 //_____________________________________________________________________________ 305 StXRefManager::~StXRefManager() 306 { 307 308 UInt_t umin,umax,u; 309 fObjTab.GetMiMax(umin,umax); 310 for (u=umin;u<=umax;u++) { 311 TObject **to = (TObject**)fObjTab.Get(u); 312 if (!to ) continue; 313 if (!*to) continue; 314 (*to)->SetUniqueID(0); 315 } 316 317 fgManagerList.remove(this); 318 if (fgManager==this) { fgManager=0; StObject::fgTally=0;} 319 fMain=0; fTally=0; 320 for (StCollListIter it = fColList.begin(); *it ;it++) {delete *it;} 321 } 322 323 324 //_____________________________________________________________________________ 325 void StXRefManager::Cd(StXRef *xref) 326 { 327 StXRefManager *man = fgManager; 328 if (man) { 329 if (man->fTally!=StObject::fgTally) {//Was modified 330 man->fTally = StObject::fgTally; 331 } } 332 333 if (!man || man->fUUId.Compare(xref->GetUUId())!=0) { 334 StXRefManagerListIter it; 335 man = 0; 336 for (it=fgManagerList.begin();it!=fgManagerList.end();it++){ 337 StXRefManager *m=*it; 338 if (m->fUUId.Compare(xref->GetUUId())!=0) continue; 339 man = m; break; 340 } } 341 fgManager = man; 342 } 343 //_____________________________________________________________________________ 344 void StXRefManager::Open(StXRef *xref) 345 { 346 if (fgRWmode==1) { //Writing 347 if (xref->IsMain()) StObject::fgTally=1; 348 return; 349 } 350 351 Cd(xref); 352 StXRefManager *man = fgManager; 353 if (!man) { 354 assert(xref->IsMain()); 355 man = new StXRefManager(xref->GetUUId()); 356 fgManagerList.push_front(man); 357 fgManager = man; 358 StObject::fgTally=1; 359 } 360 if (man->fMain==0) { 361 man->fMain = xref->GetMain(); 362 } else { 363 xref->SetMain(man->fMain); 364 } 365 } 366 //_____________________________________________________________________________ 367 void StXRefManager::Close(StXRef *xref) 368 { 369 if (fgRWmode==1) { //Writing 370 if (!xref->IsMain()) return; 371 StObject::fgTally=0;fgRWmode=-1; 372 return; 373 } 374 Cd(xref); 375 StXRefManager *man = fgManager; 376 assert(man); 377 if (xref->IsMain()) man->Update(); 378 if (man->fMain && man->fMain!= xref) man->fMain->Add(xref); 379 if (!xref->IsMain()) return; 380 delete man; fgRWmode=-1; StObject::fgTally=0; 381 } 382 383 384 //_____________________________________________________________________________ 385 void StXRefManager::AddColl (StProxyUrr *rarr) 386 { 387 fUpd=1; fColList.push_front(rarr); 388 } 389 //_____________________________________________________________________________ 390 void StXRefManager::AddColl (const StStrArray *sarr) 391 { 392 int size = sarr->size(); 393 if (!size) return; 394 fUpd=1; 395 UInt_t u; 396 const TObject *to, **p; 397 const_VecTObjIter it= sarr->begin(); 398 for(int i=0;i<size;i++) { 399 if (!(to = it[i])) continue; 400 if (!(u = to->GetUniqueID())) continue; 401 p = (const TObject**)fObjTab.GET(u); 402 if (*p) {// Used already 403 if (*p == to) continue; 404 assert(to->IsA() == (*p)->IsA()); 405 } 406 *p = to; 407 } 408 } 409 //_____________________________________________________________________________ 410 void StXRefManager::Update () 411 { 412 if(!fUpd) return; 413 fUpd = 0; 414 StObjArray *arr; 415 StProxyUrr *urr; 416 StCollListIter it; 417 UInt_t idx,udx,sizeUrr,lst=999999; 418 TObject **p; 419 for (it = fColList.begin(); (urr = *it);) {//List 420 sizeUrr = urr->size(); 421 switch (urr->GetType()) { 422 423 case 1: //Link case 424 assert(sizeUrr==1); 425 lst = 2; 426 udx = (*urr)[0]; 427 p = (TObject**)fObjTab.Get(udx); 428 if (!p || !(*p)) break; 429 urr->GetAdr()[0] = *p; 430 lst = 0; break; 431 432 case 0: //refArray case 433 lst=0; 434 arr = (StObjArray*)urr->GetArr(); assert(arr); 435 for (idx=0;idx<sizeUrr;idx++) { //RefArray loop 436 udx = (*urr)[idx]; 437 p = (TObject**)fObjTab.Get(udx); 438 if (!p || !(*p)) {(*urr)[lst++] = udx; continue;} 439 arr->push_back(*p); 440 }//end RefArray loop 441 } 442 if (lst) { urr->resize(lst-1); it++; } 443 else {it = fColList.erase(it); delete urr;} 444 }//end List 445 446 } 447 //_____________________________________________________________________________ 448 void StXRefManager::Clear (Option_t*) 449 {} 450 451 //_____________________________________________________________________________ 452 TDataSet *StXRefManager::GetMain() 453 { 454 if (!fgManager) return 0; 455 return fgManager->fMain; 456 } 457 //_____________________________________________________________________________ 458 TPageMap::TPageMap() 459 { 460 461 fList = 0; 462 fTopPage = NewPage(); 463 fLstPage = 0; 464 fLstUdx = 0; 465 fMinUdx = 1000000000; 466 fMaxUdx = 0; 467 } 468 //_____________________________________________________________________________ 469 470 471 TPageMap::~TPageMap() 472 { 473 ULong_t *p,*n=0; 474 for (p = fList; p ; p = n) 475 { n = (ULong_t*)p[0]; free(p);} 476 } 477 //_____________________________________________________________________________ 478 ULong_t *TPageMap::NewPage() 479 { 480 int n = sizeof(ULong_t)*(kPAGE+1); 481 ULong_t *p = (ULong_t*)malloc(n); memset(p,0,n); 482 p[0] = (ULong_t)fList; fList = p; 483 return p+1; 484 } 485 486 //_____________________________________________________________________________ 487 ULong_t *TPageMap::Get(UInt_t udx) 488 { 489 if ((udx&kLAST) == fLstUdx) { 490 if (!fLstPage) return 0; 491 492 } else { 493 494 fLstPage = 0; 495 fLstUdx = (udx&kLAST); 496 ULong_t *b = fTopPage; 497 UInt_t u,s=kBITZ; 498 while(2001) { 499 u = (udx>>s)&kMASK; 500 b = (ULong_t*)b[u]; 501 if (!b) return 0; 502 if (!(s -=kBITS)) break;; 503 } 504 fLstPage = b; 505 } 506 return fLstPage + (udx&kMASK); 507 } 508 //_____________________________________________________________________________ 509 ULong_t *TPageMap::GET(UInt_t udx) 510 { 511 if (fMinUdx>udx) fMinUdx=udx; 512 if (fMaxUdx<udx) fMaxUdx=udx; 513 514 if ((udx&kLAST) != fLstUdx || fLstPage==0) { 515 fLstUdx = (udx&kLAST); 516 ULong_t *b = fTopPage,*a; 517 UInt_t u,s=kBITZ; 518 while(2001) { 519 u = (udx>>s)&kMASK; 520 if (!(a = (ULong_t*)b[u])) {((ULong_t**)b)[u] = a = NewPage();} 521 b = a; 522 if (!(s -=kBITS)) break;; 523 } 524 fLstPage = b; 525 } 526 return fLstPage + (udx&kMASK); 527 } 528 //_____________________________________________________________________________ 529 void TPageMap::Test() 530 { 531 TPageMap map; 532 533 UInt_t range = 10000000; 534 UInt_t step = range/1000; 535 UInt_t u; 536 for (u=1; u < range; u+=step) 537 { 538 ULong_t *p = map.GET(u); 539 assert(p); 540 assert(!*p); 541 *p = u; 542 } 543 for (u=1; u < range; u+=step) 544 { 545 ULong_t *p = map.Get(u); 546 assert(p); 547 assert(*p); 548 assert(*p==u); 549 } 550 printf(" TPageMap::Test() OK\n"); 551 } 552 553 554 555 556 557 558 559 560 561