// @(#)root/tree:$Id$
// Author: Rene Brun   19/08/2004

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// A branch containing and managing a TRefTable for TRef autoloading.   //
// It loads the TBranch containing a referenced object when requested   //
// by TRef::GetObject(), so the reference can be resolved. The          //
// information which branch to load is stored by TRefTable. Once a      //
// TBranch has read the TBranchRef's current entry it will not be told  //
// to re-read, in case the use has changed objects read from the        //
// branch.                                                              //
//                                                                      //
//                                                                      //
// *** LIMITATION ***                                                   //
// Note that this does NOT allow for autoloading of references spanning //
// different entries. The TBranchRef's current entry has to correspond  //
// to the entry of the TBranch containing the referenced object.        //
//                                                                      //
// The TRef cannot be stored in a top-level branch which is a           //
// TBranchObject for the auto-loading to work. E.g. you cannot store    //
// the TRefs in TObjArray, and create a top-level branch storing this   //
// TObjArray.                                                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TBranchRef.h"
#include "TTree.h"
#include "TBasket.h"
#include "TFile.h"
#include "TFriendElement.h"

ClassImp(TBranchRef)

//______________________________________________________________________________
TBranchRef::TBranchRef(): TBranch(), fRequestedEntry(-1), fRefTable(0)
{
   // Default constructor.

   fReadLeaves = (ReadLeaves_t)&TBranchRef::ReadLeavesImpl;
   fFillLeaves = (FillLeaves_t)&TBranchRef::FillLeavesImpl;
}


//______________________________________________________________________________
TBranchRef::TBranchRef(TTree *tree)
    : TBranch(), fRequestedEntry(-1), fRefTable(0)
{
   // Main constructor called by TTree::BranchRef.

   if (!tree) return;
   SetName("TRefTable");
   SetTitle("List of branch numbers with referenced objects");
   fRefTable = new TRefTable(this,100);

   fCompress       = 1;
   fBasketSize     = 32000;
   fAddress        = 0;
   fBasketBytes    = new Int_t[fMaxBaskets];
   fBasketEntry    = new Long64_t[fMaxBaskets];
   fBasketSeek     = new Long64_t[fMaxBaskets];

   for (Int_t i=0;i<fMaxBaskets;i++) {
      fBasketBytes[i] = 0;
      fBasketEntry[i] = 0;
      fBasketSeek[i]  = 0;
   }

   fTree       = tree;
   fMother     = this;
   fDirectory  = fTree->GetDirectory();
   fFileName   = "";
   fReadLeaves = (ReadLeaves_t)&TBranchRef::ReadLeavesImpl;
   fFillLeaves = (FillLeaves_t)&TBranchRef::FillLeavesImpl;
}


//______________________________________________________________________________
TBranchRef::~TBranchRef()
{
   // Typical destructor.

   delete fRefTable;
}

//______________________________________________________________________________
void TBranchRef::Clear(Option_t *option)
{
  // Clear entries in the TRefTable.

   if (fRefTable) fRefTable->Clear(option);
}

//______________________________________________________________________________
Int_t TBranchRef::Fill()
{
  // Fill the branch basket with the referenced objects parent numbers.

   Int_t nbytes = TBranch::Fill();
   return nbytes;
}

//______________________________________________________________________________
Bool_t TBranchRef::Notify()
{
   // This function is called by TRefTable::Notify, itself called by
   // TRef::GetObject.
   // The function reads the branch containing the object referenced
   // by the TRef.

   if (!fRefTable) fRefTable = new TRefTable(this,100);
   UInt_t uid = fRefTable->GetUID();
   TProcessID* context = fRefTable->GetUIDContext();
   if (fReadEntry != fRequestedEntry) {
      // Load the RefTable if we need to.
      GetEntry(fRequestedEntry);
   }
   TBranch *branch = (TBranch*)fRefTable->GetParent(uid, context);
   if (branch) {
      // don't re-read, the user might have changed some object
      if (branch->GetReadEntry() != fRequestedEntry)
         branch->GetEntry(fRequestedEntry);
   } else {
      //scan the TRefTable of possible friend Trees
      TList *friends = fTree->GetListOfFriends();
      if (!friends) return kTRUE;
      TObjLink *lnk = friends->FirstLink();
      while (lnk) {
         TFriendElement* elem = (TFriendElement*)lnk->GetObject();
         TTree *tree = elem->GetTree();
         TBranchRef *bref = tree->GetBranchRef();
         if (bref) {
            if (bref->GetReadEntry() != fRequestedEntry) {
               bref->GetEntry(fRequestedEntry);
            }
            branch = (TBranch*)bref->GetRefTable()->GetParent(uid, context);
            if (branch) {
               // don't re-read, the user might have changed some object
               if (branch->GetReadEntry() != fRequestedEntry)
                  branch->GetEntry(fRequestedEntry);
               return kTRUE;
            }
         }
         lnk = lnk->Next();
      }
   }
   return kTRUE;
}

//______________________________________________________________________________
void TBranchRef::Print(Option_t *option) const
{
  // Print the TRefTable branch.

   TBranch::Print(option);
}

//______________________________________________________________________________
void TBranchRef::ReadLeavesImpl(TBuffer &b)
{
   // This function called by TBranch::GetEntry overloads TBranch::ReadLeaves.

   if (!fRefTable) fRefTable = new TRefTable(this,100);
   fRefTable->ReadBuffer(b);
}

//______________________________________________________________________________
void TBranchRef::FillLeavesImpl(TBuffer &b)
{
   // This function called by TBranch::Fill overloads TBranch::FillLeaves.

   if (!fRefTable) fRefTable = new TRefTable(this,100);
   fRefTable->FillBuffer(b);
}


//______________________________________________________________________________
void TBranchRef::Reset(Option_t *option)
{
  //    Existing buffers are deleted
  //    Entries, max and min are reset
  //    TRefTable is cleared.

   TBranch::Reset(option);
   if (!fRefTable) fRefTable = new TRefTable(this,100);
   fRefTable->Reset();
}

//______________________________________________________________________________
void TBranchRef::ResetAfterMerge(TFileMergeInfo *info)
{
   // Reset a Branch after a Merge operation (drop data but keep customizations)
   // TRefTable is cleared.

   TBranch::ResetAfterMerge(info);
   if (!fRefTable) fRefTable = new TRefTable(this,100);
   fRefTable->Reset();
}

//______________________________________________________________________________
Int_t TBranchRef::SetParent(const TObject* object, Int_t branchID)
{
   // -- Set the current parent branch.
   //
   // This function is called by TBranchElement::GetEntry()
   // and TBranchElement::Fill() when reading or writing
   // branches that may contain referenced objects.
   //
   if (!fRefTable) {
      fRefTable = new TRefTable(this, 100);
   }
   TRefTable::SetRefTable(fRefTable);
   return fRefTable->SetParent(object, branchID);
}

 TBranchRef.cxx:1
 TBranchRef.cxx:2
 TBranchRef.cxx:3
 TBranchRef.cxx:4
 TBranchRef.cxx:5
 TBranchRef.cxx:6
 TBranchRef.cxx:7
 TBranchRef.cxx:8
 TBranchRef.cxx:9
 TBranchRef.cxx:10
 TBranchRef.cxx:11
 TBranchRef.cxx:12
 TBranchRef.cxx:13
 TBranchRef.cxx:14
 TBranchRef.cxx:15
 TBranchRef.cxx:16
 TBranchRef.cxx:17
 TBranchRef.cxx:18
 TBranchRef.cxx:19
 TBranchRef.cxx:20
 TBranchRef.cxx:21
 TBranchRef.cxx:22
 TBranchRef.cxx:23
 TBranchRef.cxx:24
 TBranchRef.cxx:25
 TBranchRef.cxx:26
 TBranchRef.cxx:27
 TBranchRef.cxx:28
 TBranchRef.cxx:29
 TBranchRef.cxx:30
 TBranchRef.cxx:31
 TBranchRef.cxx:32
 TBranchRef.cxx:33
 TBranchRef.cxx:34
 TBranchRef.cxx:35
 TBranchRef.cxx:36
 TBranchRef.cxx:37
 TBranchRef.cxx:38
 TBranchRef.cxx:39
 TBranchRef.cxx:40
 TBranchRef.cxx:41
 TBranchRef.cxx:42
 TBranchRef.cxx:43
 TBranchRef.cxx:44
 TBranchRef.cxx:45
 TBranchRef.cxx:46
 TBranchRef.cxx:47
 TBranchRef.cxx:48
 TBranchRef.cxx:49
 TBranchRef.cxx:50
 TBranchRef.cxx:51
 TBranchRef.cxx:52
 TBranchRef.cxx:53
 TBranchRef.cxx:54
 TBranchRef.cxx:55
 TBranchRef.cxx:56
 TBranchRef.cxx:57
 TBranchRef.cxx:58
 TBranchRef.cxx:59
 TBranchRef.cxx:60
 TBranchRef.cxx:61
 TBranchRef.cxx:62
 TBranchRef.cxx:63
 TBranchRef.cxx:64
 TBranchRef.cxx:65
 TBranchRef.cxx:66
 TBranchRef.cxx:67
 TBranchRef.cxx:68
 TBranchRef.cxx:69
 TBranchRef.cxx:70
 TBranchRef.cxx:71
 TBranchRef.cxx:72
 TBranchRef.cxx:73
 TBranchRef.cxx:74
 TBranchRef.cxx:75
 TBranchRef.cxx:76
 TBranchRef.cxx:77
 TBranchRef.cxx:78
 TBranchRef.cxx:79
 TBranchRef.cxx:80
 TBranchRef.cxx:81
 TBranchRef.cxx:82
 TBranchRef.cxx:83
 TBranchRef.cxx:84
 TBranchRef.cxx:85
 TBranchRef.cxx:86
 TBranchRef.cxx:87
 TBranchRef.cxx:88
 TBranchRef.cxx:89
 TBranchRef.cxx:90
 TBranchRef.cxx:91
 TBranchRef.cxx:92
 TBranchRef.cxx:93
 TBranchRef.cxx:94
 TBranchRef.cxx:95
 TBranchRef.cxx:96
 TBranchRef.cxx:97
 TBranchRef.cxx:98
 TBranchRef.cxx:99
 TBranchRef.cxx:100
 TBranchRef.cxx:101
 TBranchRef.cxx:102
 TBranchRef.cxx:103
 TBranchRef.cxx:104
 TBranchRef.cxx:105
 TBranchRef.cxx:106
 TBranchRef.cxx:107
 TBranchRef.cxx:108
 TBranchRef.cxx:109
 TBranchRef.cxx:110
 TBranchRef.cxx:111
 TBranchRef.cxx:112
 TBranchRef.cxx:113
 TBranchRef.cxx:114
 TBranchRef.cxx:115
 TBranchRef.cxx:116
 TBranchRef.cxx:117
 TBranchRef.cxx:118
 TBranchRef.cxx:119
 TBranchRef.cxx:120
 TBranchRef.cxx:121
 TBranchRef.cxx:122
 TBranchRef.cxx:123
 TBranchRef.cxx:124
 TBranchRef.cxx:125
 TBranchRef.cxx:126
 TBranchRef.cxx:127
 TBranchRef.cxx:128
 TBranchRef.cxx:129
 TBranchRef.cxx:130
 TBranchRef.cxx:131
 TBranchRef.cxx:132
 TBranchRef.cxx:133
 TBranchRef.cxx:134
 TBranchRef.cxx:135
 TBranchRef.cxx:136
 TBranchRef.cxx:137
 TBranchRef.cxx:138
 TBranchRef.cxx:139
 TBranchRef.cxx:140
 TBranchRef.cxx:141
 TBranchRef.cxx:142
 TBranchRef.cxx:143
 TBranchRef.cxx:144
 TBranchRef.cxx:145
 TBranchRef.cxx:146
 TBranchRef.cxx:147
 TBranchRef.cxx:148
 TBranchRef.cxx:149
 TBranchRef.cxx:150
 TBranchRef.cxx:151
 TBranchRef.cxx:152
 TBranchRef.cxx:153
 TBranchRef.cxx:154
 TBranchRef.cxx:155
 TBranchRef.cxx:156
 TBranchRef.cxx:157
 TBranchRef.cxx:158
 TBranchRef.cxx:159
 TBranchRef.cxx:160
 TBranchRef.cxx:161
 TBranchRef.cxx:162
 TBranchRef.cxx:163
 TBranchRef.cxx:164
 TBranchRef.cxx:165
 TBranchRef.cxx:166
 TBranchRef.cxx:167
 TBranchRef.cxx:168
 TBranchRef.cxx:169
 TBranchRef.cxx:170
 TBranchRef.cxx:171
 TBranchRef.cxx:172
 TBranchRef.cxx:173
 TBranchRef.cxx:174
 TBranchRef.cxx:175
 TBranchRef.cxx:176
 TBranchRef.cxx:177
 TBranchRef.cxx:178
 TBranchRef.cxx:179
 TBranchRef.cxx:180
 TBranchRef.cxx:181
 TBranchRef.cxx:182
 TBranchRef.cxx:183
 TBranchRef.cxx:184
 TBranchRef.cxx:185
 TBranchRef.cxx:186
 TBranchRef.cxx:187
 TBranchRef.cxx:188
 TBranchRef.cxx:189
 TBranchRef.cxx:190
 TBranchRef.cxx:191
 TBranchRef.cxx:192
 TBranchRef.cxx:193
 TBranchRef.cxx:194
 TBranchRef.cxx:195
 TBranchRef.cxx:196
 TBranchRef.cxx:197
 TBranchRef.cxx:198
 TBranchRef.cxx:199
 TBranchRef.cxx:200
 TBranchRef.cxx:201
 TBranchRef.cxx:202
 TBranchRef.cxx:203
 TBranchRef.cxx:204
 TBranchRef.cxx:205
 TBranchRef.cxx:206
 TBranchRef.cxx:207
 TBranchRef.cxx:208
 TBranchRef.cxx:209
 TBranchRef.cxx:210
 TBranchRef.cxx:211
 TBranchRef.cxx:212
 TBranchRef.cxx:213
 TBranchRef.cxx:214
 TBranchRef.cxx:215
 TBranchRef.cxx:216
 TBranchRef.cxx:217
 TBranchRef.cxx:218
 TBranchRef.cxx:219
 TBranchRef.cxx:220
 TBranchRef.cxx:221
 TBranchRef.cxx:222
 TBranchRef.cxx:223