### Tree

- Changed the MaxTreeSize default from 1.9 GBytes to 100 GBytes.
- Add new special functions in TTreeFormula (and hence TTree::Draw and TTree::Scan) to calculate the minimun and maximum with an entry:

  -     Min$(formula),Max$(formula):

    return the minimun/maximum (within one TTree entry) of the value of the elements of the formula given as a parameter.

  -     MinIf$(formula,condition),MaxIf$(formula,condition):

    return the minimum (maximum) (within one TTree entry) of the value of the elements of the formula given as a parameter if they match the condition. If not element match the condition, the result is zero. To avoid the the result is zero. To avoid the consequent peak a zero, use the pattern:

        tree->Draw("MinIf$(formula,condition)","condition");

    which will avoid calculation MinIf$ for the entries that have no match for the condition.
- Add support in TTreeFormula (and hence TTree::Draw and TTree::Scan) for the ternary condition operator ( cond ? if_expr : else_expr ).
- Significantly (by 2 order of magnitude) improved the performance of TTree::Draw calling C++ functions.
- Replace the function `TSelectorDraw::MakeIndex` and `TSelectorDraw::GetNameByIndex` with the function `TSelectorDraw::SplitNames.`
- Add a return value to SetBranchAddress, a return value greater or equal to zero indicate success, a negative value indicates failure (in both case, the address is still updated). Example:

      if (tree->SetBranchAddress(mybranch,&myvar) < 0) {
         cerr << "Something went wrong\n";
         return;
      }

  The possible return values are:
  - kMissingBranch (-5) : Missing branch
  - kInternalError (-4) : Internal error (could not find the type corresponding to a data type number.
  - kMissingCompiledCollectionProxy (-3) : Missing compiled collection proxy for a compiled collection.
  - kMismatch (-2) : Non-Class Pointer type given does not match the type expected by the branch.
  - kClassMismatch (-1) : Class Pointer type given does not match the type expected by the branch.
  - kMatch (0) : perfect match.
  - kMatchConversion (1) : match with (I/O) conversion.
  - kMatchConversionCollection (2) : match with (I/O) conversion of the content of a collection.
  - kMakeClass (3) : MakeClass mode so we can not check.
  - kVoidPtr (4) : void* passed so no check was made.
  - kNoCheck (5) : Underlying TBranch not yet available so no check was made.
- Insure that the TTreeCloner (fast merging) is able to also copy 'uninitialized' TStreamerInfo describing abstract classes.
- Repair several use case of splitting collection of pointers (especially when their split level is 1).
- Several run-time performance improvements.
- In TTree::Fill use fZipBytes instead of fTotBytes for deciding when to flush or autosave.
- Properly handle TTree aliases containing array indices.
- Fix the default sorting order of baskets when the TTree is an older in-memory TTree. Enhance the sort order to use the 'entry number' when the seek position are equal. Consequently the default sort order for an older in-memory TTree is now essentially kSortBasketsByEntry rather than kSortBasketsByBranch (old 'correct' sort order) or 'random' (the 'broken' sort order prior to this release).

#### IMPORTANT enhancement in TTree::Fill:

Slides from a recent seminar describing the main features of ROOT IO and Trees and the recent improvements described below are available at http://root.cern.ch/files/brun_lcgapp09.pptx or http://root.cern.ch/files/brun_lcgapp09.pdf .

The baskets are flushed and the Tree header saved at regular intervals (See AutoFlush and OptimizeBaskets)

When the amount of data written so far (fTotBytes) is greater than fAutoFlush (see SetAutoFlush) all the baskets are flushed to disk. This makes future reading faster as it guarantees that baskets belonging to nearby entries will be on the same disk region.

When the first call to flush the baskets happens, we also take this opportunity to optimize the baskets buffers. We also check if the number of bytes written is greater than fAutoSave (see SetAutoSave). In this case we also write the Tree header. This makes the Tree recoverable up to this point in case the program writing the Tree crashes.

Note that the user can also decide to call FlushBaskets and AutoSave in her event loop on the base of the number of events written instead of the number of bytes written.

#### New function TTree::OptimizeBaskets

    void TTree::OptimizeBaskets(Int_t maxMemory, Float_t minComp, Option_t *option)

This function may be called after having filled some entries in a Tree using the information in the existing branch buffers, it will reassign new branch buffer sizes to optimize time and memory.

The function computes the best values for branch buffer sizes such that the total buffer sizes is less than maxMemory and nearby entries written at the same time. In case the branch compression factor for the data written so far is less than compMin, the compression is disabled. if option ="d" an analysis report is printed.

This function may also be called on an existing Tree to figure out the best values given the information in the Tree header

       TFile f("myfile.root");
       TTree *T = (TTree*)f.Get("mytreename");
       T->Print();  //show the branch buffer sizes before optimization
       T->OptimizeBaskets(10000000,1,"d");
       T->Print();  //show the branch buffer sizes after optimization

#### New interface functions to customize the TreeCache

       virtual void  AddBranchToCache(const char *bname, Bool_t subbranches = kFALSE);
       virtual void  AddBranchToCache(TBranch *branch,   Bool_t subbranches = kFALSE);
       virtual void  PrintCacheStats(Option_t* option = "") const;
       virtual void  SetParallelUnzip(Bool_t opt=kTRUE);
       virtual void  SetCacheEntryRange(Long64_t first, Long64_t last);
       virtual void  SetCacheLearnEntries(Int_t n=10);
       virtual void  StopCacheLearningPhase();

#### New functionality AutoFlush (and changes to AutoSave)

Implement a new member fAutoFlush in TTree with its getter and setter:

    void TTree::SetAutoFlush(Long64_t autof)

The logic of the AutoFlush mechanism is optimized such that the TreeCache will read always up to the point where FlushBaskets has been called. This minimizes the number of cases where one has to seek backward when reading.
This function may be called at the start of a program to change the default value for fAutoFlush.

- CASE 1 : autof > 0
  autof is the number of consecutive entries after which TTree::Fill will flush all branch buffers to disk.
- CASE 2 : autof < 0
  When filling the Tree the branch buffers will be flushed to disk when more than autof bytes have been written to the file. At the first FlushBaskets TTree::Fill will replace fAutoFlush by the current value of fEntries. Calling this function with autof < 0 is interesting when it is hard to estimate the size of one entry. This value is also independent of the Tree. When calling SetAutoFlush with no arguments, the default value is -30000000, ie that the first AutoFlush will be done when 30 MBytes of data are written to the file.
- CASE 3 : autof = 0
  The AutoFlush mechanism is disabled.

Flushing the buffers at regular intervals optimize the location of consecutive entries on the disk.
Changed the default value of AutoSave from 10 to 30 MBytes.

#### New class TTreePerfStats

This new class is an important tool to measure the I/O performance of a Tree. It shows the locations in the file when reading a Tree. In particular it is easy to see the performance of the Tree Cache. The results can be:

- drawn in a canvas.
- printed on standard output.
- saved to a file for processing later.

           Example of use
     {
       TFile *f = TFile::Open("RelValMinBias-GEN-SIM-RECO.root");
       T = (TTree*)f->Get("Events");
       Long64_t nentries = T->GetEntries();
       T->SetCacheSize(10000000);
       T->AddBranchToCache("*");

       TTreePerfStats *ps= new TTreePerfStats("ioperf",T);

       for (Int_t i=0;i<nentries;i++) {
          T->GetEntry(i);
       }
       ps->SaveAs("atlas_perf.root");
     }

then, in a root interactive session, one can do:

        root > TFile f("atlas_perf.root");
        root > ioperf->Draw();
        root > ioperf->Print();

The Draw or Print functions print the following information:

       TreeCache = TTree cache size in MBytes
       N leaves  = Number of leaves in the TTree
       ReadTotal = Total number of zipped bytes read
       ReadUnZip = Total number of unzipped bytes read
       ReadCalls = Total number of disk reads
       ReadSize  = Average read size in KBytes
       Readahead = Readahead size in KBytes
       Readextra = Readahead overhead in percent
       Real Time = Real Time in seconds
       CPU  Time = CPU Time in seconds
       Disk Time = Real Time spent in pure raw disk IO
       Disk IO   = Raw disk IO speed in MBytes/second
       ReadUZRT  = Unzipped MBytes per RT second
       ReadUZCP  = Unipped MBytes per CP second
       ReadRT    = Zipped MBytes per RT second
       ReadCP    = Zipped MBytes per CP second

The Figure below shows the result for an original non optimized file when the Tree Cache is not used.

The Figure below shows the result for the above data file written with the new version of ROOT and when the Tree cache is activated.