36 const auto entryIndex =
fEntries.size();
40 auto [itrEntryIdx, isNew] = itrPageSet->second.emplace(
RPagePosition(page), entryIndex);
42 assert(itrEntryIdx->second <
fEntries.size());
45 fEntries[itrEntryIdx->second].fRefCounter += initialRefCounter;
46 return fEntries[itrEntryIdx->second];
55 return fEntries.emplace_back(
REntry{std::move(page), key, initialRefCounter});
60 std::lock_guard<std::mutex> lockGuard(
fLock);
66 std::lock_guard<std::mutex> lockGuard(
fLock);
67 const auto &entry =
AddPage(std::move(page), key, 0);
68 if (entry.fRefCounter == 0)
79 if (itrPageSet->second.empty())
84 if (entryIdx != (
N - 1)) {
89 assert(itrEntryIdx != itrPageSet->second.end());
90 itrEntryIdx->second = entryIdx;
100 if (page.
IsNull())
return;
101 std::lock_guard<std::mutex> lockGuard(
fLock);
105 const auto idx = itrLookup->second;
107 assert(
fEntries[idx].fRefCounter >= 1);
108 if (--
fEntries[idx].fRefCounter == 0) {
127 if (itr->second.empty())
133 std::lock_guard<std::mutex> lockGuard(
fLock);
137 assert(!itrPageSet->second.empty());
139 auto itrEntryIdx = itrPageSet->second.upper_bound(
RPagePosition(globalIndex));
140 if (itrEntryIdx == itrPageSet->second.begin())
144 if (
fEntries[itrEntryIdx->second].fPage.Contains(globalIndex)) {
145 if (
fEntries[itrEntryIdx->second].fRefCounter == 0)
147 fEntries[itrEntryIdx->second].fRefCounter++;
155 std::lock_guard<std::mutex> lockGuard(
fLock);
159 assert(!itrPageSet->second.empty());
161 auto itrEntryIdx = itrPageSet->second.upper_bound(
RPagePosition(localIndex));
162 if (itrEntryIdx == itrPageSet->second.begin())
166 if (
fEntries[itrEntryIdx->second].fPage.Contains(localIndex)) {
167 if (
fEntries[itrEntryIdx->second].fRefCounter == 0)
169 fEntries[itrEntryIdx->second].fRefCounter++;
177 std::lock_guard<std::mutex> lockGuard(
fLock);
182 for (
auto pageBuffer : itr->second) {
185 const auto entryIdx = itrLookupByBuffer->second;
186 assert(
fEntries[entryIdx].fRefCounter == 0);
A thread-safe integral performance counter.
A thread-safe integral performance counter.
std::unique_ptr< RCounters > fCounters
void ErasePage(std::size_t entryIdx, decltype(fLookupByBuffer)::iterator lookupByBufferItr)
Called both by ReleasePage() and by Evict() to remove an unused page from the pool.
ROOT::Experimental::Detail::RNTupleMetrics fMetrics
The page pool counters are observed by the page source.
void Evict(ROOT::DescriptorId_t clusterId)
Removes unused pages (pages with reference counter 0) from the page pool.
REntry & AddPage(RPage page, const RKey &key, std::int64_t initialRefCounter)
Add a new page to the fLookupByBuffer and fLookupByKey data structures.
std::unordered_map< ROOT::DescriptorId_t, std::unordered_set< void * > > fUnusedPages
Remembers pages with reference counter 0, organized by the page's cluster id.
std::mutex fLock
The page pool is accessed concurrently due to parallel decompression.
RPageRef GetPage(RKey key, ROOT::NTupleSize_t globalIndex)
Tries to find the page corresponding to column and index in the cache.
RPagePool(RPageSource &pageSource)
std::unordered_map< RKey, std::map< RPagePosition, std::size_t >, RKeyHasher > fLookupByKey
Used in GetPage() to find the right page in fEntries.
void AddToUnusedPages(const RPage &page)
Called by PreloadPage() if the page at hand is new and thus added with ref counter 0.
void PreloadPage(RPage page, RKey key)
Like RegisterPage() but the reference counter is initialized to 0.
RPageRef RegisterPage(RPage page, RKey key)
Adds a new page to the pool.
void RemoveFromUnusedPages(const RPage &page)
Called by GetPage(), when the reference counter increases from zero to one.
RPageSource & fPageSource
Every page pool is associated to exactly one page source.
std::unordered_map< void *, std::size_t > fLookupByBuffer
Used in ReleasePage() to find the page index in fPages.
std::vector< REntry > fEntries
All cached pages in the page pool.
void ReleasePage(const RPage &page)
Give back a page to the pool and decrease the reference counter.
Abstract interface to read data from an ntuple.
ROOT::DescriptorId_t GetId() const
A page is a slice of a column that is mapped into memory.
ROOT::NTupleSize_t GetGlobalRangeLast() const
const RClusterInfo & GetClusterInfo() const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Performance counters that get registered in fMetrics.
Every page in the page pool is annotated with a search key and a reference counter.
Used in fLookupByKey to store both the absolute and the cluster-local page index of the referenced pa...