@@ -1346,6 +1346,91 @@ Int_t TChain::LoadBaskets(Long64_t /*maxmemory*/)
1346
1346
return 0 ;
1347
1347
}
1348
1348
1349
+ Long64_t TChain::RefreshFriendAddresses (TTree &mainTree, TTree &innerTree, Long64_t entry)
1350
+ {
1351
+ auto *friendList = mainTree.GetListOfFriends ();
1352
+ if (!friendList)
1353
+ return 0 ;
1354
+
1355
+ TFriendLock lock (&mainTree, kLoadTree );
1356
+
1357
+ bool needUpdate = false ;
1358
+
1359
+ for (auto *frEl : ROOT::Detail::TRangeStaticCast<TFriendElement>(*friendList)) {
1360
+ auto *frTree = frEl->GetTree ();
1361
+ // Depending on whether we are traversing the friends of the chain itself
1362
+ // or the friends of the current tree in the chain, the meaning of the
1363
+ // entry parameter changes. In the first case, we pass the current chain
1364
+ // global entry number. In the latter case, we pass the local tree entry
1365
+ // number.
1366
+ frTree->LoadTreeFriend (entry, &mainTree);
1367
+ }
1368
+
1369
+ if (auto *innerFriendList = innerTree.GetListOfFriends ()) {
1370
+ for (auto *frEl : ROOT::Detail::TRangeStaticCast<TFriendElement>(*innerFriendList)) {
1371
+ if (frEl->IsUpdated ()) {
1372
+ needUpdate = true ;
1373
+ frEl->ResetUpdated ();
1374
+ }
1375
+ }
1376
+ }
1377
+
1378
+ if (needUpdate) {
1379
+ // Update the branch/leaf addresses and
1380
+ // the list of leaves in all TTreeFormula of the TTreePlayer (if any).
1381
+
1382
+ // Set the branch statuses for the newly opened file.
1383
+ for (auto *chainEl : ROOT::Detail::TRangeStaticCast<TChainElement>(*fStatus )) {
1384
+ Int_t status = chainEl->GetStatus ();
1385
+ // Only set the branch status if it has a value provided
1386
+ // by the user
1387
+ if (status != -1 )
1388
+ innerTree.SetBranchStatus (chainEl->GetName (), status);
1389
+ }
1390
+
1391
+ // Set the branch addresses for the newly opened file.
1392
+ for (auto *chainEl : ROOT::Detail::TRangeStaticCast<TChainElement>(*fStatus )) {
1393
+ void *addr = chainEl->GetBaddress ();
1394
+ if (addr) {
1395
+ TBranch *br = innerTree.GetBranch (chainEl->GetName ());
1396
+ TBranch **pp = chainEl->GetBranchPtr ();
1397
+ if (pp) {
1398
+ // FIXME: What if br is zero here?
1399
+ *pp = br;
1400
+ }
1401
+ if (br) {
1402
+ if (!chainEl->GetCheckedType ()) {
1403
+ Int_t res =
1404
+ CheckBranchAddressType (br, TClass::GetClass (chainEl->GetBaddressClassName ()),
1405
+ (EDataType)chainEl->GetBaddressType (), chainEl->GetBaddressIsPtr ());
1406
+ if ((res & kNeedEnableDecomposedObj ) && !br->GetMakeClass ()) {
1407
+ br->SetMakeClass (true );
1408
+ }
1409
+ chainEl->SetDecomposedObj (br->GetMakeClass ());
1410
+ chainEl->SetCheckedType (true );
1411
+ }
1412
+ // FIXME: We may have to tell the branch it should
1413
+ // not be an owner of the object pointed at.
1414
+ br->SetAddress (addr);
1415
+ if (TestBit (kAutoDelete )) {
1416
+ br->SetAutoDelete (true );
1417
+ }
1418
+ }
1419
+ }
1420
+ }
1421
+ if (fPlayer ) {
1422
+ fPlayer ->UpdateFormulaLeaves ();
1423
+ }
1424
+ // Notify user if requested.
1425
+ if (fNotify ) {
1426
+ if (!fNotify ->Notify ())
1427
+ return -6 ;
1428
+ }
1429
+ }
1430
+
1431
+ return 0 ;
1432
+ }
1433
+
1349
1434
// //////////////////////////////////////////////////////////////////////////////
1350
1435
// / Find the tree which contains entry, and set it as the current tree.
1351
1436
// /
@@ -1414,83 +1499,21 @@ Long64_t TChain::LoadTree(Long64_t entry)
1414
1499
// next loop).
1415
1500
fTree ->LoadTree (treeReadEntry);
1416
1501
1417
- if (fFriends ) {
1418
- // The current tree has not changed but some of its friends might.
1419
- //
1420
- TIter next (fFriends );
1421
- TFriendLock lock (this , kLoadTree );
1422
- TFriendElement* fe = nullptr ;
1423
- while ((fe = (TFriendElement*) next ())) {
1424
- TTree* at = fe->GetTree ();
1425
- // If the tree is a
1426
- // direct friend of the chain, it should be scanned
1427
- // used the chain entry number and NOT the tree entry
1428
- // number (treeReadEntry) hence we do:
1429
- at->LoadTreeFriend (entry, this );
1430
- }
1431
- bool needUpdate = false ;
1432
- if (fTree ->GetListOfFriends ()) {
1433
- for (auto fetree : ROOT::Detail::TRangeStaticCast<TFriendElement>(*fTree ->GetListOfFriends ())) {
1434
- if (fetree->IsUpdated ()) {
1435
- needUpdate = true ;
1436
- fetree->ResetUpdated ();
1437
- }
1438
- }
1502
+ if (fExternalFriends ) {
1503
+ for (auto external_fe : ROOT::Detail::TRangeStaticCast<TFriendElement>(*fExternalFriends )) {
1504
+ external_fe->MarkUpdated ();
1439
1505
}
1440
- if (needUpdate) {
1441
- // Update the branch/leaf addresses and
1442
- // the list of leaves in all TTreeFormula of the TTreePlayer (if any).
1443
-
1444
- // Set the branch statuses for the newly opened file.
1445
- TChainElement *frelement;
1446
- TIter fnext (fStatus );
1447
- while ((frelement = (TChainElement*) fnext ())) {
1448
- Int_t status = frelement->GetStatus ();
1449
- // Only set the branch status if it has a value provided
1450
- // by the user
1451
- if (status != -1 )
1452
- fTree ->SetBranchStatus (frelement->GetName (), status);
1453
- }
1506
+ }
1454
1507
1455
- // Set the branch addresses for the newly opened file.
1456
- fnext.Reset ();
1457
- while ((frelement = (TChainElement*) fnext ())) {
1458
- void * addr = frelement->GetBaddress ();
1459
- if (addr) {
1460
- TBranch* br = fTree ->GetBranch (frelement->GetName ());
1461
- TBranch** pp = frelement->GetBranchPtr ();
1462
- if (pp) {
1463
- // FIXME: What if br is zero here?
1464
- *pp = br;
1465
- }
1466
- if (br) {
1467
- if (!frelement->GetCheckedType ()) {
1468
- Int_t res = CheckBranchAddressType (br, TClass::GetClass (frelement->GetBaddressClassName ()),
1469
- (EDataType) frelement->GetBaddressType (), frelement->GetBaddressIsPtr ());
1470
- if ((res & kNeedEnableDecomposedObj ) && !br->GetMakeClass ()) {
1471
- br->SetMakeClass (true );
1472
- }
1473
- frelement->SetDecomposedObj (br->GetMakeClass ());
1474
- frelement->SetCheckedType (true );
1475
- }
1476
- // FIXME: We may have to tell the branch it should
1477
- // not be an owner of the object pointed at.
1478
- br->SetAddress (addr);
1479
- if (TestBit (kAutoDelete )) {
1480
- br->SetAutoDelete (true );
1481
- }
1482
- }
1483
- }
1484
- }
1485
- if (fPlayer ) {
1486
- fPlayer ->UpdateFormulaLeaves ();
1487
- }
1488
- // Notify user if requested.
1489
- if (fNotify ) {
1490
- if (!fNotify ->Notify ()) return -6 ;
1491
- }
1492
- }
1508
+ Long64_t refreshFriendAddressesRet{};
1509
+ if (fFriends ) {
1510
+ refreshFriendAddressesRet = RefreshFriendAddresses (*this , *fTree , entry);
1511
+ } else if (fTree ->GetListOfFriends ()) {
1512
+ refreshFriendAddressesRet = RefreshFriendAddresses (*fTree , *fTree , treeReadEntry);
1493
1513
}
1514
+ if (refreshFriendAddressesRet == -6 )
1515
+ return refreshFriendAddressesRet;
1516
+
1494
1517
return treeReadEntry;
1495
1518
}
1496
1519
0 commit comments