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

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. #include "GCIContainer.hpp"
  14. #include <NdbOut.hpp>
  15. #include <NdbMem.h>
  16. #include <new>
  17. #include <rep/rep_version.hpp>
  18. //#define GCICONTAINER_DEBUG
  19. /*****************************************************************************
  20.  * Constructors / Destructors
  21.  *****************************************************************************/
  22. GCIContainer::GCIContainer(Uint32 maxNoOfIds) 
  23. {
  24.   m_maxNoOfIds = maxNoOfIds;
  25.   gciRange = new GCIRange[maxNoOfIds * sizeof(GCIRange)];
  26.   
  27.   for(Uint32 i = 0; i < maxNoOfIds; i++) {
  28.     gciRange[i].m_firstGCI = 1;  // The empty interval = [1,0]
  29.     gciRange[i].m_lastGCI = 0;
  30.   }
  31.   theMutexPtr = NdbMutex_Create();
  32. }
  33. GCIContainer::~GCIContainer() 
  34. {
  35.   for(Uint32 i=0; i < m_bufferList.size(); i++) {
  36.     delete m_bufferList[i];
  37.     m_bufferList[i] = 0;
  38.   }
  39.   m_bufferList=0;
  40.   delete [] gciRange;
  41.   NdbMutex_Destroy(theMutexPtr);
  42. }
  43. /*****************************************************************************
  44.  * GCIBuffer Create / Destroy
  45.  *****************************************************************************/
  46. GCIBuffer * 
  47. GCIContainer::createGCIBuffer(Uint32 gci, Uint32 id) 
  48. {
  49.   GCIBuffer * buf = new GCIBuffer(gci, id);
  50.   if (buf == NULL) REPABORT("Could not allocate new buffer");
  51.   
  52.   m_bufferList.push_back(buf, true);
  53.   
  54. #ifdef GCICONTAINER_DEBUG
  55.   ndbout_c("GCIContainer: New buffer created (GCI: %d, Id: %d)", gci, id);
  56. #endif
  57.   return buf;
  58. }
  59. /**
  60.  * Delete all GCI buffers strictly less than "gci"
  61.  */
  62. void
  63. GCIContainer::destroyGCIBuffersBeforeGCI(Uint32 gci, Uint32 id) 
  64. {
  65.   for(Uint32 i = 0 ; i < m_bufferList.size(); i++) {
  66.     if(m_bufferList[i]->getGCI() < gci) {
  67. #ifdef GCICONTAINER_DEBUG
  68.       ndbout_c("GCIContainer: Destroying buffer (GCI: %d, id: %d)",
  69.        m_bufferList[i]->getGCI(), id);
  70. #endif
  71.       destroyGCIBuffer(i, id);
  72.     }
  73.   }
  74. }
  75. /**
  76.  * Delete one GCI Buffer
  77.  */
  78. bool
  79. GCIContainer::destroyGCIBuffer(Uint32 gci, Uint32 id) 
  80. {
  81.   m_bufferList.lock();
  82.   for(Uint32 i = 0 ; i < m_bufferList.size(); i++) {
  83.     if((m_bufferList[i]->getGCI() == gci) && 
  84.        (m_bufferList[i]->getId() == id)) {
  85.       /**
  86.        * Delete the GCI Buffer
  87.        */      
  88.       delete m_bufferList[i];
  89.       m_bufferList[i] = 0;
  90.       /**
  91.        * Remove from the list of buffers stored in GCIContainer
  92.        */
  93.       m_bufferList.erase(i,false); 
  94.       m_bufferList.unlock();
  95.       /**
  96.        * Set info
  97.        */
  98.       NdbMutex_Lock(theMutexPtr);
  99.       if(gciRange[id].m_firstGCI != gci)
  100. RLOG(("WARNING! Buffer %d deleted from [%d-%d]",
  101.       gci, gciRange[id].m_firstGCI, gciRange[id].m_lastGCI));
  102.       
  103.       gciRange[id].m_firstGCI++;
  104.       /**
  105.        * Normalize empty interval to [1,0]
  106.        */
  107.       if (gciRange[id].m_firstGCI > gciRange[id].m_lastGCI){
  108. gciRange[id].m_firstGCI = 1;
  109. gciRange[id].m_lastGCI = 0;
  110.       }
  111.       NdbMutex_Unlock(theMutexPtr);
  112.       return true;
  113.     }
  114.   }
  115.   m_bufferList.unlock();
  116.   return false;
  117. }
  118. /*****************************************************************************
  119.  * GCIBuffer interface
  120.  *****************************************************************************/
  121. GCIBuffer * 
  122. GCIContainer::getGCIBuffer(Uint32 gci, Uint32 id) 
  123. {
  124.   GCIBuffer * gciBuffer = 0;
  125.   m_bufferList.lock();
  126.   for(Uint32 i=0; i < m_bufferList.size(); i++) {
  127.     gciBuffer = m_bufferList[i];
  128.     if((gciBuffer->getGCI() == gci) && (gciBuffer->getId() == id)) {
  129.       m_bufferList.unlock();
  130.       return gciBuffer;
  131.     }
  132.   }
  133.   m_bufferList.unlock();
  134.   return 0;
  135. }
  136. void
  137. GCIContainer::setCompleted(Uint32 gci, Uint32 id) 
  138. {
  139.   GCIBuffer * gciBuffer = getGCIBuffer(gci, id);
  140.   if(gciBuffer == 0) gciBuffer = createGCIBuffer(gci, id);
  141.   gciBuffer->setComplete();
  142.   
  143. #ifdef GCICONTAINER_DEBUG
  144.   ndbout_c("GCIContainer: Buffer completely stored in GCIContainer (GCI: %d)",
  145.    gci);
  146. #endif
  147.   
  148.   NdbMutex_Lock(theMutexPtr);
  149.   
  150.   /**
  151.    * If this is the first GCI Buffer to be completed
  152.    * then both first and last must be updated.
  153.    * Subsequently, only the last value must be updated.
  154.    */
  155.   if(gciRange[id].m_firstGCI == 1 && gciRange[id].m_lastGCI == 0) {
  156.     gciRange[id].m_firstGCI =  gci;
  157.     gciRange[id].m_lastGCI =  gci;
  158.   } else {
  159.     if (gci != gciRange[id].m_lastGCI + 1) {
  160.       RLOG(("WARNING! Non-consequtive buffer %u completed [%u-%u])",
  161.     gci, gciRange[id].m_firstGCI, gciRange[id].m_lastGCI));
  162.     }
  163.     gciRange[id].m_lastGCI = gci;
  164.   }  
  165.   NdbMutex_Unlock(theMutexPtr);
  166. }
  167. void
  168. GCIContainer::getAvailableGCIBuffers(Uint32 id, Uint32 * first, Uint32 * last) 
  169. {
  170.   NdbMutex_Lock(theMutexPtr);
  171.   *first = gciRange[id].m_firstGCI;
  172.   *last = gciRange[id].m_lastGCI;
  173.   NdbMutex_Unlock(theMutexPtr);
  174. }
  175. /*****************************************************************************
  176.  * Inserts
  177.  *****************************************************************************/
  178. void
  179. GCIContainer::insertMetaRecord(Uint32 id, Uint32 tableId, 
  180.        class LinearSectionPtr ptr[3], Uint32 gci) 
  181. {
  182.   /**********************************************************
  183.    * 1. Find correct GCI Buffer (Doesn't exist?  Create one)
  184.    **********************************************************/
  185.   GCIBuffer * gciBuffer = getGCIBuffer(gci, id);
  186.   if(gciBuffer == 0) gciBuffer = createGCIBuffer(gci, id);
  187.   /**********************************
  188.    * 2. Insert record into GCIBuffer
  189.    **********************************/
  190.   gciBuffer->insertMetaRecord(tableId, ptr);
  191. }
  192. void
  193. GCIContainer::insertLogRecord(Uint32 id, Uint32 tableId, Uint32 operation,
  194.       class LinearSectionPtr ptr[3], Uint32 gci) 
  195. {
  196.   /*********************************************************
  197.    * 1. Find correct GCI Buffer (doesn't exist? create one)
  198.    *********************************************************/
  199.   GCIBuffer * gciBuffer = getGCIBuffer(gci, id);
  200.   if(gciBuffer == 0) gciBuffer = createGCIBuffer(gci, id);
  201.   /**********************************
  202.    * 2. Insert record into GCIBuffer
  203.    **********************************/
  204.   gciBuffer->insertLogRecord(tableId, operation, ptr);
  205. }
  206. void
  207. GCIContainer::insertPage(Uint32 gci, Uint32 id,
  208.  char * dataPtr, Uint32 dataBLen) 
  209. {
  210.   /*********************************************************
  211.    * 1. Find correct GCI Buffer (doesn't exist? create one)
  212.    *********************************************************/
  213.   GCIBuffer * gciBuffer = getGCIBuffer(gci, id);
  214.   if(gciBuffer == 0) gciBuffer = createGCIBuffer(gci, id);
  215.   /********************************
  216.    * 2. Insert page into GCIBuffer
  217.    ********************************/
  218.   gciBuffer->insertPage(gci, dataPtr, dataBLen);
  219. }
  220. bool
  221. GCIContainer::reset() 
  222. {
  223.   /**
  224.    * Clear the intervals
  225.    */ 
  226.   for(Uint32 i = 0; i < m_maxNoOfIds; i++) {
  227.     gciRange[i].m_firstGCI = 1;  // The empty interval = [1,0]
  228.     gciRange[i].m_lastGCI = 0;
  229.   }
  230.   /**
  231.    * Destroy ALL gci buffers for ALL ids
  232.    */
  233.   for(Uint32 i=0; i < m_bufferList.size(); i++) {
  234.     delete m_bufferList[i];
  235.     m_bufferList[i] = 0;
  236.   }
  237.   m_bufferList.clear();
  238.   return true;
  239. }