You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-30 07:25:34 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			336 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
| 
 | |
|    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; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    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., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| /* ========================================================================== */
 | |
| /*                                                                            */
 | |
| /*   we_indexlist_narray.cpp                                                       */
 | |
| /*                                                                            */
 | |
| /*                                                                            */
 | |
| /*   Description                                                              */
 | |
| /*                                                                            */
 | |
| /* ========================================================================== */
 | |
| #include <stdio.h>
 | |
| //#include <pthread.h>
 | |
| #include <string.h>
 | |
| #ifndef _MSC_VER
 | |
| #include <inttypes.h>
 | |
| #endif
 | |
| #include <math.h>
 | |
| #include "we_indextree.h"
 | |
| #include "we_indexlist.h"
 | |
| using namespace std;
 | |
| 
 | |
| namespace WriteEngine
 | |
| {
 | |
| 
 | |
|    /****************************************************************
 | |
|     * DESCRIPTION:
 | |
|     * Private Function for print the block trees
 | |
|     * 
 | |
|     ***************************************************************/ 
 | |
|     const int  IndexList::printBlocks(uint64_t& lbid)
 | |
|     {
 | |
|         int rc;
 | |
|         IdxRidListArrayPtr idxRidListArrayPtr;
 | |
|         int curLevel = 0, curCount=0;
 | |
|         
 | |
|         memset(&idxRidListArrayPtr, 0, sizeof(idxRidListArrayPtr));
 | |
|         m_lbid = lbid;
 | |
|         rc = readCurBlk();
 | |
|         getSubBlockEntry(m_curBlock.data, 0, 
 | |
|                          BEGIN_LIST_BLK_LLP_POS, 
 | |
|                          LIST_BLK_LLP_ENTRY_WIDTH, 
 | |
|                          &idxRidListArrayPtr);
 | |
|         curLevel     = idxRidListArrayPtr.nextIdxListPtr.curLevel;
 | |
|         curCount     = idxRidListArrayPtr.nextIdxListPtr.count;
 | |
|         for (int i=0; i< curLevel ; i++)
 | |
|         {
 | |
|           cout << "        ";
 | |
|         }
 | |
|         cout << "   Lbid->" << lbid << " curLevel->" << curLevel 
 | |
|                                   << " curCount->" << curCount << endl;
 | |
|         for (int i=0; i<TOTAL_NUM_ARRAY_PTR; i++)
 | |
|         {
 | |
|           uint64_t lbid;
 | |
|           lbid = idxRidListArrayPtr.childIdxRidListPtr[i].childLbid;
 | |
|           if (lbid != (uint64_t)INVALID_LBID)
 | |
|               printBlocks(lbid);
 | |
|         }
 | |
|         return rc;
 | |
|      }
 | |
| 
 | |
|     /****************************************************************
 | |
|      * DESCRIPTION:
 | |
|      * Private Function for getting the last Fbo on header
 | |
|      * 
 | |
|      ***************************************************************/ 
 | |
|      const int  IndexList::setCurBlkNextPtr(uint64_t& nextLbid, int count)
 | |
|      {
 | |
|         int rc ;
 | |
|         CommBlock cb;
 | |
|         
 | |
|         cb.file.oid = m_oid;     
 | |
|         cb.file.pFile = m_pFile; 
 | |
|         if (nextLbid== (uint64_t)INVALID_LBID)
 | |
|          return ERR_IDX_LIST_SET_NEXT_LBID;
 | |
|          
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.type       = (int)LIST_BLOCK_TYPE;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.curLevel   = m_curLevel;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.count      = count;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.nextLbid   = nextLbid; 
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.spare      = 0;
 | |
| 
 | |
|         if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state>= BLK_READ))
 | |
|         {
 | |
|           rc = writeSubBlockEntry( cb, &m_curBlock,  m_lbid, 0, 
 | |
|                                    BEGIN_LIST_BLK_LLP_POS+ NEXT_BLK_PTR_OFFSET, 
 | |
|                                    LIST_ENTRY_WIDTH, 
 | |
|                                    &m_idxRidListArrayPtr.nextIdxListPtr );
 | |
|           m_curBlock.state = BLK_READ;
 | |
|           if (rc!= NO_ERROR)
 | |
|              return rc;
 | |
|         }          
 | |
|         else
 | |
|           return ERR_IDX_LIST_SET_NEXT_LBID;
 | |
|         
 | |
|         return NO_ERROR;
 | |
|      } 
 | |
| 
 | |
|     /****************************************************************
 | |
|      * DESCRIPTION:
 | |
|      * Private Function for setting the last Fbo on header
 | |
|      * 
 | |
|      ***************************************************************/    
 | |
|      const int  IndexList::initCurBlock()
 | |
|      {
 | |
| 
 | |
|       if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state>= BLK_READ))
 | |
|       {
 | |
|         memset(&m_idxRidListArrayPtr, 0, sizeof(m_idxRidListArrayPtr));
 | |
|         for (int i=0; i<TOTAL_NUM_ARRAY_PTR; i++)
 | |
|         {
 | |
|           m_idxRidListArrayPtr.childIdxRidListPtr[i].type = LIST_NOT_USED_TYPE;
 | |
|           m_idxRidListArrayPtr.childIdxRidListPtr[i].llpStat = LLP_NOT_FULL;
 | |
|           m_idxRidListArrayPtr.childIdxRidListPtr[i].spare =0;
 | |
|           m_idxRidListArrayPtr.childIdxRidListPtr[i].childLbid= INVALID_LBID;
 | |
|         }
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.type       = LIST_SIZE_TYPE;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.spare      = 0;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.curLevel   = m_curLevel;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.count   = 0;
 | |
|         m_idxRidListArrayPtr.nextIdxListPtr.nextLbid   = INVALID_LBID;
 | |
|           
 | |
|             
 | |
|         m_idxRidListArrayPtr.parentIdxListPtr.type = LIST_LLP_TYPE;
 | |
|         m_idxRidListArrayPtr.parentIdxListPtr.spare = 0;
 | |
|         m_idxRidListArrayPtr.parentIdxListPtr.curLevelPos = m_curLevelPos; 
 | |
|         m_idxRidListArrayPtr.parentIdxListPtr.curBlkPos = m_curBlkPos;        
 | |
|         m_idxRidListArrayPtr.parentIdxListPtr.parentLbid = m_parentLbid;
 | |
| 
 | |
|         setSubBlockEntry(m_curBlock.data, 0, BEGIN_LIST_BLK_LLP_POS, 
 | |
|                          LIST_BLK_LLP_ENTRY_WIDTH, &m_idxRidListArrayPtr);
 | |
|       }
 | |
|       else
 | |
|         return ERR_IDX_LIST_INIT_LINK_BLKS;
 | |
|       return NO_ERROR;
 | |
|      }
 | |
|     /****************************************************************
 | |
|      * DESCRIPTION:
 | |
|      * Private Function for setting the last Fbo on header
 | |
|      * 
 | |
|      ***************************************************************/    
 | |
|      const int  IndexList::getNextInfoFromArray(IdxRidNextListPtr& nextIdxListPtr)
 | |
|      {
 | |
|        if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state>= BLK_READ))
 | |
|         getSubBlockEntry(m_curBlock.data, 0, 
 | |
|                          BEGIN_LIST_BLK_LLP_POS+ NEXT_BLK_PTR_OFFSET, 
 | |
|                          LIST_ENTRY_WIDTH, &nextIdxListPtr);
 | |
|        else
 | |
|         return ERR_IDX_LIST_GET_NEXT;
 | |
|        return NO_ERROR;
 | |
|      }
 | |
|     /****************************************************************
 | |
|      * DESCRIPTION:
 | |
|      * Private Function for setting the last Fbo on header
 | |
|      * 
 | |
|      ***************************************************************/    
 | |
|      const int  IndexList::getParentInfoFromArray(IdxRidParentListPtr& parentIdxListPtr)
 | |
|      {
 | |
|         int rc;
 | |
|         CommBlock cb;
 | |
|         
 | |
|         cb.file.oid = m_oid;     
 | |
|         cb.file.pFile = m_pFile;    
 | |
|         if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state>= BLK_READ))
 | |
|            getSubBlockEntry(m_curBlock.data, 0, 
 | |
|                             BEGIN_LIST_BLK_LLP_POS+ PARENT_PTR_OFFSET, 
 | |
|                             LIST_ENTRY_WIDTH, &parentIdxListPtr);
 | |
|         else
 | |
|            return ERR_IDX_LIST_GET_PARENT;
 | |
|         m_curLevelPos   = parentIdxListPtr.curLevelPos;
 | |
|         m_curBlkPos     = parentIdxListPtr.curBlkPos;
 | |
|         m_parentLbid    = parentIdxListPtr.parentLbid;
 | |
|         if (m_parentLbid == (uint64_t)INVALID_LBID)
 | |
|          return NO_ERROR;
 | |
|         memset( m_parentBlock.data, 0, sizeof(m_parentBlock.data));
 | |
|         rc = readDBFile(cb, &m_parentBlock, m_parentLbid );
 | |
|         m_parentBlock.lbid  = m_parentLbid;
 | |
|         m_parentBlock.state = BLK_READ;
 | |
|         m_parentBlock.dirty = true;
 | |
|       return NO_ERROR;
 | |
|      }
 | |
|     /****************************************************************
 | |
|      * DESCRIPTION:
 | |
|      * Private Function for setting the last Fbo on header
 | |
|      * 
 | |
|      ***************************************************************/    
 | |
|      const int  IndexList::updateCurCountInArray(int insCnt)
 | |
|      {
 | |
|        int rc = NO_ERROR;
 | |
|        IdxRidNextListPtr nextIdxListPtr;
 | |
|        
 | |
|        memset(&nextIdxListPtr, 0, sizeof(IdxRidNextListPtr));    
 | |
|        if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state>= BLK_READ))
 | |
|        {
 | |
|          getSubBlockEntry(m_curBlock.data, 0, BEGIN_LIST_BLK_LLP_POS+ NEXT_BLK_PTR_OFFSET, 
 | |
|                           LIST_ENTRY_WIDTH, &nextIdxListPtr);
 | |
| 
 | |
|          nextIdxListPtr.count = nextIdxListPtr.count + insCnt;
 | |
|          setSubBlockEntry(m_curBlock.data, 0, BEGIN_LIST_BLK_LLP_POS+ NEXT_BLK_PTR_OFFSET, 
 | |
|                          LIST_ENTRY_WIDTH, &nextIdxListPtr);
 | |
|          m_curBlock.state = BLK_WRITE;
 | |
|        }
 | |
|        else
 | |
|          return ERR_IDX_LIST_GET_COUNT;
 | |
|        return rc;
 | |
|      }
 | |
|    /****************************************************************
 | |
|     * DESCRIPTION:
 | |
|     * childLbid is the new child block and need to register it in 
 | |
|     * the correct parent and assigned level        
 | |
|     * Private Function for getting the header
 | |
|     * 
 | |
|     ***************************************************************/ 
 | |
|    const int IndexList::updateParentStatus(uint64_t& childLbid)                                      
 | |
|    {
 | |
|       int rc;
 | |
|       CommBlock cb;
 | |
|         
 | |
|       cb.file.oid = m_oid;     
 | |
|       cb.file.pFile = m_pFile; 
 | |
|         
 | |
|       IdxRidListArrayPtr   idxRidListArrayPtr; 
 | |
|       //Get the parent block read out or get the 4 children pointers out
 | |
|       if ((m_parentBlock.state== BLK_INIT)||(m_parentBlock.lbid !=m_parentLbid))
 | |
|       {    
 | |
|                      rc = readSubBlockEntry(cb, &m_parentBlock, m_parentLbid,
 | |
|                                             0, BEGIN_LIST_BLK_LLP_POS, 
 | |
|                                             LIST_BLK_LLP_ENTRY_WIDTH, 
 | |
|                                             &idxRidListArrayPtr);
 | |
|                      m_parentBlock.dirty = true;
 | |
|                      m_parentBlock.state = BLK_READ;
 | |
|                      m_parentBlock.lbid  = m_parentLbid;
 | |
|       }
 | |
|       else
 | |
|                getSubBlockEntry(m_parentBlock.data, 0, BEGIN_LIST_BLK_LLP_POS,                                             
 | |
|                                 LIST_BLK_LLP_ENTRY_WIDTH, 
 | |
|                                 &idxRidListArrayPtr);
 | |
|       //update current Child Block to full
 | |
|       // The reason to update parent is becuse CURRENT child link is full
 | |
|       // The CURRENT child lbid is m_lbid, m_curBlkPos is where it was registered
 | |
|       if (m_lbid != m_parentLbid)//The fulled child is not the parent itself
 | |
|       { //normal case found the child block is full and set it full
 | |
| 
 | |
|         if (idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].type == (int)LIST_BLOCK_TYPE)
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].llpStat = LLP_FULL;
 | |
|         //else if ((m_curBlkPos==0) && (m_flag)) //Next level parent, a new parent, no child
 | |
|         else if (m_curBlkPos==0)//get here only when a brand new parent given, 
 | |
|                                 //it went up one level and the go back down to the same level, 
 | |
|                                 
 | |
|         {
 | |
|              if (!m_flag) //it is NOT the first block, this flag is useless, cannot be FALSE!
 | |
|                 return ERR_IDX_LIST_WRONG_TYPE;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].type = LIST_BLOCK_TYPE;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].llpStat = LLP_NOT_FULL;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].spare =0;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].childLbid= childLbid;
 | |
|              setSubBlockEntry(m_parentBlock.data, 0, BEGIN_LIST_BLK_LLP_POS+m_curBlkPos, 
 | |
|                    LIST_ENTRY_WIDTH, &idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos]);
 | |
|              rc = writeDBFile( cb, m_parentBlock.data, m_parentLbid );
 | |
|              m_parentBlock.state = BLK_READ;
 | |
|              m_curLevelPos ++;
 | |
|              return rc; 
 | |
|         }
 | |
|         else //m_flag cannot be false since it is not the first block
 | |
|           return ERR_IDX_LIST_WRONG_TYPE;
 | |
|       }
 | |
|       else//This is the first block-> the current block's parent is itself
 | |
|       {//only done once when first block was full
 | |
|          m_curBlkPos = 0;
 | |
|          idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].type = (int)LIST_BLOCK_TYPE;
 | |
|          idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].llpStat = LLP_FULL;
 | |
|          idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].spare =0;
 | |
|          idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos].childLbid= childLbid;
 | |
|          setSubBlockEntry(m_parentBlock.data, 0, BEGIN_LIST_BLK_LLP_POS+m_curBlkPos, 
 | |
|                    LIST_ENTRY_WIDTH, &idxRidListArrayPtr.childIdxRidListPtr[m_curBlkPos]);
 | |
|          rc = writeDBFile( cb, m_parentBlock.data, m_parentLbid );
 | |
|          m_parentBlock.state = BLK_READ;
 | |
|          m_curLevel=1;
 | |
|          m_curLevelPos = 0;
 | |
|          return rc;
 | |
|       }
 | |
|       int i;
 | |
|       for (i=0; i<TOTAL_NUM_ARRAY_PTR; i++)
 | |
|       {
 | |
|           if(idxRidListArrayPtr.childIdxRidListPtr[i].type != (int)LIST_BLOCK_TYPE)
 | |
|           {
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[i].type = LIST_BLOCK_TYPE;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[i].llpStat = LLP_NOT_FULL;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[i].spare =0;
 | |
|              idxRidListArrayPtr.childIdxRidListPtr[i].childLbid= childLbid;
 | |
|              setSubBlockEntry(m_parentBlock.data, 0, BEGIN_LIST_BLK_LLP_POS+ i, 
 | |
|                    LIST_ENTRY_WIDTH, &idxRidListArrayPtr.childIdxRidListPtr[i]);
 | |
|              rc = writeDBFile( cb, m_parentBlock.data, m_parentLbid );
 | |
|              m_parentBlock.state = BLK_READ;
 | |
|              m_curBlkPos = i; //Need to figure out this where to put it
 | |
|              m_curLevelPos ++;
 | |
|              return rc;
 | |
|           }
 | |
|       }
 | |
|       //Parent is full and all children are full Not found any child pointer is available to add
 | |
|       //then go to sibling in the same level or down
 | |
|       //Need to look for the next block on parent block, on level down
 | |
|       //The level will be increment by 1 HERE
 | |
|       //Change parent lbid go to next link
 | |
|       if (m_curLevelPos == (pow(4.0, m_curLevel)-1))//if the last node of this level
 | |
|       {
 | |
|          m_curLevel++;
 | |
|          m_curLevelPos = -1;
 | |
|       }
 | |
|       m_flag = true; // this need to go
 | |
|       // A new parent
 | |
|       m_curBlkPos = 0;
 | |
|       m_parentLbid = idxRidListArrayPtr.nextIdxListPtr.nextLbid;
 | |
|       memset( m_parentBlock.data, 0, sizeof(m_parentBlock.data));
 | |
|       m_parentBlock.state = BLK_INIT;
 | |
|       m_parentBlock.dirty = false;
 | |
|      
 | |
|       rc = updateParentStatus(childLbid);
 | |
|       return rc;
 | |
|    } 
 | |
|   }
 |