TFileCacheWrite.cxx

Go to the documentation of this file.
00001 // @(#)root/io:$Id: TFileCacheWrite.cxx 23122 2008-04-10 14:56:30Z rdm $
00002 // Author: Rene Brun   18/05/2006
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 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TFileCacheWrite : a cache when writing files over the network        //
00015 //                                                                      //
00016 // A caching system to speed up network I/O, i.e. when there is         //
00017 // no operating system caching support (like the buffer cache for       //
00018 // local disk I/O). The cache makes sure that every I/O is done with    //
00019 // a (large) fixed length buffer thereby avoiding many small I/O's.     //
00020 // Currently the write cache system is used by the classes TNetFile,    //
00021 // TXNetFile and TWebFile (via TFile::WriteBuffers()).                  //
00022 //                                                                      //
00023 // The write cache is automatically created when writing a remote file  //
00024 // (created in TFile::Open()).                                          //
00025 //                                                                      //
00026 //////////////////////////////////////////////////////////////////////////
00027 
00028 
00029 #include "TFile.h"
00030 #include "TFileCacheWrite.h"
00031 
00032 ClassImp(TFileCacheWrite)
00033 
00034 //______________________________________________________________________________
00035 TFileCacheWrite::TFileCacheWrite() : TObject()
00036 {
00037    // Default Constructor.
00038 
00039    fBufferSize  = 0;
00040    fNtot        = 0;
00041    fSeekStart   = 0;
00042    fFile        = 0;
00043    fBuffer      = 0;
00044    fRecursive   = kFALSE;
00045 }
00046 
00047 //_____________________________________________________________________________
00048 TFileCacheWrite::TFileCacheWrite(TFile *file, Int_t buffersize)
00049            : TObject()
00050 {
00051    // Creates a TFileCacheWrite data structure.
00052    // The write cache will be connected to file.
00053    // The size of the cache will be buffersize,
00054    // if buffersize < 10000 a default size of 512 Kbytes is used
00055 
00056    if (buffersize < 10000) buffersize = 512000;
00057    fBufferSize  = buffersize;
00058    fSeekStart   = 0;
00059    fNtot        = 0;
00060    fFile        = file;
00061    fRecursive   = kFALSE;
00062    fBuffer      = new char[fBufferSize];
00063    if (file) file->SetCacheWrite(this);
00064    if (gDebug > 0) Info("TFileCacheWrite","Creating a write cache with buffersize=%d bytes",buffersize);
00065 }
00066 
00067 //_____________________________________________________________________________
00068 TFileCacheWrite::~TFileCacheWrite()
00069 {
00070    // Destructor.
00071 
00072    delete [] fBuffer;
00073 }
00074 
00075 //_____________________________________________________________________________
00076 Bool_t TFileCacheWrite::Flush()
00077 {
00078    // Flush the current write buffer to the file.
00079    // Returns kTRUE in case of error.
00080 
00081    if (!fNtot) return kFALSE;
00082    fFile->Seek(fSeekStart);
00083    //printf("Flushing buffer at fSeekStart=%lld, fNtot=%d\n",fSeekStart,fNtot);
00084    fRecursive = kTRUE;
00085    Bool_t status = fFile->WriteBuffer(fBuffer, fNtot);
00086    fRecursive = kFALSE;
00087    fNtot = 0;
00088    return status;
00089 }
00090 
00091 //_____________________________________________________________________________
00092 void TFileCacheWrite::Print(Option_t *option) const
00093 {
00094    // Print class internal structure.
00095 
00096    TString opt = option;
00097    printf("Write cache for file %s\n",fFile->GetName());
00098    printf("Size of write cache: %d bytes to be written at %lld\n",fNtot,fSeekStart);
00099    opt.ToLower();
00100 }
00101 
00102 //_____________________________________________________________________________
00103 Int_t TFileCacheWrite::ReadBuffer(char *buf, Long64_t pos, Int_t len)
00104 {
00105    // Called by the read cache to check if the requested data is not
00106    // in the write cache buffer.
00107    //        Returns -1 if data not in write cache,
00108    //        0 otherwise.
00109 
00110    if (pos < fSeekStart || pos+len > fSeekStart+fNtot) return -1;
00111    memcpy(buf,fBuffer+pos-fSeekStart,len);
00112    return 0;
00113 }
00114 
00115 //_____________________________________________________________________________
00116 Int_t TFileCacheWrite::WriteBuffer(const char *buf, Long64_t pos, Int_t len)
00117 {
00118    // Write buffer at position pos in the write buffer.
00119    // The function returns 1 if the buffer has been successfully entered into the write buffer.
00120    // The function returns 0 in case WriteBuffer() was recusively called via Flush().
00121    // The function returns -1 in case of error.
00122 
00123    if (fRecursive) return 0;
00124 
00125    //printf("TFileCacheWrite::WriteBuffer, pos=%lld, len=%d, fSeekStart=%lld, fNtot=%d\n",pos,len,fSeekStart,fNtot);
00126 
00127    if (fSeekStart + fNtot != pos) {
00128       //we must flush the current cache
00129       if (Flush()) return -1; //failure
00130    }
00131    if (fNtot + len >= fBufferSize) {
00132       if (Flush()) return -1; //failure
00133       if (len >= fBufferSize) {
00134          //buffer larger than the cache itself: direct write to file
00135          fRecursive = kTRUE;
00136          if (fFile->WriteBuffer(buf,len)) return -1;  // failure
00137          fRecursive = kFALSE;
00138          return 1;
00139       }
00140    }
00141    if (!fNtot) fSeekStart = pos;
00142    memcpy(fBuffer+fNtot,buf,len);
00143    fNtot += len;
00144 
00145    return 1;
00146 }
00147 
00148 //_____________________________________________________________________________
00149 void TFileCacheWrite::SetFile(TFile *file)
00150 {
00151    // Set the file using this cache.
00152    // Any write not yet flushed will be lost.
00153 
00154    fFile = file;
00155 }

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