📄 dbtuppagemap.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#define DBTUP_C#include "Dbtup.hpp"#include <RefConvert.hpp>#include <ndb_limits.h>#include <pc.hpp>#define ljam() { jamLine(14000 + __LINE__); }#define ljamEntry() { jamEntryLine(14000 + __LINE__); }//// PageMap is a service used by Dbtup to map logical page id's to physical// page id's. The mapping is needs the fragment and the logical page id to// provide the physical id.//// This is a part of Dbtup which is the exclusive user of a certain set of// variables on the fragment record and it is the exclusive user of the// struct for page ranges.////// The following methods operate on the data handled by the page map class.//// Public methods// insertPageRange(Uint32 startPageId, # In// Uint32 noPages) # In// Inserts a range of pages into the mapping structure.//// void releaseFragPages()// Releases all pages and their mappings belonging to a fragment.//// Uint32 allocFragPages(Uint32 tafpNoAllocRequested)// Allocate a set of pages to the fragment from the page manager//// Uint32 getEmptyPage()// Get an empty page from the pool of empty pages on the fragment.// It returns the physical page id of the empty page.// Returns RNIL if no empty page is available.//// Uint32 getRealpid(Uint32 logicalPageId)// Return the physical page id provided the logical page id//// void initializePageRange()// Initialise free list of page ranges and initialise the page raneg records.//// void initFragRange()// Initialise the fragment variables when allocating a fragment to a table.//// void initPageRangeSize(Uint32 size)// Initialise the number of page ranges.//// Uint32 getNoOfPages()// Get the number of pages on the fragment currently.////// Private methods// Uint32 leafPageRangeFull(PageRangePtr currPageRangePtr)//// void errorHandler()// Method to crash NDB kernel in case of weird data set-up//// void allocMoreFragPages()// When no more empty pages are attached to the fragment and we need more// we allocate more pages from the page manager using this method.//// Private data// On the fragment record// currentPageRange # The current page range where to insert the next range// rootPageRange # The root of the page ranges owned// nextStartRange # The next page id to assign when expanding the// # page map// noOfPages # The number of pages in the fragment// emptyPrimPage # The first page of the empty pages in the fragment//// The full page range structUint32 Dbtup::getEmptyPage(Fragrecord* const regFragPtr){ Uint32 logicalPageId = regFragPtr->emptyPrimPage; if (logicalPageId == RNIL) { ljam(); allocMoreFragPages(regFragPtr); logicalPageId = regFragPtr->emptyPrimPage; if (logicalPageId == RNIL) { ljam(); return RNIL; }//if }//if Uint32 physicalPageId = getRealpid(regFragPtr, logicalPageId); PagePtr pagePtr; pagePtr.i = physicalPageId; ptrCheckGuard(pagePtr, cnoOfPage, page); regFragPtr->emptyPrimPage = pagePtr.p->pageWord[ZPAGE_NEXT_POS]; return physicalPageId;}//Dbtup::getEmptyPage()Uint32 Dbtup::getRealpid(Fragrecord* const regFragPtr, Uint32 logicalPageId) { PageRangePtr grpPageRangePtr; Uint32 loopLimit; Uint32 loopCount = 0; Uint32 pageRangeLimit = cnoOfPageRangeRec; grpPageRangePtr.i = regFragPtr->rootPageRange; while (true) { ndbrequire(loopCount++ < 100); ndbrequire(grpPageRangePtr.i < pageRangeLimit); ptrAss(grpPageRangePtr, pageRange); loopLimit = grpPageRangePtr.p->currentIndexPos; ndbrequire(loopLimit <= 3); for (Uint32 i = 0; i <= loopLimit; i++) { ljam(); if (grpPageRangePtr.p->startRange[i] <= logicalPageId) { if (grpPageRangePtr.p->endRange[i] >= logicalPageId) { if (grpPageRangePtr.p->type[i] == ZLEAF) { ljam(); Uint32 realPageId = (logicalPageId - grpPageRangePtr.p->startRange[i]) + grpPageRangePtr.p->basePageId[i]; return realPageId; } else { ndbrequire(grpPageRangePtr.p->type[i] == ZNON_LEAF); grpPageRangePtr.i = grpPageRangePtr.p->basePageId[i]; }//if }//if }//if }//for }//while return 0;}//Dbtup::getRealpid()Uint32 Dbtup::getNoOfPages(Fragrecord* const regFragPtr){ return regFragPtr->noOfPages;}//Dbtup::getNoOfPages()void Dbtup::initPageRangeSize(Uint32 size){ cnoOfPageRangeRec = size;}//Dbtup::initPageRangeSize()/* ---------------------------------------------------------------- *//* ----------------------- INSERT_PAGE_RANGE_TAB ------------------ *//* ---------------------------------------------------------------- *//* INSERT A PAGE RANGE INTO THE FRAGMENT *//* *//* NOTE: THE METHOD IS ATOMIC. EITHER THE ACTION IS *//* PERFORMED FULLY OR NO ACTION IS PERFORMED AT ALL. *//* TO SUPPORT THIS THE CODE HAS A CLEANUP PART AFTER *//* ERRORS. *//* ---------------------------------------------------------------- */bool Dbtup::insertPageRangeTab(Fragrecord* const regFragPtr, Uint32 startPageId, Uint32 noPages) { PageRangePtr currPageRangePtr; if (cfirstfreerange == RNIL) { ljam(); return false; }//if currPageRangePtr.i = regFragPtr->currentPageRange; if (currPageRangePtr.i == RNIL) { ljam();/* ---------------------------------------------------------------- *//* THE FIRST PAGE RANGE IS HANDLED WITH SPECIAL CODE *//* ---------------------------------------------------------------- */ seizePagerange(currPageRangePtr); regFragPtr->rootPageRange = currPageRangePtr.i; currPageRangePtr.p->currentIndexPos = 0; currPageRangePtr.p->parentPtr = RNIL; } else { ljam(); ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange); if (currPageRangePtr.p->currentIndexPos < 3) { ljam();/* ---------------------------------------------------------------- *//* THE SIMPLE CASE WHEN IT IS ONLY NECESSARY TO FILL IN THE *//* NEXT EMPTY POSITION IN THE PAGE RANGE RECORD IS TREATED *//* BY COMMON CODE AT THE END OF THE SUBROUTINE. *//* ---------------------------------------------------------------- */ currPageRangePtr.p->currentIndexPos++; } else { ljam(); ndbrequire(currPageRangePtr.p->currentIndexPos == 3); currPageRangePtr.i = leafPageRangeFull(regFragPtr, currPageRangePtr); if (currPageRangePtr.i == RNIL) { return false; }//if ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange); }//if }//if currPageRangePtr.p->startRange[currPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;/* ---------------------------------------------------------------- *//* NOW SET THE LEAF LEVEL PAGE RANGE RECORD PROPERLY *//* PAGE_RANGE_PTR REFERS TO LEAF RECORD WHEN ARRIVING HERE *//* ---------------------------------------------------------------- */ currPageRangePtr.p->endRange[currPageRangePtr.p->currentIndexPos] = (regFragPtr->nextStartRange + noPages) - 1; currPageRangePtr.p->basePageId[currPageRangePtr.p->currentIndexPos] = startPageId; currPageRangePtr.p->type[currPageRangePtr.p->currentIndexPos] = ZLEAF;/* ---------------------------------------------------------------- *//* WE NEED TO UPDATE THE CURRENT PAGE RANGE IN CASE IT HAS *//* CHANGED. WE ALSO NEED TO UPDATE THE NEXT START RANGE *//* ---------------------------------------------------------------- */ regFragPtr->currentPageRange = currPageRangePtr.i; regFragPtr->nextStartRange += noPages;/* ---------------------------------------------------------------- *//* WE NEED TO UPDATE THE END RANGE IN ALL PAGE RANGE RECORDS *//* UP TO THE ROOT. *//* ---------------------------------------------------------------- */ PageRangePtr loopPageRangePtr; loopPageRangePtr = currPageRangePtr; while (true) { ljam(); loopPageRangePtr.i = loopPageRangePtr.p->parentPtr; if (loopPageRangePtr.i != RNIL) { ljam(); ptrCheckGuard(loopPageRangePtr, cnoOfPageRangeRec, pageRange); ndbrequire(loopPageRangePtr.p->currentIndexPos < 4); loopPageRangePtr.p->endRange[loopPageRangePtr.p->currentIndexPos] += noPages; } else { ljam(); break; }//if }//while regFragPtr->noOfPages += noPages; return true;}//Dbtup::insertPageRangeTab()void Dbtup::releaseFragPages(Fragrecord* const regFragPtr) { if (regFragPtr->rootPageRange == RNIL) { ljam(); return; }//if PageRangePtr regPRPtr; regPRPtr.i = regFragPtr->rootPageRange; ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange); while (true) { ljam(); const Uint32 indexPos = regPRPtr.p->currentIndexPos; ndbrequire(indexPos < 4); const Uint32 basePageId = regPRPtr.p->basePageId[indexPos]; regPRPtr.p->basePageId[indexPos] = RNIL; if (basePageId == RNIL) { ljam(); /** * Finished with indexPos continue with next */ if (indexPos > 0) { ljam(); regPRPtr.p->currentIndexPos--; continue; }//if /* ---------------------------------------------------------------- */ /* THE PAGE RANGE REC IS EMPTY. RELEASE IT. */ /*----------------------------------------------------------------- */ Uint32 parentPtr = regPRPtr.p->parentPtr; releasePagerange(regPRPtr); if (parentPtr != RNIL) { ljam();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -