summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp')
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
new file mode 100644
index 00000000000..642ba270760
--- /dev/null
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp
@@ -0,0 +1,212 @@
+/* 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(22000 + __LINE__); }
+#define ljamEntry() { jamEntryLine(22000 + __LINE__); }
+
+/* **************************************************************** */
+/* *********** TABLE DESCRIPTOR MEMORY MANAGER ******************** */
+/* **************************************************************** */
+/* This module is used to allocate and deallocate table descriptor */
+/* memory attached to fragments (could be allocated per table */
+/* instead. Performs its task by a buddy algorithm. */
+/* **************************************************************** */
+
+Uint32
+Dbtup::getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset)
+{
+ // belongs to configure.in
+ unsigned sizeOfPointer = sizeof(CHARSET_INFO*);
+ ndbrequire((sizeOfPointer & 0x3) == 0);
+ sizeOfPointer = (sizeOfPointer >> 2);
+ // do in layout order and return offsets (see DbtupMeta.cpp)
+ Uint32 allocSize = 0;
+ // magically aligned to 8 bytes
+ offset[0] = allocSize += ZTD_SIZE;
+ offset[1] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction();
+ offset[2] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction();
+ offset[3] = allocSize += regTabPtr->noOfCharsets * sizeOfPointer;
+ offset[4] = allocSize += regTabPtr->noOfKeyAttr;
+ offset[5] = allocSize += regTabPtr->noOfAttributeGroups;
+ allocSize += regTabPtr->noOfAttr * ZAD_SIZE;
+ allocSize += ZTD_TRAILER_SIZE;
+ // return number of words
+ return allocSize;
+}
+
+Uint32 Dbtup::allocTabDescr(const Tablerec* regTabPtr, Uint32* offset)
+{
+ Uint32 reference = RNIL;
+ Uint32 allocSize = getTabDescrOffsets(regTabPtr, offset);
+/* ---------------------------------------------------------------- */
+/* ALWAYS ALLOCATE A MULTIPLE OF 16 BYTES */
+/* ---------------------------------------------------------------- */
+ allocSize = (((allocSize - 1) >> 4) + 1) << 4;
+ Uint32 list = nextHigherTwoLog(allocSize - 1); /* CALCULATE WHICH LIST IT BELONGS TO */
+ for (Uint32 i = list; i < 16; i++) {
+ ljam();
+ if (cfreeTdList[i] != RNIL) {
+ ljam();
+ reference = cfreeTdList[i];
+ removeTdArea(reference, i); /* REMOVE THE AREA FROM THE FREELIST */
+ Uint32 retNo = (1 << i) - allocSize; /* CALCULATE THE DIFFERENCE */
+ if (retNo >= ZTD_FREE_SIZE) {
+ ljam();
+ Uint32 retRef = reference + allocSize; /* SET THE RETURN POINTER */
+ retNo = itdaMergeTabDescr(retRef, retNo); /* MERGE WITH POSSIBLE RIGHT NEIGHBOURS */
+ freeTabDescr(retRef, retNo); /* RETURN UNUSED TD SPACE TO THE TD AREA */
+ } else {
+ ljam();
+ allocSize = 1 << i;
+ }//if
+ break;
+ }//if
+ }//for
+ if (reference == RNIL) {
+ ljam();
+ terrorCode = ZMEM_NOTABDESCR_ERROR;
+ return RNIL;
+ } else {
+ ljam();
+ setTabDescrWord((reference + allocSize) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
+ setTabDescrWord(reference + ZTD_DATASIZE, allocSize);
+
+ /* INITIALIZE THE TRAILER RECORD WITH TYPE AND SIZE */
+ /* THE TRAILER IS USED TO SIMPLIFY MERGE OF FREE AREAS */
+
+ setTabDescrWord(reference + ZTD_HEADER, ZTD_TYPE_NORMAL);
+ setTabDescrWord((reference + allocSize) - ZTD_TR_SIZE, allocSize);
+ return reference;
+ }//if
+}//Dbtup::allocTabDescr()
+
+void Dbtup::freeTabDescr(Uint32 retRef, Uint32 retNo)
+{
+ while (retNo >= ZTD_FREE_SIZE) {
+ ljam();
+ Uint32 list = nextHigherTwoLog(retNo);
+ list--; /* RETURN TO NEXT LOWER LIST */
+ Uint32 sizeOfChunk = 1 << list;
+ insertTdArea(sizeOfChunk, retRef, list);
+ retRef += sizeOfChunk;
+ retNo -= sizeOfChunk;
+ }//while
+}//Dbtup::freeTabDescr()
+
+Uint32
+Dbtup::getTabDescrWord(Uint32 index)
+{
+ ndbrequire(index < cnoOfTabDescrRec);
+ return tableDescriptor[index].tabDescr;
+}//Dbtup::getTabDescrWord()
+
+void
+Dbtup::setTabDescrWord(Uint32 index, Uint32 word)
+{
+ ndbrequire(index < cnoOfTabDescrRec);
+ tableDescriptor[index].tabDescr = word;
+}//Dbtup::setTabDescrWord()
+
+void Dbtup::insertTdArea(Uint32 sizeOfChunk, Uint32 tabDesRef, Uint32 list)
+{
+ ndbrequire(list < 16);
+ setTabDescrWord(tabDesRef + ZTD_FL_HEADER, ZTD_TYPE_FREE);
+ setTabDescrWord(tabDesRef + ZTD_FL_NEXT, cfreeTdList[list]);
+ if (cfreeTdList[list] != RNIL) {
+ ljam(); /* PREVIOUSLY EMPTY SLOT */
+ setTabDescrWord(cfreeTdList[list] + ZTD_FL_PREV, tabDesRef);
+ }//if
+ cfreeTdList[list] = tabDesRef; /* RELINK THE LIST */
+
+ setTabDescrWord(tabDesRef + ZTD_FL_PREV, RNIL);
+ setTabDescrWord(tabDesRef + ZTD_FL_SIZE, 1 << list);
+ setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_FREE);
+ setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_SIZE, 1 << list);
+}//Dbtup::insertTdArea()
+
+/* ---------------------------------------------------------------- */
+/* ----------------------- MERGE_TAB_DESCR ------------------------ */
+/* ---------------------------------------------------------------- */
+/* INPUT: TAB_DESCR_PTR POINTING AT THE CURRENT CHUNK */
+/* */
+/* SHORTNAME: MTD */
+/* -----------------------------------------------------------------*/
+Uint32 Dbtup::itdaMergeTabDescr(Uint32 retRef, Uint32 retNo)
+{
+ /* THE SIZE OF THE PART TO MERGE MUST BE OF THE SAME SIZE AS THE INSERTED PART */
+ /* THIS IS TRUE EITHER IF ONE PART HAS THE SAME SIZE OR THE SUM OF BOTH PARTS */
+ /* TOGETHER HAS THE SAME SIZE AS THE PART TO BE INSERTED */
+ /* FIND THE SIZES OF THE PARTS TO THE RIGHT OF THE PART TO BE REINSERTED */
+ while ((retRef + retNo) < cnoOfTabDescrRec) {
+ ljam();
+ Uint32 tabDesRef = retRef + retNo;
+ Uint32 headerWord = getTabDescrWord(tabDesRef + ZTD_FL_HEADER);
+ if (headerWord == ZTD_TYPE_FREE) {
+ ljam();
+ Uint32 sizeOfMergedPart = getTabDescrWord(tabDesRef + ZTD_FL_SIZE);
+
+ retNo += sizeOfMergedPart;
+ Uint32 list = nextHigherTwoLog(sizeOfMergedPart - 1);
+ removeTdArea(tabDesRef, list);
+ } else {
+ ljam();
+ return retNo;
+ }//if
+ }//while
+ ndbrequire((retRef + retNo) == cnoOfTabDescrRec);
+ return retNo;
+}//Dbtup::itdaMergeTabDescr()
+
+/* ---------------------------------------------------------------- */
+/* ------------------------ REMOVE_TD_AREA ------------------------ */
+/* ---------------------------------------------------------------- */
+/* */
+/* THIS ROUTINE REMOVES A TD CHUNK FROM THE POOL OF TD RECORDS */
+/* */
+/* INPUT: TLIST LIST TO USE */
+/* TAB_DESCR_PTR POINTS TO THE CHUNK TO BE REMOVED */
+/* */
+/* SHORTNAME: RMTA */
+/* -----------------------------------------------------------------*/
+void Dbtup::removeTdArea(Uint32 tabDesRef, Uint32 list)
+{
+ ndbrequire(list < 16);
+ Uint32 tabDescrNextPtr = getTabDescrWord(tabDesRef + ZTD_FL_NEXT);
+ Uint32 tabDescrPrevPtr = getTabDescrWord(tabDesRef + ZTD_FL_PREV);
+
+ setTabDescrWord(tabDesRef + ZTD_HEADER, ZTD_TYPE_NORMAL);
+ setTabDescrWord((tabDesRef + (1 << list)) - ZTD_TR_TYPE, ZTD_TYPE_NORMAL);
+
+ if (tabDesRef == cfreeTdList[list]) {
+ ljam();
+ cfreeTdList[list] = tabDescrNextPtr; /* RELINK THE LIST */
+ }//if
+ if (tabDescrNextPtr != RNIL) {
+ ljam();
+ setTabDescrWord(tabDescrNextPtr + ZTD_FL_PREV, tabDescrPrevPtr);
+ }//if
+ if (tabDescrPrevPtr != RNIL) {
+ ljam();
+ setTabDescrWord(tabDescrPrevPtr + ZTD_FL_NEXT, tabDescrNextPtr);
+ }//if
+}//Dbtup::removeTdArea()