1    	// @(#)root/io:$Id$
2    	// Author: Rene Brun   28/11/94
3    	
4    	/*************************************************************************
5    	 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
6    	 * All rights reserved.                                                  *
7    	 *                                                                       *
8    	 * For the licensing terms see $ROOTSYS/LICENSE.                         *
9    	 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
10   	 *************************************************************************/
11   	
12   	#ifndef ROOT_TFile
13   	#define ROOT_TFile
14   	
15   	
16   	//////////////////////////////////////////////////////////////////////////
17   	//                                                                      //
18   	// TFile                                                                //
19   	//                                                                      //
20   	// ROOT file.                                                           //
21   	//                                                                      //
22   	//////////////////////////////////////////////////////////////////////////
23   	
24   	#if __cplusplus >= 201103L
25   	#include <atomic>
26   	#endif
27   	#ifndef ROOT_TDirectoryFile
28   	#include "TDirectoryFile.h"
29   	#endif
30   	#ifndef ROOT_TMap
31   	#include "TMap.h"
32   	#endif
33   	#ifndef ROOT_TUrl
34   	#include "TUrl.h"
35   	#endif
36   	
37   	class TFree;
38   	class TArrayC;
39   	class TArchiveFile;
40   	class TFileOpenHandle;
41   	class TFileCacheRead;
42   	class TFileCacheWrite;
43   	class TProcessID;
44   	class TStopwatch;
45   	class TFilePrefetch;
46   	
47   	class TFile : public TDirectoryFile {
48   	  friend class TDirectoryFile;
49   	  friend class TFilePrefetch;
50   	
51   	public:
52   	   // Asynchronous open request status
53   	   enum EAsyncOpenStatus { kAOSNotAsync = -1,  kAOSFailure = 0,
54   	                           kAOSInProgress = 1, kAOSSuccess = 2 };
55   	   // Open timeout constants
56   	   enum EOpenTimeOut { kInstantTimeout = 0, kEternalTimeout = 999999999 };
57   	
58   	   // TTreeCache flushing semantics
59   	   enum ECacheAction { kDisconnect = 0, kDoNotDisconnect = 1 };
60   	
61   	protected:
62   	   Double_t         fSumBuffer;      //Sum of buffer sizes of objects written so far
63   	   Double_t         fSum2Buffer;     //Sum of squares of buffer sizes of objects written so far
64   	   Long64_t         fBytesWrite;     //Number of bytes written to this file
65   	   Long64_t         fBytesRead;      //Number of bytes read from this file
66   	   Long64_t         fBytesReadExtra; //Number of extra bytes (overhead) read by the readahead buffer
67   	   Long64_t         fBEGIN;          //First used byte in file
68   	   Long64_t         fEND;            //Last used byte in file
69   	   Long64_t         fSeekFree;       //Location on disk of free segments structure
70   	   Long64_t         fSeekInfo;       //Location on disk of StreamerInfo record
71   	   Int_t            fD;              //File descriptor
72   	   Int_t            fVersion;        //File format version
73   	   Int_t            fCompress;       //Compression level and algorithm
74   	   Int_t            fNbytesFree;     //Number of bytes for free segments structure
75   	   Int_t            fNbytesInfo;     //Number of bytes for StreamerInfo record
76   	   Int_t            fWritten;        //Number of objects written so far
77   	   Int_t            fNProcessIDs;    //Number of TProcessID written to this file
78   	   Int_t            fReadCalls;      //Number of read calls ( not counting the cache calls )
79   	   TString          fRealName;       //Effective real file name (not original url)
80   	   TString          fOption;         //File options
81   	   Char_t           fUnits;          //Number of bytes for file pointers
82   	   TList           *fFree;           //Free segments linked list table
83   	   TArrayC         *fClassIndex;     //!Index of TStreamerInfo classes written to this file
84   	   TObjArray       *fProcessIDs;     //!Array of pointers to TProcessIDs
85   	   Long64_t         fOffset;         //!Seek offset cache
86   	   TArchiveFile    *fArchive;        //!Archive file from which we read this file
87   	   TFileCacheRead  *fCacheRead;      //!Pointer to the read cache (if any)
88   	   TMap            *fCacheReadMap;   //!Pointer to the read cache (if any)
89   	   TFileCacheWrite *fCacheWrite;     //!Pointer to the write cache (if any)
90   	   Long64_t         fArchiveOffset;  //!Offset at which file starts in archive
91   	   Bool_t           fIsArchive;      //!True if this is a pure archive file
92   	   Bool_t           fNoAnchorInName; //!True if we don't want to force the anchor to be appended to the file name
93   	   Bool_t           fIsRootFile;     //!True is this is a ROOT file, raw file otherwise
94   	   Bool_t           fInitDone;       //!True if the file has been initialized
95   	   Bool_t           fMustFlush;      //!True if the file buffers must be flushed
96   	   TFileOpenHandle *fAsyncHandle;    //!For proper automatic cleanup
97   	   EAsyncOpenStatus fAsyncOpenStatus; //!Status of an asynchronous open request
98   	   TUrl             fUrl;            //!URL of file
99   	
100  	   TList           *fInfoCache;      //!Cached list of the streamer infos in this file
101  	   TList           *fOpenPhases;     //!Time info about open phases
102  	
103  	   static TList    *fgAsyncOpenRequests; //List of handles for pending open requests
104  	
105  	   static TString   fgCacheFileDir;          //Directory where to locally stage files
106  	   static Bool_t    fgCacheFileDisconnected; //Indicates, we trust in the files in the cache dir without stat on the cached file
107  	   static Bool_t    fgCacheFileForce;        //Indicates, to force all READ to CACHEREAD
108  	   static UInt_t    fgOpenTimeout;           //Timeout for open operations in ms  - 0 corresponds to blocking i/o
109  	   static Bool_t    fgOnlyStaged ;           //Before the file is opened, it is checked, that the file is staged, if not, the open fails
110  	
111  	#if __cplusplus >= 201103L
112  	   static std::atomic<Long64_t>  fgBytesWrite;            //Number of bytes written by all TFile objects
113  	   static std::atomic<Long64_t>  fgBytesRead;             //Number of bytes read by all TFile objects
114  	   static std::atomic<Long64_t>  fgFileCounter;           //Counter for all opened files
115  	   static std::atomic<Int_t>     fgReadCalls;             //Number of bytes read from all TFile objects
116  	#else
117  	   static Long64_t  fgBytesWrite;            //Number of bytes written by all TFile objects
118  	   static Long64_t  fgBytesRead;             //Number of bytes read by all TFile objects
119  	   static Long64_t  fgFileCounter;           //Counter for all opened files
120  	   static Int_t     fgReadCalls;             //Number of bytes read from all TFile objects
121  	#endif
122  	   static Int_t     fgReadaheadSize;         //Readahead buffer size
123  	   static Bool_t    fgReadInfo;              //if true (default) ReadStreamerInfo is called when opening a file
124  	   virtual EAsyncOpenStatus GetAsyncOpenStatus() { return fAsyncOpenStatus; }
125  	   virtual void  Init(Bool_t create);
126  	   Bool_t        FlushWriteCache();
127  	   Int_t         ReadBufferViaCache(char *buf, Int_t len);
128  	   Int_t         WriteBufferViaCache(const char *buf, Int_t len);
129  	
130  	   // Creating projects
131  	   Int_t         MakeProjectParMake(const char *packname, const char *filename);
132  	   Int_t         MakeProjectParProofInf(const char *packname, const char *proofinfdir);
133  	
134  	   // Interface to basic system I/O routines
135  	   virtual Int_t    SysOpen(const char *pathname, Int_t flags, UInt_t mode);
136  	   virtual Int_t    SysClose(Int_t fd);
137  	   virtual Int_t    SysRead(Int_t fd, void *buf, Int_t len);
138  	   virtual Int_t    SysWrite(Int_t fd, const void *buf, Int_t len);
139  	   virtual Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence);
140  	   virtual Int_t    SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime);
141  	   virtual Int_t    SysSync(Int_t fd);
142  	
143  	   // Interface for text-based TDirectory I/O
144  	   virtual Long64_t DirCreateEntry(TDirectory*) { return 0; }
145  	   virtual Int_t    DirReadKeys(TDirectory*) { return 0; }
146  	   virtual void     DirWriteKeys(TDirectory*) {}
147  	   virtual void     DirWriteHeader(TDirectory*) {}
148  	
149  	private:
150  	   TFile(const TFile &);            //Files cannot be copied
151  	   void operator=(const TFile &);
152  	
153  	   static void   CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch);
154  	   static TFile *OpenFromCache(const char *name, Option_t * = "",
155  	                               const char *ftitle = "", Int_t compress = 1,
156  	                               Int_t netopt = 0);
157  	
158  	public:
159  	   // TFile status bits
160  	   enum EStatusBits {
161  	      kRecovered     = BIT(10),
162  	      kHasReferences = BIT(11),
163  	      kDevNull       = BIT(12),
164  	      kWriteError    = BIT(14), // BIT(13) is taken up by TObject
165  	      kBinaryFile    = BIT(15),
166  	      kRedirected    = BIT(16)
167  	   };
168  	   enum ERelativeTo { kBeg = 0, kCur = 1, kEnd = 2 };
169  	   enum { kStartBigFile  = 2000000000 };
170  	   // File type
171  	   enum EFileType { kDefault = 0, kLocal = 1, kNet = 2, kWeb = 3, kFile = 4, kMerge = 5};
172  	
173  	   TFile();
174  	   TFile(const char *fname, Option_t *option="", const char *ftitle="", Int_t compress=1);
175  	   virtual ~TFile();
176  	   virtual void        Close(Option_t *option=""); // *MENU*
177  	   virtual void        Copy(TObject &) const { MayNotUse("Copy(TObject &)"); }
178  	   virtual Bool_t      Cp(const char *dst, Bool_t progressbar = kTRUE,UInt_t buffersize = 1000000);
179  	   virtual TKey*       CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize);
180  	   virtual TKey*       CreateKey(TDirectory* mother, const void* obj, const TClass* cl,
181  	                                 const char* name, Int_t bufsize);
182  	   static TFile      *&CurrentFile(); // Return the current file for this thread.
183  	   virtual void        Delete(const char *namecycle="");
184  	   virtual void        Draw(Option_t *option="");
185  	   virtual void        DrawMap(const char *keys="*",Option_t *option=""); // *MENU*
186  	   virtual void        FillBuffer(char *&buffer);
187  	   virtual void        Flush();
188  	   TArchiveFile       *GetArchive() const { return fArchive; }
189  	   Long64_t            GetArchiveOffset() const { return fArchiveOffset; }
190  	   Int_t               GetBestBuffer() const;
191  	   virtual Int_t       GetBytesToPrefetch() const;
192  	   TFileCacheRead     *GetCacheRead(TObject* tree = 0) const;
193  	   TFileCacheWrite    *GetCacheWrite() const;
194  	   TArrayC            *GetClassIndex() const { return fClassIndex; }
195  	   Int_t               GetCompressionAlgorithm() const;
196  	   Int_t               GetCompressionLevel() const;
197  	   Int_t               GetCompressionSettings() const;
198  	   Float_t             GetCompressionFactor();
199  	   virtual Long64_t    GetEND() const { return fEND; }
200  	   virtual Int_t       GetErrno() const;
201  	   virtual void        ResetErrno() const;
202  	   Int_t               GetFd() const { return fD; }
203  	   virtual const TUrl *GetEndpointUrl() const { return &fUrl; }
204  	   TObjArray          *GetListOfProcessIDs() const {return fProcessIDs;}
205  	   TList              *GetListOfFree() const { return fFree; }
206  	   virtual Int_t       GetNfree() const { return fFree->GetSize(); }
207  	   virtual Int_t       GetNProcessIDs() const { return fNProcessIDs; }
208  	   Option_t           *GetOption() const { return fOption.Data(); }
209  	   virtual Long64_t    GetBytesRead() const { return fBytesRead; }
210  	   virtual Long64_t    GetBytesReadExtra() const { return fBytesReadExtra; }
211  	   virtual Long64_t    GetBytesWritten() const;
212  	   virtual Int_t       GetReadCalls() const { return fReadCalls; }
213  	   Int_t               GetVersion() const { return fVersion; }
214  	   Int_t               GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes,
215  	                                       Int_t &nbytes, Int_t &objlen, Int_t &keylen);
216  	   virtual Int_t       GetNbytesInfo() const {return fNbytesInfo;}
217  	   virtual Int_t       GetNbytesFree() const {return fNbytesFree;}
218  	   virtual TString     GetNewUrl() { return ""; }
219  	   Long64_t            GetRelOffset() const { return fOffset - fArchiveOffset; }
220  	   virtual Long64_t    GetSeekFree() const {return fSeekFree;}
221  	   virtual Long64_t    GetSeekInfo() const {return fSeekInfo;}
222  	   virtual Long64_t    GetSize() const;
223  	   virtual TList      *GetStreamerInfoList();
224  	   const   TList      *GetStreamerInfoCache();
225  	   virtual void        IncrementProcessIDs() { fNProcessIDs++; }
226  	   virtual Bool_t      IsArchive() const { return fIsArchive; }
227  	           Bool_t      IsBinary() const { return TestBit(kBinaryFile); }
228  	           Bool_t      IsRaw() const { return !fIsRootFile; }
229  	   virtual Bool_t      IsOpen() const;
230  	   virtual void        ls(Option_t *option="") const;
231  	   virtual void        MakeFree(Long64_t first, Long64_t last);
232  	   virtual void        MakeProject(const char *dirname, const char *classes="*",
233  	                                   Option_t *option="new"); // *MENU*
234  	   virtual void        Map(); // *MENU*
235  	   virtual Bool_t      Matches(const char *name);
236  	   virtual Bool_t      MustFlush() const {return fMustFlush;}
237  	   virtual void        Paint(Option_t *option="");
238  	   virtual void        Print(Option_t *option="") const;
239  	   virtual Bool_t      ReadBufferAsync(Long64_t offs, Int_t len);
240  	   virtual Bool_t      ReadBuffer(char *buf, Int_t len);
241  	   virtual Bool_t      ReadBuffer(char *buf, Long64_t pos, Int_t len);
242  	   virtual Bool_t      ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf);
243  	   virtual void        ReadFree();
244  	   virtual TProcessID *ReadProcessID(UShort_t pidf);
245  	   virtual void        ReadStreamerInfo();
246  	   virtual Int_t       Recover();
247  	   virtual Int_t       ReOpen(Option_t *mode);
248  	   virtual void        Seek(Long64_t offset, ERelativeTo pos = kBeg);
249  	   virtual void        SetCacheRead(TFileCacheRead *cache, TObject* tree = 0, ECacheAction action = kDisconnect);
250  	   virtual void        SetCacheWrite(TFileCacheWrite *cache);
251  	   virtual void        SetCompressionAlgorithm(Int_t algorithm=0);
252  	   virtual void        SetCompressionLevel(Int_t level=1);
253  	   virtual void        SetCompressionSettings(Int_t settings=1);
254  	   virtual void        SetEND(Long64_t last) { fEND = last; }
255  	   virtual void        SetOffset(Long64_t offset, ERelativeTo pos = kBeg);
256  	   virtual void        SetOption(Option_t *option=">") { fOption = option; }
257  	   virtual void        SetReadCalls(Int_t readcalls = 0) { fReadCalls = readcalls; }
258  	   virtual void        ShowStreamerInfo();
259  	   virtual Int_t       Sizeof() const;
260  	   void                SumBuffer(Int_t bufsize);
261  	   virtual void        UseCache(Int_t maxCacheSize = 10, Int_t pageSize = 0);
262  	   virtual Bool_t      WriteBuffer(const char *buf, Int_t len);
263  	   virtual Int_t       Write(const char *name=0, Int_t opt=0, Int_t bufsiz=0);
264  	   virtual Int_t       Write(const char *name=0, Int_t opt=0, Int_t bufsiz=0) const;
265  	   virtual void        WriteFree();
266  	   virtual void        WriteHeader();
267  	   virtual UShort_t    WriteProcessID(TProcessID *pid);
268  	   virtual void        WriteStreamerInfo();
269  	
270  	   static TFileOpenHandle
271  	                      *AsyncOpen(const char *name, Option_t *option = "",
272  	                                 const char *ftitle = "", Int_t compress = 1,
273  	                                 Int_t netopt = 0);
274  	   static TFile       *Open(const char *name, Option_t *option = "",
275  	                            const char *ftitle = "", Int_t compress = 1,
276  	                            Int_t netopt = 0);
277  	   static TFile       *Open(TFileOpenHandle *handle);
278  	
279  	   static EFileType    GetType(const char *name, Option_t *option = "", TString *prefix = 0);
280  	
281  	   static EAsyncOpenStatus GetAsyncOpenStatus(const char *name);
282  	   static EAsyncOpenStatus GetAsyncOpenStatus(TFileOpenHandle *handle);
283  	   static const TUrl  *GetEndpointUrl(const char *name);
284  	
285  	   static Long64_t     GetFileBytesRead();
286  	   static Long64_t     GetFileBytesWritten();
287  	   static Int_t        GetFileReadCalls();
288  	   static Int_t        GetReadaheadSize();
289  	
290  	   static void         SetFileBytesRead(Long64_t bytes = 0);
291  	   static void         SetFileBytesWritten(Long64_t bytes = 0);
292  	   static void         SetFileReadCalls(Int_t readcalls = 0);
293  	   static void         SetReadaheadSize(Int_t bufsize = 256000);
294  	   static void         SetReadStreamerInfo(Bool_t readinfo=kTRUE);
295  	
296  	   static Long64_t     GetFileCounter();
297  	   static void         IncrementFileCounter();
298  	
299  	   static Bool_t       SetCacheFileDir(const char *cacheDir, Bool_t operateDisconnected = kTRUE,
300  	                                       Bool_t forceCacheread = kFALSE);
301  	   static const char  *GetCacheFileDir();
302  	   static Bool_t       ShrinkCacheFileDir(Long64_t shrinkSize, Long_t cleanupInteval = 0);
303  	   static Bool_t       Cp(const char *src, const char *dst, Bool_t progressbar = kTRUE,
304  	                          UInt_t buffersize = 1000000);
305  	
306  	   static UInt_t       SetOpenTimeout(UInt_t timeout);  // in ms
307  	   static UInt_t       GetOpenTimeout(); // in ms
308  	   static Bool_t       SetOnlyStaged(Bool_t onlystaged);
309  	   static Bool_t       GetOnlyStaged();
310  	
311  	   ClassDef(TFile,8)  //ROOT file
312  	};
313  	
314  	#ifndef __CINT__
315  	#define gFile (TFile::CurrentFile())
316  	
317  	#elif defined(__MAKECINT__)
318  	// To properly handle the use of gFile in header files (in static declarations)
319  	R__EXTERN TFile   *gFile;
320  	#endif
321  	
322  	//
323  	// Class holding info about the file being opened
324  	//
325  	class TFileOpenHandle : public TNamed {
326  	
327  	friend class TFile;
328  	friend class TAlienFile;
329  	
330  	private:
331  	   TString  fOpt;        // Options
332  	   Int_t    fCompress;   // Compression level and algorithm
333  	   Int_t    fNetOpt;     // Network options
334  	   TFile   *fFile;       // TFile instance of the file being opened
335  	
336  	   TFileOpenHandle(TFile *f) : TNamed("",""), fOpt(""), fCompress(1),
337  	                               fNetOpt(0), fFile(f) { }
338  	   TFileOpenHandle(const char *n, const char *o, const char *t, Int_t cmp,
339  	                   Int_t no) : TNamed(n,t), fOpt(o), fCompress(cmp),
340  	                               fNetOpt(no), fFile(0) { }
341  	   TFileOpenHandle(const TFileOpenHandle&);
342  	   TFileOpenHandle& operator=(const TFileOpenHandle&);
343  	
344  	   TFile      *GetFile() const { return fFile; }
345  	
346  	public:
347  	   ~TFileOpenHandle() { }
348  	
349  	   Bool_t      Matches(const char *name);
350  	
351  	   const char *GetOpt() const { return fOpt; }
352  	   Int_t       GetCompress() const { return fCompress; }
353  	   Int_t       GetNetOpt() const { return fNetOpt; }
354  	};
355  	
356  	//______________________________________________________________________________
357  	inline Int_t TFile::GetCompressionAlgorithm() const
358  	{
359  	   return (fCompress < 0) ? -1 : fCompress / 100;
360  	}
361  	
362  	//______________________________________________________________________________
363  	inline Int_t TFile::GetCompressionLevel() const
364  	{
365  	   return (fCompress < 0) ? -1 : fCompress % 100;
366  	}
367  	
368  	//______________________________________________________________________________
369  	inline Int_t TFile::GetCompressionSettings() const
370  	{
371  	   return (fCompress < 0) ? -1 : fCompress;
372  	}
373  	
374  	#endif
375