Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file ROOT/RPagePool.hxx
0002 /// \ingroup NTuple ROOT7
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2018-10-09
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-2019, 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_RPagePool
0017 #define ROOT7_RPagePool
0018 
0019 #include <ROOT/RPage.hxx>
0020 #include <ROOT/RPageAllocator.hxx>
0021 #include <ROOT/RNTupleUtil.hxx>
0022 
0023 #include <cstddef>
0024 #include <mutex>
0025 #include <vector>
0026 
0027 namespace ROOT {
0028 namespace Experimental {
0029 
0030 namespace Internal {
0031 
0032 // clang-format off
0033 /**
0034 \class ROOT::Experimental::Internal::RPagePool
0035 \ingroup NTuple
0036 \brief A thread-safe cache of column pages.
0037 
0038 The page pool provides memory tracking for data written into an ntuple or read from an ntuple. Adding and removing
0039 pages is thread-safe. The page pool does not allocate the memory -- allocation and deallocation is performed by the
0040 page storage, which might do it in a way optimized to the backing store (e.g., mmap()).
0041 Multiple page caches can coexist.
0042 
0043 TODO(jblomer): it should be possible to register pages and to find them by column and index; this would
0044 facilitate pre-filling a cache, e.g. by read-ahead.
0045 */
0046 // clang-format on
0047 class RPagePool {
0048 private:
0049    /// TODO(jblomer): should be an efficient index structure that allows
0050    ///   - random insert
0051    ///   - random delete
0052    ///   - searching by page
0053    ///   - searching by tree index
0054    std::vector<RPage> fPages;
0055    std::vector<std::int32_t> fReferences;
0056    std::vector<RPageDeleter> fDeleters;
0057    std::mutex fLock;
0058 
0059 public:
0060    RPagePool() = default;
0061    RPagePool(const RPagePool&) = delete;
0062    RPagePool& operator =(const RPagePool&) = delete;
0063    ~RPagePool() = default;
0064 
0065    /// Adds a new page to the pool together with the function to free its space. Upon registration,
0066    /// the page pool takes ownership of the page's memory. The new page has its reference counter set to 1.
0067    void RegisterPage(const RPage &page, const RPageDeleter &deleter);
0068    /// Like RegisterPage() but the reference counter is initialized to 0
0069    void PreloadPage(const RPage &page, const RPageDeleter &deleter);
0070    /// Tries to find the page corresponding to column and index in the cache. If the page is found, its reference
0071    /// counter is increased
0072    RPage GetPage(ColumnId_t columnId, NTupleSize_t globalIndex);
0073    RPage GetPage(ColumnId_t columnId, RClusterIndex clusterIndex);
0074    /// Give back a page to the pool and decrease the reference counter. There must not be any pointers anymore into
0075    /// this page. If the reference counter drops to zero, the page pool might decide to call the deleter given in
0076    /// during registration.
0077    void ReturnPage(const RPage &page);
0078 };
0079 
0080 } // namespace Internal
0081 
0082 } // namespace Experimental
0083 } // namespace ROOT
0084 
0085 #endif