summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp')
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp556
1 files changed, 556 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
new file mode 100644
index 00000000000..1f674876642
--- /dev/null
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
@@ -0,0 +1,556 @@
+/* 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 struct
+
+Uint32 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();
+ regPRPtr.i = parentPtr;
+ ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
+ continue;
+ }//if
+
+ ljam();
+ ndbrequire(regPRPtr.i == regFragPtr->rootPageRange);
+ initFragRange(regFragPtr);
+ return;
+ } else {
+ if (regPRPtr.p->type[indexPos] == ZNON_LEAF) {
+ jam();
+ /* ---------------------------------------------------------------- */
+ // A non-leaf node, we must release everything below it before we
+ // release this node.
+ /* ---------------------------------------------------------------- */
+ regPRPtr.i = basePageId;
+ ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
+ } else {
+ jam();
+ ndbrequire(regPRPtr.p->type[indexPos] == ZLEAF);
+ /* ---------------------------------------------------------------- */
+ /* PAGE_RANGE_PTR /= RNIL AND THE CURRENT POS IS NOT A CHLED. */
+ /*----------------------------------------------------------------- */
+ const Uint32 start = regPRPtr.p->startRange[indexPos];
+ const Uint32 stop = regPRPtr.p->endRange[indexPos];
+ ndbrequire(stop >= start);
+ const Uint32 retNo = (stop - start + 1);
+ returnCommonArea(basePageId, retNo);
+ }//if
+ }//if
+ }//while
+}//Dbtup::releaseFragPages()
+
+void Dbtup::initializePageRange()
+{
+ PageRangePtr regPTRPtr;
+ for (regPTRPtr.i = 0;
+ regPTRPtr.i < cnoOfPageRangeRec; regPTRPtr.i++) {
+ ptrAss(regPTRPtr, pageRange);
+ regPTRPtr.p->nextFree = regPTRPtr.i + 1;
+ }//for
+ regPTRPtr.i = cnoOfPageRangeRec - 1;
+ ptrAss(regPTRPtr, pageRange);
+ regPTRPtr.p->nextFree = RNIL;
+ cfirstfreerange = 0;
+ c_noOfFreePageRanges = cnoOfPageRangeRec;
+}//Dbtup::initializePageRange()
+
+void Dbtup::initFragRange(Fragrecord* const regFragPtr)
+{
+ regFragPtr->emptyPrimPage = RNIL;
+ regFragPtr->rootPageRange = RNIL;
+ regFragPtr->currentPageRange = RNIL;
+ regFragPtr->noOfPages = 0;
+ regFragPtr->nextStartRange = 0;
+}//initFragRange()
+
+Uint32 Dbtup::allocFragPages(Fragrecord* const regFragPtr, Uint32 tafpNoAllocRequested)
+{
+ Uint32 tafpPagesAllocated = 0;
+ while (true) {
+ Uint32 noOfPagesAllocated = 0;
+ Uint32 noPagesToAllocate = tafpNoAllocRequested - tafpPagesAllocated;
+ Uint32 retPageRef = RNIL;
+ allocConsPages(noPagesToAllocate, noOfPagesAllocated, retPageRef);
+ if (noOfPagesAllocated == 0) {
+ ljam();
+ return tafpPagesAllocated;
+ }//if
+/* ---------------------------------------------------------------- */
+/* IT IS NOW TIME TO PUT THE ALLOCATED AREA INTO THE PAGE */
+/* RANGE TABLE. */
+/* ---------------------------------------------------------------- */
+ Uint32 startRange = regFragPtr->nextStartRange;
+ if (!insertPageRangeTab(regFragPtr, retPageRef, noOfPagesAllocated)) {
+ ljam();
+ returnCommonArea(retPageRef, noOfPagesAllocated);
+ return tafpPagesAllocated;
+ }//if
+ tafpPagesAllocated += noOfPagesAllocated;
+ Uint32 loopLimit = retPageRef + noOfPagesAllocated;
+ PagePtr loopPagePtr;
+/* ---------------------------------------------------------------- */
+/* SINCE A NUMBER OF PAGES WERE ALLOCATED FROM COMMON AREA */
+/* WITH SUCCESS IT IS NOW TIME TO CHANGE THE STATE OF */
+/* THOSE PAGES TO EMPTY_MM AND LINK THEM INTO THE EMPTY */
+/* PAGE LIST OF THE FRAGMENT. */
+/* ---------------------------------------------------------------- */
+ for (loopPagePtr.i = retPageRef; loopPagePtr.i < loopLimit; loopPagePtr.i++) {
+ ljam();
+ ptrCheckGuard(loopPagePtr, cnoOfPage, page);
+ loopPagePtr.p->pageWord[ZPAGE_STATE_POS] = ZEMPTY_MM;
+ loopPagePtr.p->pageWord[ZPAGE_FRAG_PAGE_ID_POS] = startRange +
+ (loopPagePtr.i - retPageRef);
+ loopPagePtr.p->pageWord[ZPAGE_NEXT_POS] = loopPagePtr.p->pageWord[ZPAGE_FRAG_PAGE_ID_POS] + 1;
+ }//for
+ loopPagePtr.i = (retPageRef + noOfPagesAllocated) - 1;
+ ptrCheckGuard(loopPagePtr, cnoOfPage, page);
+ loopPagePtr.p->pageWord[ZPAGE_NEXT_POS] = regFragPtr->emptyPrimPage;
+ regFragPtr->emptyPrimPage = startRange;
+/* ---------------------------------------------------------------- */
+/* WAS ENOUGH PAGES ALLOCATED OR ARE MORE NEEDED. */
+/* ---------------------------------------------------------------- */
+ if (tafpPagesAllocated < tafpNoAllocRequested) {
+ ljam();
+ } else {
+ ndbrequire(tafpPagesAllocated == tafpNoAllocRequested);
+ ljam();
+ return tafpNoAllocRequested;
+ }//if
+ }//while
+}//Dbtup::allocFragPages()
+
+void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr)
+{
+ Uint32 noAllocPages = regFragPtr->noOfPages >> 3; // 12.5%
+ noAllocPages += regFragPtr->noOfPages >> 4; // 6.25%
+ noAllocPages += 2;
+/* -----------------------------------------------------------------*/
+// We will grow by 18.75% plus two more additional pages to grow
+// a little bit quicker in the beginning.
+/* -----------------------------------------------------------------*/
+ allocFragPages(regFragPtr, noAllocPages);
+}//Dbtup::allocMoreFragPages()
+
+Uint32 Dbtup::leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr)
+{
+/* ---------------------------------------------------------------- */
+/* THE COMPLEX CASE WHEN THE LEAF NODE IS FULL. GO UP THE TREE*/
+/* TO FIND THE FIRST RECORD WITH A FREE ENTRY. ALLOCATE NEW */
+/* PAGE RANGE RECORDS THEN ALL THE WAY DOWN TO THE LEAF LEVEL */
+/* AGAIN. THE TREE SHOULD ALWAYS REMAIN BALANCED. */
+/* ---------------------------------------------------------------- */
+ PageRangePtr parentPageRangePtr;
+ PageRangePtr foundPageRangePtr;
+ parentPageRangePtr = currPageRangePtr;
+ Uint32 tiprNoLevels = 1;
+ while (true) {
+ ljam();
+ parentPageRangePtr.i = parentPageRangePtr.p->parentPtr;
+ if (parentPageRangePtr.i == RNIL) {
+ ljam();
+/* ---------------------------------------------------------------- */
+/* WE HAVE REACHED THE ROOT. A NEW ROOT MUST BE ALLOCATED. */
+/* ---------------------------------------------------------------- */
+ if (c_noOfFreePageRanges < tiprNoLevels) {
+ ljam();
+ return RNIL;
+ }//if
+ PageRangePtr oldRootPRPtr;
+ PageRangePtr newRootPRPtr;
+ oldRootPRPtr.i = regFragPtr->rootPageRange;
+ ptrCheckGuard(oldRootPRPtr, cnoOfPageRangeRec, pageRange);
+ seizePagerange(newRootPRPtr);
+ regFragPtr->rootPageRange = newRootPRPtr.i;
+ oldRootPRPtr.p->parentPtr = newRootPRPtr.i;
+
+ newRootPRPtr.p->basePageId[0] = oldRootPRPtr.i;
+ newRootPRPtr.p->parentPtr = RNIL;
+ newRootPRPtr.p->startRange[0] = 0;
+ newRootPRPtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
+ newRootPRPtr.p->type[0] = ZNON_LEAF;
+ newRootPRPtr.p->startRange[1] = regFragPtr->nextStartRange;
+ newRootPRPtr.p->endRange[1] = regFragPtr->nextStartRange - 1;
+ newRootPRPtr.p->type[1] = ZNON_LEAF;
+ newRootPRPtr.p->currentIndexPos = 1;
+ foundPageRangePtr = newRootPRPtr;
+ break;
+ } else {
+ ljam();
+ ptrCheckGuard(parentPageRangePtr, cnoOfPageRangeRec, pageRange);
+ if (parentPageRangePtr.p->currentIndexPos < 3) {
+ ljam();
+/* ---------------------------------------------------------------- */
+/* WE HAVE FOUND AN EMPTY ENTRY IN A PAGE RANGE RECORD. */
+/* ALLOCATE A NEW PAGE RANGE RECORD, FILL IN THE START RANGE, */
+/* ALLOCATE A NEW PAGE RANGE RECORD AND UPDATE THE POINTERS */
+/* ---------------------------------------------------------------- */
+ parentPageRangePtr.p->currentIndexPos++;
+ parentPageRangePtr.p->startRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;
+ parentPageRangePtr.p->endRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange - 1;
+ parentPageRangePtr.p->type[parentPageRangePtr.p->currentIndexPos] = ZNON_LEAF;
+ foundPageRangePtr = parentPageRangePtr;
+ break;
+ } else {
+ ljam();
+ ndbrequire(parentPageRangePtr.p->currentIndexPos == 3);
+/* ---------------------------------------------------------------- */
+/* THE PAGE RANGE RECORD WAS FULL. FIND THE PARENT RECORD */
+/* AND INCREASE THE NUMBER OF LEVELS WE HAVE TRAVERSED */
+/* GOING UP THE TREE. */
+/* ---------------------------------------------------------------- */
+ tiprNoLevels++;
+ }//if
+ }//if
+ }//while
+/* ---------------------------------------------------------------- */
+/* REMEMBER THE ERROR LEVEL IN CASE OF ALLOCATION ERRORS */
+/* ---------------------------------------------------------------- */
+ PageRangePtr newPageRangePtr;
+ PageRangePtr prevPageRangePtr;
+ prevPageRangePtr = foundPageRangePtr;
+ if (c_noOfFreePageRanges < tiprNoLevels) {
+ ljam();
+ return RNIL;
+ }//if
+/* ---------------------------------------------------------------- */
+/* NOW WE HAVE PERFORMED THE SEARCH UPWARDS AND FILLED IN THE */
+/* PROPER FIELDS IN THE PAGE RANGE RECORD WHERE SOME SPACE */
+/* WAS FOUND. THE NEXT STEP IS TO ALLOCATE PAGE RANGES SO */
+/* THAT WE KEEP THE B-TREE BALANCED. THE NEW PAGE RANGE */
+/* ARE ALSO PROPERLY UPDATED ON THE PATH TO THE LEAF LEVEL. */
+/* ---------------------------------------------------------------- */
+ while (true) {
+ ljam();
+ seizePagerange(newPageRangePtr);
+ tiprNoLevels--;
+ ndbrequire(prevPageRangePtr.p->currentIndexPos < 4);
+ prevPageRangePtr.p->basePageId[prevPageRangePtr.p->currentIndexPos] = newPageRangePtr.i;
+ newPageRangePtr.p->parentPtr = prevPageRangePtr.i;
+ newPageRangePtr.p->currentIndexPos = 0;
+ if (tiprNoLevels > 0) {
+ ljam();
+ newPageRangePtr.p->startRange[0] = regFragPtr->nextStartRange;
+ newPageRangePtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
+ newPageRangePtr.p->type[0] = ZNON_LEAF;
+ prevPageRangePtr = newPageRangePtr;
+ } else {
+ ljam();
+ break;
+ }//if
+ }//while
+ return newPageRangePtr.i;
+}//Dbtup::leafPageRangeFull()
+
+void Dbtup::releasePagerange(PageRangePtr regPRPtr)
+{
+ regPRPtr.p->nextFree = cfirstfreerange;
+ cfirstfreerange = regPRPtr.i;
+ c_noOfFreePageRanges++;
+}//Dbtup::releasePagerange()
+
+void Dbtup::seizePagerange(PageRangePtr& regPageRangePtr)
+{
+ regPageRangePtr.i = cfirstfreerange;
+ ptrCheckGuard(regPageRangePtr, cnoOfPageRangeRec, pageRange);
+ cfirstfreerange = regPageRangePtr.p->nextFree;
+ regPageRangePtr.p->nextFree = RNIL;
+ regPageRangePtr.p->currentIndexPos = 0;
+ regPageRangePtr.p->parentPtr = RNIL;
+ for (Uint32 i = 0; i < 4; i++) {
+ regPageRangePtr.p->startRange[i] = 1;
+ regPageRangePtr.p->endRange[i] = 0;
+ regPageRangePtr.p->type[i] = ZNON_LEAF;
+ regPageRangePtr.p->basePageId[i] = (Uint32)-1;
+ }//for
+ c_noOfFreePageRanges--;
+}//Dbtup::seizePagerange()
+
+void Dbtup::errorHandler(Uint32 errorCode)
+{
+ switch (errorCode) {
+ case 0:
+ ljam();
+ break;
+ case 1:
+ ljam();
+ break;
+ case 2:
+ ljam();
+ break;
+ default:
+ ljam();
+ }
+ ndbrequire(false);
+}//Dbtup::errorHandler()