Rename Page and VersionHeader to PageHeader for consistency. Check for known encrypted types explicitly in isEncodingTypeEncrypted(). Make writePhysicalBlock() hold a Page reference which is simpler and more robust. Remove unused argument in switchTree().

This commit is contained in:
Steve Atherton 2022-04-07 18:40:57 -07:00
parent f7ba78ca97
commit 3ef18bc173
3 changed files with 18 additions and 26 deletions

View File

@ -1276,9 +1276,7 @@ public:
} }
// Switch the cursor to point to a new DeltaTree // Switch the cursor to point to a new DeltaTree
// if noReset is true, then the current decoded item will NOT be reset, so be sure that the original tree will void switchTree(DeltaTree2* newTree) {
// have a lifetime that exceeds this cursor as the decoded item may point into the original tree.
void switchTree(DeltaTree2* newTree, bool noReset = false) {
tree = newTree; tree = newTree;
// Reset item because it may point into tree memory // Reset item because it may point into tree memory
item.reset(); item.reset();

View File

@ -202,9 +202,9 @@ private:
// 4k-aligned memory held by an Arena // 4k-aligned memory held by an Arena
// //
// Page Format: // Page Format:
// VersionHeader - describes main header version, encoding type, and offsets of subheaders and payload. // PageHeader - describes main header version, encoding type, and offsets of subheaders and payload.
// MainHeader - structure based on header version. It is responsible for protecting all bytes // MainHeader - structure based on header version. It is responsible for protecting all bytes
// of VersionHeader, MainHeader, and EncodingHeader with some sort of checksum. // of PageHeader, MainHeader, and EncodingHeader with some sort of checksum.
// EncodingHeader - structure based on encoding type. It is responsible for protecting and // EncodingHeader - structure based on encoding type. It is responsible for protecting and
// possibly encrypting all payload bytes. // possibly encrypting all payload bytes.
// Payload - User accessible bytes, protected and possibly encrypted based on the encoding // Payload - User accessible bytes, protected and possibly encrypted based on the encoding
@ -253,7 +253,7 @@ public:
// header versions and encoding type headers could change size as offset information // header versions and encoding type headers could change size as offset information
// is stored to enable efficient jumping to the encoding header or payload. // is stored to enable efficient jumping to the encoding header or payload.
// Page members are only initialized in init() // Page members are only initialized in init()
struct Page { struct PageHeader {
uint8_t headerVersion; uint8_t headerVersion;
EncodingType encodingType; EncodingType encodingType;
@ -379,7 +379,7 @@ public:
// Get the usable size for a new page of pageSize using HEADER_WRITE_VERSION with encoding type t // Get the usable size for a new page of pageSize using HEADER_WRITE_VERSION with encoding type t
static int getUsableSize(int pageSize, EncodingType t) { static int getUsableSize(int pageSize, EncodingType t) {
return pageSize - sizeof(Page) - sizeof(RedwoodHeaderV1) - encodingHeaderSize(t); return pageSize - sizeof(PageHeader) - sizeof(RedwoodHeaderV1) - encodingHeaderSize(t);
} }
// Initialize the header for a new page so that the payload can be written to // Initialize the header for a new page so that the payload can be written to
@ -389,9 +389,9 @@ public:
// Payload can be written to with mutateData() and dataSize() // Payload can be written to with mutateData() and dataSize()
void init(EncodingType t, PageType pageType, uint8_t pageSubType, uint8_t pageFormat = 0) { void init(EncodingType t, PageType pageType, uint8_t pageSubType, uint8_t pageFormat = 0) {
// Carefully cast away constness to modify page header // Carefully cast away constness to modify page header
Page* p = const_cast<Page*>(page); PageHeader* p = const_cast<PageHeader*>(page);
p->headerVersion = HEADER_WRITE_VERSION; p->headerVersion = HEADER_WRITE_VERSION;
p->encodingHeaderOffset = sizeof(Page) + sizeof(RedwoodHeaderV1); p->encodingHeaderOffset = sizeof(PageHeader) + sizeof(RedwoodHeaderV1);
p->encodingType = t; p->encodingType = t;
p->payloadOffset = page->encodingHeaderOffset + encodingHeaderSize(t); p->payloadOffset = page->encodingHeaderOffset + encodingHeaderSize(t);
@ -533,7 +533,7 @@ public:
const Arena& getArena() const { return arena; } const Arena& getArena() const { return arena; }
static bool isEncodingTypeEncrypted(EncodingType t) { return t != EncodingType::XXHash64; } static bool isEncodingTypeEncrypted(EncodingType t) { return t == EncodingType::XOREncryption; }
// Returns true if the page's encoding type employs encryption // Returns true if the page's encoding type employs encryption
bool isEncrypted() const { return isEncodingTypeEncrypted(getEncodingType()); } bool isEncrypted() const { return isEncodingTypeEncrypted(getEncodingType()); }
@ -554,7 +554,7 @@ private:
// For convenience, it is unioned with a Page pointer which defines the page structure // For convenience, it is unioned with a Page pointer which defines the page structure
union { union {
uint8_t* buffer; uint8_t* buffer;
const Page* page; const PageHeader* page;
}; };
// Pointer and length of page space available to the user // Pointer and length of page space available to the user

View File

@ -2657,11 +2657,12 @@ public:
Future<LogicalPageID> newExtentPageID(QueueID queueID) override { return newExtentPageID_impl(this, queueID); } Future<LogicalPageID> newExtentPageID(QueueID queueID) override { return newExtentPageID_impl(this, queueID); }
ACTOR static Future<Void> writePhysicalBlock(DWALPager* self, ACTOR static Future<Void> writePhysicalBlock(DWALPager* self,
uint8_t* data, Reference<ArenaPage> page,
int blockNum,
int blockSize,
PhysicalPageID pageID,
PagerEventReasons reason, PagerEventReasons reason,
unsigned int level, unsigned int level,
PhysicalPageID pageID,
int blockSize,
bool header) { bool header) {
state PriorityMultiLock::Lock lock = wait(self->ioLock.lock(header ? ioMaxPriority : ioMinPriority)); state PriorityMultiLock::Lock lock = wait(self->ioLock.lock(header ? ioMaxPriority : ioMinPriority));
@ -2685,7 +2686,7 @@ public:
// Note: Not using forwardError here so a write error won't be discovered until commit time. // Note: Not using forwardError here so a write error won't be discovered until commit time.
debug_printf("DWALPager(%s) op=writeBlock %s\n", self->filename.c_str(), toString(pageID).c_str()); debug_printf("DWALPager(%s) op=writeBlock %s\n", self->filename.c_str(), toString(pageID).c_str());
wait(self->pageFile->write((void*)data, blockSize, (int64_t)pageID * blockSize)); wait(self->pageFile->write(page->rawData() + (blockNum * blockSize), blockSize, (int64_t)pageID * blockSize));
debug_printf("DWALPager(%s) op=writeBlockDone %s\n", self->filename.c_str(), toString(pageID).c_str()); debug_printf("DWALPager(%s) op=writeBlockDone %s\n", self->filename.c_str(), toString(pageID).c_str());
return Void(); return Void();
} }
@ -2710,7 +2711,6 @@ public:
return Void(); return Void();
} }
// The caller must keep page in scope until future is ready
Future<Void> writePhysicalPage(PagerEventReasons reason, Future<Void> writePhysicalPage(PagerEventReasons reason,
unsigned int level, unsigned int level,
Standalone<VectorRef<PhysicalPageID>> pageIDs, Standalone<VectorRef<PhysicalPageID>> pageIDs,
@ -2738,22 +2738,16 @@ public:
int blockSize = header ? smallestPhysicalBlock : physicalPageSize; int blockSize = header ? smallestPhysicalBlock : physicalPageSize;
Future<Void> f; Future<Void> f;
if (pageIDs.size() == 1) { if (pageIDs.size() == 1) {
f = writePhysicalBlock(this, page->rawData(), reason, level, pageIDs.front(), blockSize, header); f = writePhysicalBlock(this, page, 0, blockSize, pageIDs.front(), reason, level, header);
} else { } else {
std::vector<Future<Void>> writers; std::vector<Future<Void>> writers;
for (int i = 0; i < pageIDs.size(); ++i) { for (int i = 0; i < pageIDs.size(); ++i) {
Future<Void> p = writePhysicalBlock( Future<Void> p = writePhysicalBlock(this, page, i, blockSize, pageIDs[i], reason, level, header);
this, page->rawData() + (i * blockSize), reason, level, pageIDs[i], blockSize, header);
writers.push_back(p); writers.push_back(p);
} }
f = waitForAll(writers); f = waitForAll(writers);
} }
// If the page was copied, hold the copy alive until f is ready
if (copy) {
f = holdWhile(page, f);
}
operations.push_back(f); operations.push_back(f);
return f; return f;
} }
@ -6357,7 +6351,7 @@ private:
int i = 0; int i = 0;
if (updating) { if (updating) {
// Update must be done in the new tree, not the original tree where the end cursor will be from // Update must be done in the new tree, not the original tree where the end cursor will be from
end.switchTree(btPage()->tree(), true); end.switchTree(btPage()->tree());
// TODO: insert recs in a random order to avoid new subtree being entirely right child links // TODO: insert recs in a random order to avoid new subtree being entirely right child links
while (i != recs.size()) { while (i != recs.size()) {
@ -6429,7 +6423,7 @@ private:
if (c != u.cEnd) { if (c != u.cEnd) {
cloneForUpdate(); cloneForUpdate();
// must point c to the tree to erase from // must point c to the tree to erase from
c.switchTree(btPage()->tree(), true); c.switchTree(btPage()->tree());
} }
while (c != u.cEnd) { while (c != u.cEnd) {