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

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(22000 + __LINE__); }
  19. #define ljamEntry() { jamEntryLine(22000 + __LINE__); }
  20. /* **************************************************************** */
  21. /* *********** TABLE DESCRIPTOR MEMORY MANAGER ******************** */
  22. /* **************************************************************** */
  23. /* This module is used to allocate and deallocate table descriptor  */
  24. /* memory attached to fragments (could be allocated per table       */
  25. /* instead. Performs its task by a buddy algorithm.                 */
  26. /* **************************************************************** */
  27. Uint32
  28. Dbtup::getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset)
  29. {
  30.   // belongs to configure.in
  31.   unsigned sizeOfPointer = sizeof(CHARSET_INFO*);
  32.   ndbrequire((sizeOfPointer & 0x3) == 0);
  33.   sizeOfPointer = (sizeOfPointer >> 2);
  34.   // do in layout order and return offsets (see DbtupMeta.cpp)
  35.   Uint32 allocSize = 0;
  36.   // magically aligned to 8 bytes
  37.   offset[0] = allocSize += ZTD_SIZE;
  38.   offset[1] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction();
  39.   offset[2] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction();
  40.   offset[3] = allocSize += regTabPtr->noOfCharsets * sizeOfPointer;
  41.   offset[4] = allocSize += regTabPtr->noOfKeyAttr;
  42.   offset[5] = allocSize += regTabPtr->noOfAttributeGroups;
  43.   allocSize += regTabPtr->noOfAttr * ZAD_SIZE;
  44.   allocSize += ZTD_TRAILER_SIZE;
  45.   // return number of words
  46.   return allocSize;
  47. }
  48. Uint32 Dbtup::allocTabDescr(const Tablerec* regTabPtr, Uint32* offset)
  49. {
  50.   Uint32 reference = RNIL;
  51.   Uint32 allocSize = getTabDescrOffsets(regTabPtr, offset);
  52. /* ---------------------------------------------------------------- */
  53. /*       ALWAYS ALLOCATE A MULTIPLE OF 16 BYTES                     */
  54. /* ---------------------------------------------------------------- */
  55.   allocSize = (((allocSize - 1) >> 4) + 1) << 4;
  56.   Uint32 list = nextHigherTwoLog(allocSize - 1); /* CALCULATE WHICH LIST IT BELONGS TO     */
  57.   for (Uint32 i = list; i < 16; i++) {
  58.     ljam();
  59.     if (cfreeTdList[i] != RNIL) {
  60.       ljam();
  61.       reference = cfreeTdList[i];
  62.       removeTdArea(reference, i);                 /* REMOVE THE AREA FROM THE FREELIST      */
  63.       Uint32 retNo = (1 << i) - allocSize;         /* CALCULATE THE DIFFERENCE               */
  64.       if (retNo >= ZTD_FREE_SIZE) {
  65.         ljam();
  66.         Uint32 retRef = reference + allocSize;          /* SET THE RETURN POINTER                 */
  67.         retNo = itdaMergeTabDescr(retRef, retNo);       /* MERGE WITH POSSIBLE RIGHT NEIGHBOURS   */
  68.         freeTabDescr(retRef, retNo);                 /* RETURN UNUSED TD SPACE TO THE TD AREA  */
  69.       } else {
  70.         ljam();
  71.         allocSize = 1 << i;
  72.       }//if
  73.       break;
  74.     }//if
  75.   }//for
  76.   if (reference == RNIL) {
  77.     ljam();
  78.     terrorCode = ZMEM_NOTABDESCR_ERROR;
  79.     return RNIL;
  80.   } else {
  81.     ljam();
  82.     setTabDescrWord((reference + allocSize) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
  83.     setTabDescrWord(reference + ZTD_DATASIZE, allocSize);
  84.      /* INITIALIZE THE TRAILER RECORD WITH TYPE AND SIZE     */
  85.      /* THE TRAILER IS USED TO SIMPLIFY MERGE OF FREE AREAS  */
  86.     setTabDescrWord(reference + ZTD_HEADER, ZTD_TYPE_NORMAL);
  87.     setTabDescrWord((reference + allocSize) - ZTD_TR_SIZE, allocSize);
  88.     return reference;
  89.   }//if
  90. }//Dbtup::allocTabDescr()
  91. void Dbtup::freeTabDescr(Uint32 retRef, Uint32 retNo) 
  92. {
  93.   while (retNo >= ZTD_FREE_SIZE) {
  94.     ljam();
  95.     Uint32 list = nextHigherTwoLog(retNo);
  96.     list--; /* RETURN TO NEXT LOWER LIST    */
  97.     Uint32 sizeOfChunk = 1 << list;
  98.     insertTdArea(sizeOfChunk, retRef, list);
  99.     retRef += sizeOfChunk;
  100.     retNo -= sizeOfChunk;
  101.   }//while
  102. }//Dbtup::freeTabDescr()
  103. Uint32
  104. Dbtup::getTabDescrWord(Uint32 index)
  105. {
  106.   ndbrequire(index < cnoOfTabDescrRec);
  107.   return tableDescriptor[index].tabDescr;
  108. }//Dbtup::getTabDescrWord()
  109. void
  110. Dbtup::setTabDescrWord(Uint32 index, Uint32 word)
  111. {
  112.   ndbrequire(index < cnoOfTabDescrRec);
  113.   tableDescriptor[index].tabDescr = word;
  114. }//Dbtup::setTabDescrWord()
  115. void Dbtup::insertTdArea(Uint32 sizeOfChunk, Uint32 tabDesRef, Uint32 list) 
  116. {
  117.   ndbrequire(list < 16);
  118.   setTabDescrWord(tabDesRef + ZTD_FL_HEADER, ZTD_TYPE_FREE);
  119.   setTabDescrWord(tabDesRef + ZTD_FL_NEXT, cfreeTdList[list]);
  120.   if (cfreeTdList[list] != RNIL) {
  121.     ljam();                                                /* PREVIOUSLY EMPTY SLOT     */
  122.     setTabDescrWord(cfreeTdList[list] + ZTD_FL_PREV, tabDesRef);
  123.   }//if
  124.   cfreeTdList[list] = tabDesRef; /* RELINK THE LIST           */
  125.   setTabDescrWord(tabDesRef + ZTD_FL_PREV, RNIL);
  126.   setTabDescrWord(tabDesRef + ZTD_FL_SIZE, 1 << list);
  127.   setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_FREE);
  128.   setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_SIZE, 1 << list);
  129. }//Dbtup::insertTdArea()
  130. /* ---------------------------------------------------------------- */
  131. /* ----------------------- MERGE_TAB_DESCR ------------------------ */
  132. /* ---------------------------------------------------------------- */
  133. /* INPUT:  TAB_DESCR_PTR   POINTING AT THE CURRENT CHUNK            */
  134. /*                                                                  */
  135. /* SHORTNAME:   MTD                                                 */
  136. /* -----------------------------------------------------------------*/
  137. Uint32 Dbtup::itdaMergeTabDescr(Uint32 retRef, Uint32 retNo) 
  138. {
  139.    /* THE SIZE OF THE PART TO MERGE MUST BE OF THE SAME SIZE AS THE INSERTED PART */
  140.    /* THIS IS TRUE EITHER IF ONE PART HAS THE SAME SIZE OR THE SUM OF BOTH PARTS  */
  141.    /* TOGETHER HAS THE SAME SIZE AS THE PART TO BE INSERTED                       */
  142.    /* FIND THE SIZES OF THE PARTS TO THE RIGHT OF THE PART TO BE REINSERTED */
  143.   while ((retRef + retNo) < cnoOfTabDescrRec) {
  144.     ljam();
  145.     Uint32 tabDesRef = retRef + retNo;
  146.     Uint32 headerWord = getTabDescrWord(tabDesRef + ZTD_FL_HEADER);
  147.     if (headerWord == ZTD_TYPE_FREE) {
  148.       ljam();
  149.       Uint32 sizeOfMergedPart = getTabDescrWord(tabDesRef + ZTD_FL_SIZE);
  150.       retNo += sizeOfMergedPart;
  151.       Uint32 list = nextHigherTwoLog(sizeOfMergedPart - 1);
  152.       removeTdArea(tabDesRef, list);
  153.     } else {
  154.       ljam();
  155.       return retNo;
  156.     }//if
  157.   }//while
  158.   ndbrequire((retRef + retNo) == cnoOfTabDescrRec);
  159.   return retNo;
  160. }//Dbtup::itdaMergeTabDescr()
  161. /* ---------------------------------------------------------------- */
  162. /* ------------------------ REMOVE_TD_AREA ------------------------ */
  163. /* ---------------------------------------------------------------- */
  164. /*                                                                  */
  165. /* THIS ROUTINE REMOVES A TD CHUNK FROM THE POOL OF TD RECORDS      */
  166. /*                                                                  */
  167. /* INPUT:  TLIST          LIST TO USE                               */
  168. /*         TAB_DESCR_PTR  POINTS TO THE CHUNK TO BE REMOVED         */
  169. /*                                                                  */
  170. /* SHORTNAME:   RMTA                                                */
  171. /* -----------------------------------------------------------------*/
  172. void Dbtup::removeTdArea(Uint32 tabDesRef, Uint32 list) 
  173. {
  174.   ndbrequire(list < 16);
  175.   Uint32 tabDescrNextPtr = getTabDescrWord(tabDesRef + ZTD_FL_NEXT);
  176.   Uint32 tabDescrPrevPtr = getTabDescrWord(tabDesRef + ZTD_FL_PREV);
  177.   setTabDescrWord(tabDesRef + ZTD_HEADER, ZTD_TYPE_NORMAL);
  178.   setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
  179.   if (tabDesRef == cfreeTdList[list]) {
  180.     ljam();
  181.     cfreeTdList[list] = tabDescrNextPtr; /* RELINK THE LIST           */
  182.   }//if
  183.   if (tabDescrNextPtr != RNIL) {
  184.     ljam();
  185.     setTabDescrWord(tabDescrNextPtr + ZTD_FL_PREV, tabDescrPrevPtr);
  186.   }//if
  187.   if (tabDescrPrevPtr != RNIL) {
  188.     ljam();
  189.     setTabDescrWord(tabDescrPrevPtr + ZTD_FL_NEXT, tabDescrNextPtr);
  190.   }//if
  191. }//Dbtup::removeTdArea()