Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:43

0001 /// \file ROOT/RFile.hxx
0002 /// \ingroup Base ROOT7
0003 /// \author Axel Naumann <axel@cern.ch>
0004 /// \date 2015-07-31
0005 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
0006 /// is welcome!
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT7_RFile
0017 #define ROOT7_RFile
0018 
0019 #include "ROOT/RDirectory.hxx"
0020 #include <string_view>
0021 
0022 #include "TClass.h"
0023 #include <memory>
0024 
0025 namespace ROOT {
0026 namespace Experimental {
0027 
0028 class RFilePtr;
0029 
0030 namespace Internal {
0031 class RFileStorageInterface;
0032 class RFileSharedPtrCtor;
0033 } // namespace Internal
0034 
0035 /** \class ROOT::Experimental::RFile
0036  A ROOT file.
0037 
0038  A ROOT file is an object store: it can serialize any
0039  object for which ROOT I/O is available (generally: an object which has a
0040  dictionary), and it stores the object's data under a key name.
0041 
0042  */
0043 class RFile: public RDirectory {
0044 private:
0045    std::unique_ptr<Internal::RFileStorageInterface> fStorage; ///< Storage backend.
0046 
0047    RFile(std::unique_ptr<Internal::RFileStorageInterface> &&storage);
0048 
0049    /// Serialize the object at address, using the object's TClass.
0050    // FIXME: what about `cl` "pointing" to a base class?
0051    void WriteMemoryWithType(std::string_view name, const void *address, TClass *cl);
0052 
0053    friend Internal::RFileSharedPtrCtor;
0054 
0055 public:
0056    /// Options for RFile construction.
0057    struct Options_t {
0058       /// Default constructor needed for member inits.
0059       Options_t() {}
0060 
0061       /// Whether the file should be opened asynchronously, if available.
0062       bool fAsynchronousOpen = false;
0063 
0064       /// Timeout for asynchronous opening.
0065       int fAsyncTimeout = 0;
0066 
0067       /// Whether the file should be cached before reading. Only available for
0068       /// "remote" file protocols. If the download fails, the file will be opened
0069       /// remotely.
0070       bool fCachedRead = false;
0071 
0072       /// Where to cache the file. If empty, defaults to RFilePtr::GetCacheDir().
0073       std::string fCacheDir;
0074    };
0075 
0076    ///\name Generator functions
0077    ///\{
0078 
0079    /// Open a file with `name` for reading.
0080    ///
0081    /// \note: Synchronizes multi-threaded accesses through locks.
0082    static RFilePtr Open(std::string_view name, const Options_t &opts = Options_t());
0083 
0084    /// Open an existing file with `name` for reading and writing. If a file with
0085    /// that name does not exist, an invalid RFilePtr will be returned.
0086    ///
0087    /// \note: Synchronizes multi-threaded accesses through locks.
0088    static RFilePtr OpenForUpdate(std::string_view name, const Options_t &opts = Options_t());
0089 
0090    /// Open a file with `name` for reading and writing. Fail (return an invalid
0091    /// `RFilePtr`) if a file with this name already exists.
0092    ///
0093    /// \note: Synchronizes multi-threaded accesses through locks.
0094    static RFilePtr Create(std::string_view name, const Options_t &opts = Options_t());
0095 
0096    /// Open a file with `name` for reading and writing. If a file with this name
0097    /// already exists, delete it and create a new one. Else simply create a new file.
0098    ///
0099    /// \note: Synchronizes multi-threaded accesses through locks.
0100    static RFilePtr Recreate(std::string_view name, const Options_t &opts = Options_t());
0101 
0102    ///\}
0103 
0104    /// Set the new directory used for cached reads, returns the old directory.
0105    ///
0106    /// \note: Synchronizes multi-threaded accesses through locks.
0107    static std::string SetCacheDir(std::string_view path);
0108 
0109    /// Get the directory used for cached reads.
0110    static std::string GetCacheDir();
0111 
0112    /// Must not call Write() of all attached objects:
0113    /// some might not be needed to be written or writing might be aborted due to
0114    /// an exception; require explicit Write().
0115    ~RFile();
0116 
0117    /// Save all objects associated with this directory (including file header) to
0118    /// the storage medium.
0119    void Flush();
0120 
0121    /// Flush() and make the file non-writable: close it.
0122    void Close();
0123 
0124    /// Read the object for a key. `T` must be the object's type.
0125    /// This will re-read the object for each call, returning a new copy; whether
0126    /// the `RDirectory` is managing an object attached to this key or not.
0127    /// \returns a `unique_ptr` to the object.
0128    /// \throws RDirectoryUnknownKey if no object is stored under this name.
0129    /// \throws RDirectoryTypeMismatch if the object stored under this name is of
0130    ///   a type different from `T`.
0131    template <class T>
0132    std::unique_ptr<T> Read(std::string_view name)
0133    {
0134       // FIXME: need separate collections for a RDirectory's key/value and registered objects. Here, we want to emit a
0135       // read and must look through the key/values without attaching an object to the RDirectory.
0136       // FIXME: do not register read object in RDirectory
0137       // FIXME: implement actual read
0138       // FIXME: for now, copy out of whatever the RDirectory manages.
0139       return std::make_unique<T>(*Get<T>(name));
0140    }
0141 
0142    /// Write an object that is not lifetime managed by this RFileImplBase.
0143    template <class T>
0144    void Write(std::string_view name, const T &obj)
0145    {
0146       WriteMemoryWithType(name, &obj, TClass::GetClass<T>());
0147    }
0148 
0149    /// Write an object that is not lifetime managed by this RFileImplBase.
0150    template <class T>
0151    void Write(std::string_view name, const T *obj)
0152    {
0153       WriteMemoryWithType(name, obj, TClass::GetClass<T>());
0154    }
0155 
0156    /// Write an object that is already lifetime managed by this RFileImplBase.
0157    void Write(std::string_view name)
0158    {
0159       auto dep = Find(name);
0160       WriteMemoryWithType(name, dep.GetPointer().get(), dep.GetType());
0161    }
0162 
0163    /// Hand over lifetime management of an object to this RFileImplBase, and
0164    /// write it.
0165    template <class T>
0166    void Write(std::string_view name, std::shared_ptr<T> &&obj)
0167    {
0168       Add(name, obj);
0169       // FIXME: use an iterator from the insertion to write instead of a second name lookup.
0170       Write(name);
0171    }
0172 };
0173 
0174 /**
0175  \class RFilePtr
0176  \brief Points to an object that stores or reads objects in ROOT's binary
0177  format.
0178 
0179  FIXME: implement async open; likely using std::future, possibly removing the
0180  Option_t element.
0181 
0182  */
0183 
0184 class RFilePtr {
0185 private:
0186    std::shared_ptr<RFile> fFile;
0187 
0188    /// Constructed by Open etc.
0189    RFilePtr(std::shared_ptr<RFile> &&);
0190 
0191    friend class RFile;
0192 
0193 public:
0194    /// Dereference the file pointer, giving access to the RFileImplBase object.
0195    RFile *operator->() { return fFile.get(); }
0196 
0197    /// Dereference the file pointer, giving access to the RFileImplBase object.
0198    /// const overload.
0199    const RFile *operator->() const { return fFile.get(); }
0200 
0201    /// Check the validity of the file pointer.
0202    operator bool() const { return fFile.get(); }
0203 };
0204 
0205 } // namespace Experimental
0206 } // namespace ROOT
0207 #endif