TFree.cxx

Go to the documentation of this file.
00001 // @(#)root/io:$Id: TFree.cxx 37531 2010-12-10 20:38:06Z pcanal $
00002 // Author: Rene Brun   28/12/94
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "TFree.h"
00013 #include "TList.h"
00014 #include "TFile.h"
00015 #include "Bytes.h"
00016 #include "Riostream.h"
00017 
00018 ClassImp(TFree)
00019 
00020 //______________________________________________________________________________
00021 //
00022 // Service class for TFile.
00023 // Each file has a linked list of free segments. Each free segment
00024 // is described by its firts and last address.
00025 // When an object is written to a file via TObject::Write, a new Key (see TKey)
00026 // is created. The first free segment big enough to accomodate the object
00027 // is used.
00028 // If the object size has a length corresponding to the size of the free segment,
00029 // the free segment is deleted from the list of free segments.
00030 // When an object is deleted from a file, a new TFree object is generated.
00031 // If the deleted object is contiguous to an already deleted object, the free
00032 // segments are merged in one single segment.
00033 //
00034 
00035 //______________________________________________________________________________
00036 TFree::TFree()
00037 {
00038    // TFree default constructor.
00039 
00040    fFirst = fLast = 0;
00041 }
00042 
00043 //______________________________________________________________________________
00044 TFree::TFree(TList *lfree, Long64_t first, Long64_t last)
00045 {
00046    // Constructor for a FREE segment.
00047 
00048    fFirst = first;
00049    fLast  = last;
00050    lfree->Add(this);
00051 }
00052 
00053 //______________________________________________________________________________
00054 TFree *TFree::AddFree(TList *lfree, Long64_t first, Long64_t last)
00055 {
00056 // Add a new free segment to the list of free segments.
00057 //
00058 //  If last just preceedes an existing free segment, then first becomes
00059 //     the new starting location of the free segment.
00060 //  if first just follows an existing free segment, then last becomes
00061 //     the new ending location of the free segment.
00062 //  if first just follows an existing free segment AND last just preceedes
00063 //     an existing free segment, these two segments are merged into
00064 //     one single segment.
00065 //
00066 
00067    TFree *idcur = this;
00068    while (idcur) {
00069       Long64_t curfirst = idcur->GetFirst();
00070       Long64_t curlast  = idcur->GetLast();
00071       if (curlast == first-1) {
00072          idcur->SetLast(last);
00073          TFree *idnext = (TFree*)lfree->After(idcur);
00074          if (idnext == 0) return idcur;
00075          if (idnext->GetFirst() > last+1) return idcur;
00076          idcur->SetLast( idnext->GetLast() );
00077          lfree->Remove(idnext);
00078          delete idnext;
00079          return idcur;
00080       }
00081       if (curfirst == last+1) {
00082          idcur->SetFirst(first);
00083          return idcur;
00084       }
00085       if (first < curfirst) {
00086          TFree * newfree = new TFree();
00087          newfree->SetFirst(first);
00088          newfree->SetLast(last);
00089          lfree->AddBefore(idcur, newfree);
00090          return newfree;
00091       }
00092       idcur = (TFree*)lfree->After(idcur);
00093    }
00094    return 0;
00095 }
00096 
00097 //______________________________________________________________________________
00098 TFree::~TFree()
00099 {
00100    // TFree Destructor.
00101 
00102 }
00103 
00104 //______________________________________________________________________________
00105 void TFree::FillBuffer(char *&buffer)
00106 {
00107    // Encode FREE structure into output buffer.
00108 
00109    Version_t version = TFree::Class_Version();
00110    if (fLast > TFile::kStartBigFile) version += 1000;
00111    tobuf(buffer, version);
00112 //printf("TFree::fillBuffer, fFirst=%lld, fLast=%lld, version=%d\n",fFirst,fLast,version);
00113    if (version > 1000) {
00114       tobuf(buffer, fFirst);
00115       tobuf(buffer, fLast);
00116    } else {
00117       tobuf(buffer, (Int_t)fFirst);
00118       tobuf(buffer, (Int_t)fLast);
00119    }
00120 }
00121 
00122 //______________________________________________________________________________
00123 TFree *TFree::GetBestFree(TList *lfree, Int_t nbytes)
00124 {
00125    // Return the best free segment where to store nbytes.
00126    
00127    TFree *idcur = this;
00128    if (idcur == 0) return 0;
00129    TFree *idcur1 = 0;
00130    do {
00131       Long64_t nleft = Long64_t(idcur->fLast - idcur->fFirst +1);
00132       if (nleft == nbytes) {
00133          // Found an exact match
00134          return idcur;
00135       }
00136       if(nleft > (Long64_t)(nbytes+3)) {
00137          if (idcur1 == 0) {
00138             idcur1=idcur;
00139          }
00140       }
00141       idcur = (TFree*)lfree->After(idcur);
00142    } while (idcur !=0);
00143    
00144    // return first segment >nbytes
00145    if (idcur1) return idcur1;                                   
00146 
00147    //try big file
00148    idcur = (TFree*)lfree->Last();
00149    Long64_t last = idcur->fLast+1000000000;
00150    idcur->SetLast(last);
00151    return idcur;
00152 }
00153 
00154 //______________________________________________________________________________
00155 void TFree::ls(Option_t *) const
00156 {
00157    // List free segment contents.
00158 
00159    cout <<"Free Segment: "<<fFirst<<"\t"<<fLast<<endl;
00160 }
00161 
00162 //______________________________________________________________________________
00163 void TFree::ReadBuffer(char *&buffer)
00164 {
00165    // Decode one FREE structure from input buffer
00166 
00167    Version_t version;
00168    frombuf(buffer, &version);
00169    if (version > 1000) {
00170       frombuf(buffer, &fFirst);
00171       frombuf(buffer, &fLast);
00172    } else {
00173       Int_t first,last;
00174       frombuf(buffer, &first);  fFirst = (Long64_t)first;
00175       frombuf(buffer, &last);   fLast  = (Long64_t)last;
00176    }
00177 }
00178 
00179 //______________________________________________________________________________
00180 Int_t TFree::Sizeof() const
00181 {
00182    // return number of bytes occupied by this TFree on permanent storage
00183 
00184    if (fLast > TFile::kStartBigFile) return 18;
00185    else                              return 10;
00186 }
00187    

Generated on Tue Jul 5 14:30:17 2011 for ROOT_528-00b_version by  doxygen 1.5.1