DbtupPageMap.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:21k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBTUP_C
  14. #include "Dbtup.hpp"
  15. #include <RefConvert.hpp>
  16. #include <ndb_limits.h>
  17. #include <pc.hpp>
  18. #define ljam() { jamLine(14000 + __LINE__); }
  19. #define ljamEntry() { jamEntryLine(14000 + __LINE__); }
  20. //
  21. // PageMap is a service used by Dbtup to map logical page id's to physical
  22. // page id's. The mapping is needs the fragment and the logical page id to
  23. // provide the physical id.
  24. //
  25. // This is a part of Dbtup which is the exclusive user of a certain set of
  26. // variables on the fragment record and it is the exclusive user of the
  27. // struct for page ranges.
  28. //
  29. //
  30. // The following methods operate on the data handled by the page map class.
  31. //
  32. // Public methods
  33. // insertPageRange(Uint32 startPageId,     # In
  34. //                 Uint32 noPages)         # In
  35. // Inserts a range of pages into the mapping structure.
  36. //
  37. // void releaseFragPages()
  38. // Releases all pages and their mappings belonging to a fragment.
  39. //
  40. // Uint32 allocFragPages(Uint32 tafpNoAllocRequested)
  41. // Allocate a set of pages to the fragment from the page manager
  42. //
  43. // Uint32 getEmptyPage()
  44. // Get an empty page from the pool of empty pages on the fragment.
  45. // It returns the physical page id of the empty page.
  46. // Returns RNIL if no empty page is available.
  47. //
  48. // Uint32 getRealpid(Uint32 logicalPageId)
  49. // Return the physical page id provided the logical page id
  50. //
  51. // void initializePageRange()
  52. // Initialise free list of page ranges and initialise the page raneg records.
  53. //
  54. // void initFragRange()
  55. // Initialise the fragment variables when allocating a fragment to a table.
  56. //
  57. // void initPageRangeSize(Uint32 size)
  58. // Initialise the number of page ranges.
  59. //
  60. // Uint32 getNoOfPages()
  61. // Get the number of pages on the fragment currently.
  62. //
  63. //
  64. // Private methods
  65. // Uint32 leafPageRangeFull(PageRangePtr currPageRangePtr)
  66. //
  67. // void errorHandler()
  68. // Method to crash NDB kernel in case of weird data set-up
  69. //
  70. // void allocMoreFragPages()
  71. // When no more empty pages are attached to the fragment and we need more
  72. // we allocate more pages from the page manager using this method.
  73. //
  74. // Private data
  75. // On the fragment record
  76. // currentPageRange    # The current page range where to insert the next range
  77. // rootPageRange       # The root of the page ranges owned
  78. // nextStartRange      # The next page id to assign when expanding the
  79. //                     # page map
  80. // noOfPages           # The number of pages in the fragment
  81. // emptyPrimPage       # The first page of the empty pages in the fragment
  82. //
  83. // The full page range struct
  84. Uint32 Dbtup::getEmptyPage(Fragrecord* const regFragPtr)
  85. {
  86.   Uint32 logicalPageId = regFragPtr->emptyPrimPage;
  87.   if (logicalPageId == RNIL) {
  88.     ljam();
  89.     allocMoreFragPages(regFragPtr);
  90.     logicalPageId = regFragPtr->emptyPrimPage;
  91.     if (logicalPageId == RNIL) {
  92.       ljam();
  93.       return RNIL;
  94.     }//if
  95.   }//if
  96.   Uint32 physicalPageId = getRealpid(regFragPtr, logicalPageId);
  97.   PagePtr pagePtr;
  98.   pagePtr.i = physicalPageId;
  99.   ptrCheckGuard(pagePtr, cnoOfPage, page);
  100.   regFragPtr->emptyPrimPage = pagePtr.p->pageWord[ZPAGE_NEXT_POS];
  101.   return physicalPageId;
  102. }//Dbtup::getEmptyPage()
  103. Uint32 Dbtup::getRealpid(Fragrecord*  const regFragPtr, Uint32 logicalPageId) 
  104. {
  105.   PageRangePtr grpPageRangePtr;
  106.   Uint32 loopLimit;
  107.   Uint32 loopCount = 0;
  108.   Uint32 pageRangeLimit = cnoOfPageRangeRec;
  109.   grpPageRangePtr.i = regFragPtr->rootPageRange;
  110.   while (true) {
  111.     ndbrequire(loopCount++ < 100);
  112.     ndbrequire(grpPageRangePtr.i < pageRangeLimit);
  113.     ptrAss(grpPageRangePtr, pageRange);
  114.     loopLimit = grpPageRangePtr.p->currentIndexPos;
  115.     ndbrequire(loopLimit <= 3);
  116.     for (Uint32 i = 0; i <= loopLimit; i++) {
  117.       ljam();
  118.       if (grpPageRangePtr.p->startRange[i] <= logicalPageId) {
  119.         if (grpPageRangePtr.p->endRange[i] >= logicalPageId) {
  120.           if (grpPageRangePtr.p->type[i] == ZLEAF) {
  121.             ljam();
  122.             Uint32 realPageId = (logicalPageId - grpPageRangePtr.p->startRange[i]) +
  123.                                  grpPageRangePtr.p->basePageId[i];
  124.             return realPageId;
  125.           } else {
  126.             ndbrequire(grpPageRangePtr.p->type[i] == ZNON_LEAF);
  127.             grpPageRangePtr.i = grpPageRangePtr.p->basePageId[i];
  128.           }//if
  129.         }//if
  130.       }//if
  131.     }//for
  132.   }//while
  133.   return 0;
  134. }//Dbtup::getRealpid()
  135. Uint32 Dbtup::getNoOfPages(Fragrecord* const regFragPtr)
  136. {
  137.   return regFragPtr->noOfPages;
  138. }//Dbtup::getNoOfPages()
  139. void Dbtup::initPageRangeSize(Uint32 size)
  140. {
  141.   cnoOfPageRangeRec = size;
  142. }//Dbtup::initPageRangeSize()
  143. /* ---------------------------------------------------------------- */
  144. /* ----------------------- INSERT_PAGE_RANGE_TAB ------------------ */
  145. /* ---------------------------------------------------------------- */
  146. /*       INSERT A PAGE RANGE INTO THE FRAGMENT                      */
  147. /*                                                                  */
  148. /*       NOTE:   THE METHOD IS ATOMIC. EITHER THE ACTION IS         */
  149. /*               PERFORMED FULLY OR NO ACTION IS PERFORMED AT ALL.  */
  150. /*               TO SUPPORT THIS THE CODE HAS A CLEANUP PART AFTER  */
  151. /*               ERRORS.                                            */
  152. /* ---------------------------------------------------------------- */
  153. bool Dbtup::insertPageRangeTab(Fragrecord*  const regFragPtr,
  154.                                Uint32 startPageId,
  155.                                Uint32 noPages) 
  156. {
  157.   PageRangePtr currPageRangePtr;
  158.   if (cfirstfreerange == RNIL) {
  159.     ljam();
  160.     return false;
  161.   }//if
  162.   currPageRangePtr.i = regFragPtr->currentPageRange;
  163.   if (currPageRangePtr.i == RNIL) {
  164.     ljam();
  165. /* ---------------------------------------------------------------- */
  166. /*       THE FIRST PAGE RANGE IS HANDLED WITH SPECIAL CODE          */
  167. /* ---------------------------------------------------------------- */
  168.     seizePagerange(currPageRangePtr);
  169.     regFragPtr->rootPageRange = currPageRangePtr.i;
  170.     currPageRangePtr.p->currentIndexPos = 0;
  171.     currPageRangePtr.p->parentPtr = RNIL;
  172.   } else {
  173.     ljam();
  174.     ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange);
  175.     if (currPageRangePtr.p->currentIndexPos < 3) {
  176.       ljam();
  177. /* ---------------------------------------------------------------- */
  178. /*       THE SIMPLE CASE WHEN IT IS ONLY NECESSARY TO FILL IN THE   */
  179. /*       NEXT EMPTY POSITION IN THE PAGE RANGE RECORD IS TREATED    */
  180. /*       BY COMMON CODE AT THE END OF THE SUBROUTINE.               */
  181. /* ---------------------------------------------------------------- */
  182.       currPageRangePtr.p->currentIndexPos++;
  183.     } else {
  184.       ljam();
  185.       ndbrequire(currPageRangePtr.p->currentIndexPos == 3);
  186.       currPageRangePtr.i = leafPageRangeFull(regFragPtr, currPageRangePtr);
  187.       if (currPageRangePtr.i == RNIL) {
  188.         return false;
  189.       }//if
  190.       ptrCheckGuard(currPageRangePtr, cnoOfPageRangeRec, pageRange);
  191.     }//if
  192.   }//if
  193.   currPageRangePtr.p->startRange[currPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;
  194. /* ---------------------------------------------------------------- */
  195. /*       NOW SET THE LEAF LEVEL PAGE RANGE RECORD PROPERLY          */
  196. /*       PAGE_RANGE_PTR REFERS TO LEAF RECORD WHEN ARRIVING HERE    */
  197. /* ---------------------------------------------------------------- */
  198.   currPageRangePtr.p->endRange[currPageRangePtr.p->currentIndexPos] = 
  199.                                                    (regFragPtr->nextStartRange + noPages) - 1;
  200.   currPageRangePtr.p->basePageId[currPageRangePtr.p->currentIndexPos] = startPageId;
  201.   currPageRangePtr.p->type[currPageRangePtr.p->currentIndexPos] = ZLEAF;
  202. /* ---------------------------------------------------------------- */
  203. /*       WE NEED TO UPDATE THE CURRENT PAGE RANGE IN CASE IT HAS    */
  204. /*       CHANGED. WE ALSO NEED TO UPDATE THE NEXT START RANGE       */
  205. /* ---------------------------------------------------------------- */
  206.   regFragPtr->currentPageRange = currPageRangePtr.i;
  207.   regFragPtr->nextStartRange += noPages;
  208. /* ---------------------------------------------------------------- */
  209. /*       WE NEED TO UPDATE THE END RANGE IN ALL PAGE RANGE RECORDS  */
  210. /*       UP TO THE ROOT.                                            */
  211. /* ---------------------------------------------------------------- */
  212.   PageRangePtr loopPageRangePtr;
  213.   loopPageRangePtr = currPageRangePtr;
  214.   while (true) {
  215.     ljam();
  216.     loopPageRangePtr.i = loopPageRangePtr.p->parentPtr;
  217.     if (loopPageRangePtr.i != RNIL) {
  218.       ljam();
  219.       ptrCheckGuard(loopPageRangePtr, cnoOfPageRangeRec, pageRange);
  220.       ndbrequire(loopPageRangePtr.p->currentIndexPos < 4);
  221.       loopPageRangePtr.p->endRange[loopPageRangePtr.p->currentIndexPos] += noPages;
  222.     } else {
  223.       ljam();
  224.       break;
  225.     }//if
  226.   }//while
  227.   regFragPtr->noOfPages += noPages;
  228.   return true;
  229. }//Dbtup::insertPageRangeTab()
  230. void Dbtup::releaseFragPages(Fragrecord* const regFragPtr) 
  231. {
  232.   if (regFragPtr->rootPageRange == RNIL) {
  233.     ljam();
  234.     return;
  235.   }//if
  236.   PageRangePtr regPRPtr;
  237.   regPRPtr.i = regFragPtr->rootPageRange;
  238.   ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
  239.   while (true) {
  240.     ljam();
  241.     const Uint32 indexPos = regPRPtr.p->currentIndexPos;
  242.     ndbrequire(indexPos < 4);
  243.     const Uint32 basePageId = regPRPtr.p->basePageId[indexPos];
  244.     regPRPtr.p->basePageId[indexPos] = RNIL;
  245.     if (basePageId == RNIL) {
  246.       ljam();
  247.       /**
  248.        * Finished with indexPos continue with next
  249.        */
  250.       if (indexPos > 0) {
  251.         ljam();
  252. regPRPtr.p->currentIndexPos--;
  253. continue;
  254.       }//if
  255.       
  256.       /* ---------------------------------------------------------------- */
  257.       /* THE PAGE RANGE REC IS EMPTY. RELEASE IT.                         */
  258.       /*----------------------------------------------------------------- */
  259.       Uint32 parentPtr = regPRPtr.p->parentPtr;
  260.       releasePagerange(regPRPtr);
  261.       
  262.       if (parentPtr != RNIL) {
  263. ljam();
  264. regPRPtr.i = parentPtr;
  265. ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
  266. continue;
  267.       }//if
  268.       ljam();
  269.       ndbrequire(regPRPtr.i == regFragPtr->rootPageRange);
  270.       initFragRange(regFragPtr);
  271.       return;
  272.     } else {
  273.       if (regPRPtr.p->type[indexPos] == ZNON_LEAF) {
  274.         jam();
  275. /* ---------------------------------------------------------------- */
  276. // A non-leaf node, we must release everything below it before we 
  277. // release this node.
  278. /* ---------------------------------------------------------------- */
  279.         regPRPtr.i = basePageId;
  280.         ptrCheckGuard(regPRPtr, cnoOfPageRangeRec, pageRange);
  281.       } else {
  282.         jam();
  283.         ndbrequire(regPRPtr.p->type[indexPos] == ZLEAF);
  284. /* ---------------------------------------------------------------- */
  285. /* PAGE_RANGE_PTR /= RNIL AND THE CURRENT POS IS NOT A CHLED.       */
  286. /*----------------------------------------------------------------- */
  287. const Uint32 start = regPRPtr.p->startRange[indexPos];
  288. const Uint32 stop = regPRPtr.p->endRange[indexPos];
  289. ndbrequire(stop >= start);
  290. const Uint32 retNo = (stop - start + 1);
  291. returnCommonArea(basePageId, retNo);
  292.       }//if
  293.     }//if
  294.   }//while
  295. }//Dbtup::releaseFragPages()
  296. void Dbtup::initializePageRange() 
  297. {
  298.   PageRangePtr regPTRPtr;
  299.   for (regPTRPtr.i = 0;
  300.        regPTRPtr.i < cnoOfPageRangeRec; regPTRPtr.i++) {
  301.     ptrAss(regPTRPtr, pageRange);
  302.     regPTRPtr.p->nextFree = regPTRPtr.i + 1;
  303.   }//for
  304.   regPTRPtr.i = cnoOfPageRangeRec - 1;
  305.   ptrAss(regPTRPtr, pageRange);
  306.   regPTRPtr.p->nextFree = RNIL;
  307.   cfirstfreerange = 0;
  308.   c_noOfFreePageRanges = cnoOfPageRangeRec;
  309. }//Dbtup::initializePageRange()
  310. void Dbtup::initFragRange(Fragrecord* const regFragPtr)
  311. {
  312.   regFragPtr->emptyPrimPage = RNIL;
  313.   regFragPtr->rootPageRange = RNIL;
  314.   regFragPtr->currentPageRange = RNIL;
  315.   regFragPtr->noOfPages = 0;
  316.   regFragPtr->nextStartRange = 0;
  317. }//initFragRange()
  318. Uint32 Dbtup::allocFragPages(Fragrecord* const regFragPtr, Uint32 tafpNoAllocRequested) 
  319. {
  320.   Uint32 tafpPagesAllocated = 0;
  321.   while (true) {
  322.     Uint32 noOfPagesAllocated = 0;
  323.     Uint32 noPagesToAllocate = tafpNoAllocRequested - tafpPagesAllocated;
  324.     Uint32 retPageRef = RNIL;
  325.     allocConsPages(noPagesToAllocate, noOfPagesAllocated, retPageRef);
  326.     if (noOfPagesAllocated == 0) {
  327.       ljam();
  328.       return tafpPagesAllocated;
  329.     }//if
  330. /* ---------------------------------------------------------------- */
  331. /*       IT IS NOW TIME TO PUT THE ALLOCATED AREA INTO THE PAGE     */
  332. /*       RANGE TABLE.                                               */
  333. /* ---------------------------------------------------------------- */
  334.     Uint32 startRange = regFragPtr->nextStartRange;
  335.     if (!insertPageRangeTab(regFragPtr, retPageRef, noOfPagesAllocated)) {
  336.       ljam();
  337.       returnCommonArea(retPageRef, noOfPagesAllocated);
  338.       return tafpPagesAllocated;
  339.     }//if
  340.     tafpPagesAllocated += noOfPagesAllocated;
  341.     Uint32 loopLimit = retPageRef + noOfPagesAllocated;
  342.     PagePtr loopPagePtr;
  343. /* ---------------------------------------------------------------- */
  344. /*       SINCE A NUMBER OF PAGES WERE ALLOCATED FROM COMMON AREA    */
  345. /*       WITH SUCCESS IT IS NOW TIME TO CHANGE THE STATE OF         */
  346. /*       THOSE PAGES TO EMPTY_MM AND LINK THEM INTO THE EMPTY       */
  347. /*       PAGE LIST OF THE FRAGMENT.                                 */
  348. /* ---------------------------------------------------------------- */
  349.     for (loopPagePtr.i = retPageRef; loopPagePtr.i < loopLimit; loopPagePtr.i++) {
  350.       ljam();
  351.       ptrCheckGuard(loopPagePtr, cnoOfPage, page);
  352.       loopPagePtr.p->pageWord[ZPAGE_STATE_POS] = ZEMPTY_MM;
  353.       loopPagePtr.p->pageWord[ZPAGE_FRAG_PAGE_ID_POS] = startRange +
  354.                                                         (loopPagePtr.i - retPageRef);
  355.       loopPagePtr.p->pageWord[ZPAGE_NEXT_POS] = loopPagePtr.p->pageWord[ZPAGE_FRAG_PAGE_ID_POS] + 1;
  356.     }//for
  357.     loopPagePtr.i = (retPageRef + noOfPagesAllocated) - 1;
  358.     ptrCheckGuard(loopPagePtr, cnoOfPage, page);
  359.     loopPagePtr.p->pageWord[ZPAGE_NEXT_POS] = regFragPtr->emptyPrimPage;
  360.     regFragPtr->emptyPrimPage = startRange;
  361. /* ---------------------------------------------------------------- */
  362. /*       WAS ENOUGH PAGES ALLOCATED OR ARE MORE NEEDED.             */
  363. /* ---------------------------------------------------------------- */
  364.     if (tafpPagesAllocated < tafpNoAllocRequested) {
  365.       ljam();
  366.     } else {
  367.       ndbrequire(tafpPagesAllocated == tafpNoAllocRequested);
  368.       ljam();
  369.       return tafpNoAllocRequested;
  370.     }//if
  371.   }//while
  372. }//Dbtup::allocFragPages()
  373. void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr) 
  374. {
  375.   Uint32 noAllocPages = regFragPtr->noOfPages >> 3; // 12.5%
  376.   noAllocPages += regFragPtr->noOfPages >> 4; // 6.25%
  377.   noAllocPages += 2;
  378. /* -----------------------------------------------------------------*/
  379. // We will grow by 18.75% plus two more additional pages to grow
  380. // a little bit quicker in the beginning.
  381. /* -----------------------------------------------------------------*/
  382.   allocFragPages(regFragPtr, noAllocPages);
  383. }//Dbtup::allocMoreFragPages()
  384. Uint32 Dbtup::leafPageRangeFull(Fragrecord*  const regFragPtr, PageRangePtr currPageRangePtr)
  385. {
  386. /* ---------------------------------------------------------------- */
  387. /*       THE COMPLEX CASE WHEN THE LEAF NODE IS FULL. GO UP THE TREE*/
  388. /*       TO FIND THE FIRST RECORD WITH A FREE ENTRY. ALLOCATE NEW   */
  389. /*       PAGE RANGE RECORDS THEN ALL THE WAY DOWN TO THE LEAF LEVEL */
  390. /*       AGAIN. THE TREE SHOULD ALWAYS REMAIN BALANCED.             */
  391. /* ---------------------------------------------------------------- */
  392.   PageRangePtr parentPageRangePtr;
  393.   PageRangePtr foundPageRangePtr;
  394.   parentPageRangePtr = currPageRangePtr;
  395.   Uint32 tiprNoLevels = 1;
  396.   while (true) {
  397.     ljam();
  398.     parentPageRangePtr.i = parentPageRangePtr.p->parentPtr;
  399.     if (parentPageRangePtr.i == RNIL) {
  400.       ljam();
  401. /* ---------------------------------------------------------------- */
  402. /*       WE HAVE REACHED THE ROOT. A NEW ROOT MUST BE ALLOCATED.    */
  403. /* ---------------------------------------------------------------- */
  404.       if (c_noOfFreePageRanges < tiprNoLevels) {
  405.         ljam();
  406.         return RNIL;
  407.       }//if
  408.       PageRangePtr oldRootPRPtr;
  409.       PageRangePtr newRootPRPtr;
  410.       oldRootPRPtr.i = regFragPtr->rootPageRange;
  411.       ptrCheckGuard(oldRootPRPtr, cnoOfPageRangeRec, pageRange);
  412.       seizePagerange(newRootPRPtr);
  413.       regFragPtr->rootPageRange = newRootPRPtr.i;
  414.       oldRootPRPtr.p->parentPtr = newRootPRPtr.i;
  415.       newRootPRPtr.p->basePageId[0] = oldRootPRPtr.i;
  416.       newRootPRPtr.p->parentPtr = RNIL;
  417.       newRootPRPtr.p->startRange[0] = 0;
  418.       newRootPRPtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
  419.       newRootPRPtr.p->type[0] = ZNON_LEAF;
  420.       newRootPRPtr.p->startRange[1] = regFragPtr->nextStartRange;
  421.       newRootPRPtr.p->endRange[1] = regFragPtr->nextStartRange - 1;
  422.       newRootPRPtr.p->type[1] = ZNON_LEAF;
  423.       newRootPRPtr.p->currentIndexPos = 1;
  424.       foundPageRangePtr = newRootPRPtr;
  425.       break;
  426.     } else {
  427.       ljam();
  428.       ptrCheckGuard(parentPageRangePtr, cnoOfPageRangeRec, pageRange);
  429.       if (parentPageRangePtr.p->currentIndexPos < 3) {
  430.         ljam();
  431. /* ---------------------------------------------------------------- */
  432. /*       WE HAVE FOUND AN EMPTY ENTRY IN A PAGE RANGE RECORD.       */
  433. /*       ALLOCATE A NEW PAGE RANGE RECORD, FILL IN THE START RANGE, */
  434. /*       ALLOCATE A NEW PAGE RANGE RECORD AND UPDATE THE POINTERS   */
  435. /* ---------------------------------------------------------------- */
  436.         parentPageRangePtr.p->currentIndexPos++;
  437.         parentPageRangePtr.p->startRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange;
  438.         parentPageRangePtr.p->endRange[parentPageRangePtr.p->currentIndexPos] = regFragPtr->nextStartRange - 1;
  439.         parentPageRangePtr.p->type[parentPageRangePtr.p->currentIndexPos] = ZNON_LEAF;
  440.         foundPageRangePtr = parentPageRangePtr;
  441.         break;
  442.       } else {
  443.         ljam();
  444.         ndbrequire(parentPageRangePtr.p->currentIndexPos == 3);
  445. /* ---------------------------------------------------------------- */
  446. /*       THE PAGE RANGE RECORD WAS FULL. FIND THE PARENT RECORD     */
  447. /*       AND INCREASE THE NUMBER OF LEVELS WE HAVE TRAVERSED        */
  448. /*       GOING UP THE TREE.                                         */
  449. /* ---------------------------------------------------------------- */
  450.         tiprNoLevels++;
  451.       }//if
  452.     }//if
  453.   }//while
  454. /* ---------------------------------------------------------------- */
  455. /*       REMEMBER THE ERROR LEVEL IN CASE OF ALLOCATION ERRORS      */
  456. /* ---------------------------------------------------------------- */
  457.   PageRangePtr newPageRangePtr;
  458.   PageRangePtr prevPageRangePtr;
  459.   prevPageRangePtr = foundPageRangePtr;
  460.   if (c_noOfFreePageRanges < tiprNoLevels) {
  461.     ljam();
  462.     return RNIL;
  463.   }//if
  464. /* ---------------------------------------------------------------- */
  465. /*       NOW WE HAVE PERFORMED THE SEARCH UPWARDS AND FILLED IN THE */
  466. /*       PROPER FIELDS IN THE PAGE RANGE RECORD WHERE SOME SPACE    */
  467. /*       WAS FOUND. THE NEXT STEP IS TO ALLOCATE PAGE RANGES SO     */
  468. /*       THAT WE KEEP THE B-TREE BALANCED. THE NEW PAGE RANGE       */
  469. /*       ARE ALSO PROPERLY UPDATED ON THE PATH TO THE LEAF LEVEL.   */
  470. /* ---------------------------------------------------------------- */
  471.   while (true) {
  472.     ljam();
  473.     seizePagerange(newPageRangePtr);
  474.     tiprNoLevels--;
  475.     ndbrequire(prevPageRangePtr.p->currentIndexPos < 4);
  476.     prevPageRangePtr.p->basePageId[prevPageRangePtr.p->currentIndexPos] = newPageRangePtr.i;
  477.     newPageRangePtr.p->parentPtr = prevPageRangePtr.i;
  478.     newPageRangePtr.p->currentIndexPos = 0;
  479.     if (tiprNoLevels > 0) {
  480.       ljam();
  481.       newPageRangePtr.p->startRange[0] = regFragPtr->nextStartRange;
  482.       newPageRangePtr.p->endRange[0] = regFragPtr->nextStartRange - 1;
  483.       newPageRangePtr.p->type[0] = ZNON_LEAF;
  484.       prevPageRangePtr = newPageRangePtr;
  485.     } else {
  486.       ljam();
  487.       break;
  488.     }//if
  489.   }//while
  490.   return newPageRangePtr.i;
  491. }//Dbtup::leafPageRangeFull()
  492. void Dbtup::releasePagerange(PageRangePtr regPRPtr) 
  493. {
  494.   regPRPtr.p->nextFree = cfirstfreerange;
  495.   cfirstfreerange = regPRPtr.i;
  496.   c_noOfFreePageRanges++;
  497. }//Dbtup::releasePagerange()
  498. void Dbtup::seizePagerange(PageRangePtr& regPageRangePtr) 
  499. {
  500.   regPageRangePtr.i = cfirstfreerange;
  501.   ptrCheckGuard(regPageRangePtr, cnoOfPageRangeRec, pageRange);
  502.   cfirstfreerange = regPageRangePtr.p->nextFree;
  503.   regPageRangePtr.p->nextFree = RNIL;
  504.   regPageRangePtr.p->currentIndexPos = 0;
  505.   regPageRangePtr.p->parentPtr = RNIL;
  506.   for (Uint32 i = 0; i < 4; i++) {
  507.     regPageRangePtr.p->startRange[i] = 1;
  508.     regPageRangePtr.p->endRange[i] = 0;
  509.     regPageRangePtr.p->type[i] = ZNON_LEAF;
  510.     regPageRangePtr.p->basePageId[i] = (Uint32)-1;
  511.   }//for
  512.   c_noOfFreePageRanges--;
  513. }//Dbtup::seizePagerange()
  514. void Dbtup::errorHandler(Uint32 errorCode)
  515. {
  516.   switch (errorCode) {
  517.   case 0:
  518.     ljam();
  519.     break;
  520.   case 1:
  521.     ljam();
  522.     break;
  523.   case 2:
  524.     ljam();
  525.     break;
  526.   default:
  527.     ljam();
  528.   }
  529.   ndbrequire(false);
  530. }//Dbtup::errorHandler()