MCPcopy Create free account
hub / github.com/apple/foundationdb / updatePage

Function updatePage

fdbserver/VersionedBTree.actor.cpp:2790–2834  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2788 }
2789
2790 void updatePage(PagerEventReasons reason,
2791 unsigned int level,
2792 Standalone<VectorRef<LogicalPageID>> pageIDs,
2793 Reference<ArenaPage> data) override {
2794 // Get the cache entry for this page, without counting it as a cache hit as we're replacing its contents now
2795 // or as a cache miss because there is no benefit to the page already being in cache
2796 // Similarly, this does not count as a point lookup for reason.
2797 ASSERT(pageIDs.front() != invalidLogicalPageID);
2798 PageCacheEntry& cacheEntry = pageCache.get(pageIDs.front(), pageIDs.size() * physicalPageSize, true);
2799 debug_printf("DWALPager(%s) op=write %s cached=%d reading=%d writing=%d\n",
2800 filename.c_str(),
2801 toString(pageIDs).c_str(),
2802 cacheEntry.initialized(),
2803 cacheEntry.initialized() && cacheEntry.reading(),
2804 cacheEntry.initialized() && cacheEntry.writing());
2805
2806 // If the page is still being read then it's not also being written because a write places
2807 // the new content into readFuture when the write is launched, not when it is completed.
2808 // Read/write ordering is being enforced so waiting readers will not see the new write. This
2809 // is necessary for remap erasure to work correctly since the oldest version of a page, located
2810 // at the original page ID, could have a pending read when that version is expired (after which
2811 // future reads of the version are not allowed) and the write of the next newest version over top
2812 // of the original page begins.
2813 if (!cacheEntry.initialized()) {
2814 cacheEntry.writeFuture = detach(writePhysicalPage(reason, level, pageIDs, data));
2815 } else if (cacheEntry.reading()) {
2816 // This is very unlikely, maybe impossible in the current pager use cases
2817 // Wait for the outstanding read to finish, then start the write
2818 cacheEntry.writeFuture = mapAsync<Void, std::function<Future<Void>(Void)>, Void>(
2819 success(cacheEntry.readFuture), [=](Void) { return writePhysicalPage(reason, level, pageIDs, data); });
2820 }
2821 // If the page is being written, wait for this write before issuing the new write to ensure the
2822 // writes happen in the correct order
2823 else if (cacheEntry.writing()) {
2824 // This is very unlikely, maybe impossible in the current pager use cases
2825 // Wait for the previous write to finish, then start new write
2826 cacheEntry.writeFuture = mapAsync<Void, std::function<Future<Void>(Void)>, Void>(
2827 cacheEntry.writeFuture, [=](Void) { return writePhysicalPage(reason, level, pageIDs, data); });
2828 } else {
2829 cacheEntry.writeFuture = detach(writePhysicalPage(reason, level, pageIDs, data));
2830 }
2831
2832 // Always update the page contents immediately regardless of what happened above.
2833 cacheEntry.readFuture = data;
2834 }
2835
2836 Future<LogicalPageID> atomicUpdatePage(PagerEventReasons reason,
2837 unsigned int level,

Callers 1

atomicUpdatePageFunction · 0.85

Calls 9

writePhysicalPageFunction · 0.85
frontMethod · 0.80
readingMethod · 0.80
writingMethod · 0.80
toStringFunction · 0.70
getMethod · 0.65
sizeMethod · 0.45
c_strMethod · 0.45
initializedMethod · 0.45

Tested by

no test coverage detected