Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-11 08:45:55

0001 // @(#)root/io:$Id$
0002 // Author: Rene Brun   28/11/94
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TFile
0013 #define ROOT_TFile
0014 
0015 
0016 //////////////////////////////////////////////////////////////////////////
0017 //                                                                      //
0018 // TFile                                                                //
0019 //                                                                      //
0020 // ROOT file.                                                           //
0021 //                                                                      //
0022 //////////////////////////////////////////////////////////////////////////
0023 
0024 #include <atomic>
0025 #include <string>
0026 
0027 #include "Compression.h"
0028 #include "TDirectoryFile.h"
0029 #include "TUrl.h"
0030 #include "ROOT/RConcurrentHashColl.hxx"
0031 
0032 // Not a part of TFile interface; provide a forward declaration instead of #include.
0033 // #ifndef R__LESS_INCLUDES
0034 // #include "TMap.h"
0035 // #endif
0036 
0037 #ifdef R__USE_IMT
0038 #include "ROOT/TRWSpinLock.hxx"
0039 #include <mutex>
0040 #endif
0041 
0042 class TMap;
0043 class TFree;
0044 class TArrayC;
0045 class TArchiveFile;
0046 class TFileOpenHandle;
0047 class TFileCacheRead;
0048 class TFileCacheWrite;
0049 class TProcessID;
0050 class TStopwatch;
0051 class TFilePrefetch;
0052 
0053 class TFile : public TDirectoryFile {
0054   friend class TDirectoryFile;
0055   friend class TFilePrefetch;
0056 // TODO: We need to make sure only one TBasket is being written at a time
0057 // if we are writing multiple baskets in parallel.
0058 #ifdef R__USE_IMT
0059   friend class TBasket;
0060 #endif
0061 
0062 public:
0063    /// Asynchronous open request status
0064    enum EAsyncOpenStatus { kAOSNotAsync = -1,  kAOSFailure = 0,
0065                            kAOSInProgress = 1, kAOSSuccess = 2 };
0066    /// Open timeout constants
0067    enum EOpenTimeOut { kInstantTimeout = 0, kEternalTimeout = 999999999 };
0068 
0069    /// TTreeCache flushing semantics
0070    enum ECacheAction { kDisconnect = 0, kDoNotDisconnect = 1 };
0071 
0072 protected:
0073    Double_t         fSumBuffer{0};            ///<Sum of buffer sizes of objects written so far
0074    Double_t         fSum2Buffer{0};           ///<Sum of squares of buffer sizes of objects written so far
0075    Long64_t         fBytesWrite{0};           ///<Number of bytes written to this file
0076    Long64_t         fBytesRead{0};            ///<Number of bytes read from this file
0077    Long64_t         fBytesReadExtra{0};       ///<Number of extra bytes (overhead) read by the readahead buffer
0078    Long64_t         fBEGIN{0};                ///<First used byte in file
0079    Long64_t         fEND{0};                  ///<Last used byte in file
0080    Long64_t         fSeekFree{0};             ///<Location on disk of free segments structure
0081    Long64_t         fSeekInfo{0};             ///<Location on disk of StreamerInfo record
0082    Int_t            fD{-1};                   ///<File descriptor
0083    Int_t            fVersion{0};              ///<File format version
0084    Int_t            fCompress{0};             ///<Compression level and algorithm
0085    Int_t            fNbytesFree{0};           ///<Number of bytes for free segments structure
0086    Int_t            fNbytesInfo{0};           ///<Number of bytes for StreamerInfo record
0087    Int_t            fWritten{0};              ///<Number of objects written so far
0088    Int_t            fNProcessIDs{0};          ///<Number of TProcessID written to this file
0089    Int_t            fReadCalls{0};            ///<Number of read calls ( not counting the cache calls )
0090    TString          fRealName;                ///<Effective real file name (not original url)
0091    TString          fOption;                  ///<File options
0092    Char_t           fUnits{0};                ///<Number of bytes for file pointers
0093    TList           *fFree{nullptr};           ///<Free segments linked list table
0094    TArrayC         *fClassIndex{nullptr};     ///<!Index of TStreamerInfo classes written to this file
0095    TObjArray       *fProcessIDs{nullptr};     ///<!Array of pointers to TProcessIDs
0096    Long64_t         fOffset{0};               ///<!Seek offset cache
0097    TArchiveFile    *fArchive{nullptr};        ///<!Archive file from which we read this file
0098    TFileCacheRead  *fCacheRead{nullptr};      ///<!Pointer to the read cache (if any)
0099    TMap            *fCacheReadMap{nullptr};   ///<!Pointer to the read cache (if any)
0100    TFileCacheWrite *fCacheWrite{nullptr};     ///<!Pointer to the write cache (if any)
0101    Long64_t         fArchiveOffset{0};        ///<!Offset at which file starts in archive
0102    Bool_t           fIsArchive{kFALSE};       ///<!True if this is a pure archive file
0103    Bool_t           fNoAnchorInName{kFALSE};  ///<!True if we don't want to force the anchor to be appended to the file name
0104    Bool_t           fIsRootFile{kTRUE};       ///<!True is this is a ROOT file, raw file otherwise
0105    Bool_t           fInitDone{kFALSE};        ///<!True if the file has been initialized
0106    Bool_t           fMustFlush{kTRUE};        ///<!True if the file buffers must be flushed
0107    Bool_t           fIsPcmFile{kFALSE};       ///<!True if the file is a ROOT pcm file.
0108    TFileOpenHandle *fAsyncHandle{nullptr};    ///<!For proper automatic cleanup
0109    EAsyncOpenStatus fAsyncOpenStatus{kAOSNotAsync}; ///<!Status of an asynchronous open request
0110    TUrl             fUrl;                     ///<!URL of file
0111 
0112    TList           *fInfoCache{nullptr};      ///<!Cached list of the streamer infos in this file
0113    TList           *fOpenPhases{nullptr};     ///<!Time info about open phases
0114 
0115    bool             fGlobalRegistration = true; ///<! if true, bypass use of global lists
0116 
0117 #ifdef R__USE_IMT
0118    std::mutex                                 fWriteMutex;  ///<!Lock for writing baskets / keys into the file.
0119 #endif
0120    static ROOT::Internal::RConcurrentHashColl fgTsSIHashes; ///<!TS Set of hashes built from read streamer infos
0121 
0122    static TList    *fgAsyncOpenRequests; //List of handles for pending open requests
0123 
0124    static TString   fgCacheFileDir;          ///<Directory where to locally stage files
0125    static Bool_t    fgCacheFileDisconnected; ///<Indicates, we trust in the files in the cache dir without stat on the cached file
0126    static Bool_t    fgCacheFileForce;        ///<Indicates, to force all READ to CACHEREAD
0127    static UInt_t    fgOpenTimeout;           ///<Timeout for open operations in ms  - 0 corresponds to blocking i/o
0128    static Bool_t    fgOnlyStaged ;           ///<Before the file is opened, it is checked, that the file is staged, if not, the open fails
0129 
0130    static std::atomic<Long64_t>  fgBytesWrite;            ///<Number of bytes written by all TFile objects
0131    static std::atomic<Long64_t>  fgBytesRead;             ///<Number of bytes read by all TFile objects
0132    static std::atomic<Long64_t>  fgFileCounter;           ///<Counter for all opened files
0133    static std::atomic<Int_t>     fgReadCalls;             ///<Number of bytes read from all TFile objects
0134    static Int_t     fgReadaheadSize;         ///<Readahead buffer size
0135    static Bool_t    fgReadInfo;              ///<if true (default) ReadStreamerInfo is called when opening a file
0136 
0137    virtual EAsyncOpenStatus GetAsyncOpenStatus() { return fAsyncOpenStatus; }
0138    virtual void        Init(Bool_t create);
0139            Bool_t      FlushWriteCache();
0140            Int_t       ReadBufferViaCache(char *buf, Int_t len);
0141            Int_t       WriteBufferViaCache(const char *buf, Int_t len);
0142 
0143    ////////////////////////////////////////////////////////////////////////////////
0144    /// \brief Simple struct of the return value of GetStreamerInfoListImpl
0145    struct InfoListRet {
0146       TList *fList;
0147       Int_t  fReturnCode;
0148       ROOT::Internal::RConcurrentHashColl::HashValue fHash;
0149    };
0150 
0151    virtual InfoListRet GetStreamerInfoListImpl(bool lookupSICache);
0152 
0153    // Creating projects
0154            Int_t       MakeProjectParMake(const char *packname, const char *filename);
0155            Int_t       MakeProjectParProofInf(const char *packname, const char *proofinfdir);
0156 
0157    // Interface to basic system I/O routines
0158    virtual Int_t       SysOpen(const char *pathname, Int_t flags, UInt_t mode);
0159    virtual Int_t       SysClose(Int_t fd);
0160    virtual Int_t       SysRead(Int_t fd, void *buf, Int_t len);
0161    virtual Int_t       SysWrite(Int_t fd, const void *buf, Int_t len);
0162    virtual Long64_t    SysSeek(Int_t fd, Long64_t offset, Int_t whence);
0163    virtual Int_t       SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime);
0164    virtual Int_t       SysSync(Int_t fd);
0165 
0166    // Interface for text-based TDirectory I/O
0167    virtual Long64_t    DirCreateEntry(TDirectory*) { return 0; }
0168    virtual Int_t       DirReadKeys(TDirectory*) { return 0; }
0169    virtual void        DirWriteKeys(TDirectory*) {}
0170    virtual void        DirWriteHeader(TDirectory*) {}
0171 
0172 private:
0173    TFile(const TFile &) = delete;            //Files cannot be copied
0174    void operator=(const TFile &) = delete;
0175 
0176    static  void        CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch);
0177    static  TFile      *OpenFromCache(const char *name, Option_t * = "",
0178                                      const char *ftitle = "", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault,
0179                                      Int_t netopt = 0);
0180 
0181 public:
0182    /// TFile status bits. BIT(13) is taken up by TObject
0183    enum EStatusBits {
0184       // Produce files forward compatible with (unpatched) version older than
0185       // v6.30 by recording the internal bits kIsOnHeap and kNotDeleted; Older
0186       // releases were not explicitly setting those bits to the correct value
0187       // but instead used verbatim the value stored in the file.
0188       // Note that to avoid a circular dependency, this value is used
0189       // hard coded in TObject.cxx.
0190       k630forwardCompatibility = BIT(2),
0191       kRecovered     = BIT(10),
0192       kHasReferences = BIT(11),
0193       kDevNull       = BIT(12),
0194       kWriteError    = BIT(14),
0195       kBinaryFile    = BIT(15),
0196       kRedirected    = BIT(16),
0197       kReproducible  = BIT(17)
0198    };
0199    enum ERelativeTo { kBeg = 0, kCur = 1, kEnd = 2 };
0200    enum { kStartBigFile  = 2000000000 };
0201    /// File type
0202    enum EFileType { kDefault = 0, kLocal = 1, kNet = 2, kWeb = 3, kFile = 4, kMerge = 5 };
0203 
0204    TFile();
0205    TFile(const char *fname, Option_t *option="", const char *ftitle="", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault);
0206    ~TFile() override;
0207 
0208            void        Close(Option_t *option="") override; // *MENU*
0209            void        Copy(TObject &) const override { MayNotUse("Copy(TObject &)"); }
0210    virtual Bool_t      Cp(const char *dst, Bool_t progressbar = kTRUE,UInt_t buffersize = 1000000);
0211    virtual TKey*       CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize);
0212    virtual TKey*       CreateKey(TDirectory* mother, const void* obj, const TClass* cl,
0213                                  const char* name, Int_t bufsize);
0214    static TFile      *&CurrentFile(); // Return the current file for this thread.
0215            void        Delete(const char *namecycle="") override;
0216            void        Draw(Option_t *option="") override;
0217    virtual void        DrawMap(const char *keys="*",Option_t *option=""); // *MENU*
0218            void        FillBuffer(char *&buffer) override;
0219    virtual void        Flush();
0220          TArchiveFile *GetArchive() const { return fArchive; }
0221            Long64_t    GetArchiveOffset() const { return fArchiveOffset; }
0222            Int_t       GetBestBuffer() const;
0223    virtual Int_t       GetBytesToPrefetch() const;
0224        TFileCacheRead *GetCacheRead(const TObject* tree = nullptr) const;
0225       TFileCacheWrite *GetCacheWrite() const;
0226            TArrayC    *GetClassIndex() const { return fClassIndex; }
0227            Int_t       GetCompressionAlgorithm() const;
0228            Int_t       GetCompressionLevel() const;
0229            Int_t       GetCompressionSettings() const;
0230            Float_t     GetCompressionFactor();
0231    virtual Long64_t    GetEND() const { return fEND; }
0232    virtual Int_t       GetErrno() const;
0233    virtual void        ResetErrno() const;
0234            Int_t       GetFd() const { return fD; }
0235    virtual const TUrl *GetEndpointUrl() const { return &fUrl; }
0236            TObjArray  *GetListOfProcessIDs() const {return fProcessIDs;}
0237            TList      *GetListOfFree() const { return fFree; }
0238    virtual Int_t       GetNfree() const { return fFree->GetSize(); }
0239    virtual Int_t       GetNProcessIDs() const { return fNProcessIDs; }
0240            Option_t   *GetOption() const override { return fOption.Data(); }
0241    virtual Long64_t    GetBytesRead() const { return fBytesRead; }
0242    virtual Long64_t    GetBytesReadExtra() const { return fBytesReadExtra; }
0243    virtual Long64_t    GetBytesWritten() const;
0244    virtual Int_t       GetReadCalls() const { return fReadCalls; }
0245            Int_t       GetVersion() const { return fVersion; }
0246            Int_t       GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes,
0247                                        Int_t &nbytes, Int_t &objlen, Int_t &keylen);
0248    virtual Int_t       GetNbytesInfo() const {return fNbytesInfo;}
0249    virtual Int_t       GetNbytesFree() const {return fNbytesFree;}
0250    virtual TString     GetNewUrl() { return ""; }
0251            Long64_t    GetRelOffset() const { return fOffset - fArchiveOffset; }
0252    virtual Long64_t    GetSeekFree() const {return fSeekFree;}
0253    virtual Long64_t    GetSeekInfo() const {return fSeekInfo;}
0254    virtual Long64_t    GetSize() const;
0255    virtual TList      *GetStreamerInfoList() final; // Note: to override behavior, please override GetStreamerInfoListImpl
0256    const   TList      *GetStreamerInfoCache();
0257    virtual void        IncrementProcessIDs() { fNProcessIDs++; }
0258    virtual Bool_t      IsArchive() const { return fIsArchive; }
0259            Bool_t      IsBinary() const { return TestBit(kBinaryFile); }
0260            Bool_t      IsRaw() const { return !fIsRootFile; }
0261    virtual Bool_t      IsOpen() const;
0262            void        ls(Option_t *option="") const override;
0263    virtual void        MakeFree(Long64_t first, Long64_t last);
0264    virtual void        MakeProject(const char *dirname, const char *classes="*",
0265                                    Option_t *option="new"); // *MENU*
0266    virtual void        Map(Option_t *opt); // *MENU*
0267    virtual void        Map() { Map(""); }; // *MENU*
0268    virtual Bool_t      Matches(const char *name);
0269    virtual Bool_t      MustFlush() const {return fMustFlush;}
0270            void        Paint(Option_t *option="") override;
0271            void        Print(Option_t *option="") const override;
0272    virtual Bool_t      ReadBufferAsync(Long64_t offs, Int_t len);
0273    virtual Bool_t      ReadBuffer(char *buf, Int_t len);
0274    virtual Bool_t      ReadBuffer(char *buf, Long64_t pos, Int_t len);
0275    virtual Bool_t      ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf);
0276    virtual void        ReadFree();
0277    virtual TProcessID *ReadProcessID(UShort_t pidf);
0278    virtual void        ReadStreamerInfo();
0279    virtual Int_t       Recover();
0280    virtual Int_t       ReOpen(Option_t *mode);
0281    virtual void        Seek(Long64_t offset, ERelativeTo pos = kBeg);
0282    virtual void        SetCacheRead(TFileCacheRead *cache, TObject *tree = nullptr, ECacheAction action = kDisconnect);
0283    virtual void        SetCacheWrite(TFileCacheWrite *cache);
0284    virtual void        SetCompressionAlgorithm(Int_t algorithm = ROOT::RCompressionSetting::EAlgorithm::kUseGlobal);
0285    virtual void        SetCompressionLevel(Int_t level = ROOT::RCompressionSetting::ELevel::kUseMin);
0286    virtual void        SetCompressionSettings(Int_t settings = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault);
0287    virtual void        SetEND(Long64_t last) { fEND = last; }
0288    virtual void        SetOffset(Long64_t offset, ERelativeTo pos = kBeg);
0289    virtual void        SetOption(Option_t *option=">") { fOption = option; }
0290    virtual void        SetReadCalls(Int_t readcalls = 0) { fReadCalls = readcalls; }
0291    virtual void        ShowStreamerInfo();
0292            Int_t       Sizeof() const override;
0293            void        SumBuffer(Int_t bufsize);
0294    virtual Bool_t      WriteBuffer(const char *buf, Int_t len);
0295            Int_t       Write(const char *name=nullptr, Int_t opt=0, Int_t bufsiz=0) override;
0296            Int_t       Write(const char *name=nullptr, Int_t opt=0, Int_t bufsiz=0) const override;
0297    virtual void        WriteFree();
0298    virtual void        WriteHeader();
0299    virtual UShort_t    WriteProcessID(TProcessID *pid);
0300    virtual void        WriteStreamerInfo();
0301 
0302    static TFileOpenHandle
0303                       *AsyncOpen(const char *name, Option_t *option = "",
0304                                  const char *ftitle = "", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault,
0305                                  Int_t netopt = 0);
0306    static TFile       *Open(const char *name, Option_t *option = "",
0307                             const char *ftitle = "", Int_t compress = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault,
0308                             Int_t netopt = 0);
0309    static TFile       *Open(TFileOpenHandle *handle);
0310 
0311    static EFileType    GetType(const char *name, Option_t *option = "", TString *prefix = nullptr);
0312 
0313    static EAsyncOpenStatus GetAsyncOpenStatus(const char *name);
0314    static EAsyncOpenStatus GetAsyncOpenStatus(TFileOpenHandle *handle);
0315    static const TUrl  *GetEndpointUrl(const char *name);
0316 
0317    static Long64_t     GetFileBytesRead();
0318    static Long64_t     GetFileBytesWritten();
0319    static Int_t        GetFileReadCalls();
0320    static Int_t        GetReadaheadSize();
0321 
0322    static void         SetFileBytesRead(Long64_t bytes = 0);
0323    static void         SetFileBytesWritten(Long64_t bytes = 0);
0324    static void         SetFileReadCalls(Int_t readcalls = 0);
0325    static void         SetReadaheadSize(Int_t bufsize = 256000);
0326    static void         SetReadStreamerInfo(Bool_t readinfo=kTRUE);
0327    static Bool_t       GetReadStreamerInfo();
0328 
0329    static Long64_t     GetFileCounter();
0330    static void         IncrementFileCounter();
0331 
0332    static Bool_t       SetCacheFileDir(std::string_view cacheDir, Bool_t operateDisconnected = kTRUE,
0333                                        Bool_t forceCacheread = kFALSE);
0334    static const char  *GetCacheFileDir();
0335    static Bool_t       ShrinkCacheFileDir(Long64_t shrinkSize, Long_t cleanupInteval = 0);
0336    static Bool_t       Cp(const char *src, const char *dst, Bool_t progressbar = kTRUE,
0337                           UInt_t buffersize = 1000000);
0338 
0339    static UInt_t       SetOpenTimeout(UInt_t timeout);  // in ms
0340    static UInt_t       GetOpenTimeout(); // in ms
0341    static Bool_t       SetOnlyStaged(Bool_t onlystaged);
0342    static Bool_t       GetOnlyStaged();
0343 
0344    ClassDefOverride(TFile,8)  //ROOT file
0345 };
0346 
0347 #define gFile (TFile::CurrentFile())
0348 
0349 /**
0350 \class TFileOpenHandle
0351 \ingroup IO
0352 Class holding info about the file being opened
0353 */
0354 class TFileOpenHandle : public TNamed {
0355 
0356 friend class TFile;
0357 
0358 private:
0359    TString  fOpt;            ///< Options
0360    Int_t    fCompress{0};    ///< Compression level and algorithm
0361    Int_t    fNetOpt{0};      ///< Network options
0362    TFile   *fFile{nullptr};  ///< TFile instance of the file being opened
0363 
0364    TFileOpenHandle(TFile *f) : TNamed("",""), fOpt(""), fCompress(ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault),
0365                                fNetOpt(0), fFile(f) { }
0366    TFileOpenHandle(const char *n, const char *o, const char *t, Int_t cmp,
0367                    Int_t no) : TNamed(n,t), fOpt(o), fCompress(cmp),
0368                                fNetOpt(no), fFile(nullptr) { }
0369    TFileOpenHandle(const TFileOpenHandle&) = delete;
0370    TFileOpenHandle& operator=(const TFileOpenHandle&) = delete;
0371 
0372    TFile      *GetFile() const { return fFile; }
0373 
0374 public:
0375    ~TFileOpenHandle() override { }
0376 
0377    Bool_t      Matches(const char *name);
0378 
0379    const char *GetOpt() const { return fOpt; }
0380    Int_t       GetCompress() const { return fCompress; }
0381    Int_t       GetNetOpt() const { return fNetOpt; }
0382 };
0383 
0384 //______________________________________________________________________________
0385 inline Int_t TFile::GetCompressionAlgorithm() const
0386 {
0387    return (fCompress < 0) ? -1 : fCompress / 100;
0388 }
0389 
0390 //______________________________________________________________________________
0391 inline Int_t TFile::GetCompressionLevel() const
0392 {
0393    return (fCompress < 0) ? -1 : fCompress % 100;
0394 }
0395 
0396 //______________________________________________________________________________
0397 inline Int_t TFile::GetCompressionSettings() const
0398 {
0399    return (fCompress < 0) ? -1 : fCompress;
0400 }
0401 
0402 #endif