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 
			
		
		
		
	
		
			
				
	
	
		
			333 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			333 lines
		
	
	
		
			14 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.cpp                                                               */
 | |
| /*   (c) 2001 Author                                                          */
 | |
| /*                                                                            */
 | |
| /*   Description                                                              */
 | |
| /*                                                                            */
 | |
| /* ========================================================================== */
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #ifndef _MSC_VER
 | |
| #include <inttypes.h>
 | |
| #endif
 | |
| #include "we_indexlist.h"
 | |
| using namespace std;
 | |
| 
 | |
| namespace WriteEngine
 | |
| {  
 | |
|     /**
 | |
|      * Constructor
 | |
|      */
 | |
|     IndexList::IndexList()
 | |
|     :m_oid((OID) INVALID_NUM), m_useNarray(true),
 | |
|      m_curLevel(INVALID_NUM),m_curBlkPos(0),
 | |
|      m_curLevelPos(INVALID_NUM)
 | |
|      
 | |
|     {
 | |
|       m_freemgr.setDebugLevel(DEBUG_0);
 | |
|       init();
 | |
|     }; 
 | |
|    /****************************************************************
 | |
|     * DESCRIPTION:
 | |
|     * Public Function for adding a header    
 | |
|     * (1) Given a key value and a row ID,                
 | |
|     * (2) Return a pointer for insertion into the correct position
 | |
|     *     in the Index Tree List Pointer group
 | |
|     * (3) A return code should indicate success or failur            
 | |
|     * PARAMETERS:
 | |
|     *    input 
 | |
|     *        pFile      - File Handler
 | |
|     *        rid        - Input row ID 
 | |
|     *        key        - Input key value
 | |
|     *    output 
 | |
|     *        listHdrPtr - Output a pointer to the index list header
 | |
|     * RETURN:
 | |
|     *    success    - successfully created the index list header
 | |
|     *    failure    - it did not create the index list header    
 | |
|     *
 | |
|     *******************************************************************/   
 | |
|     const int IndexList::addIndexListHdr( FILE* pFile, const RID& rowId, 
 | |
|                                           const uint64_t& key, 
 | |
|                                           IdxEmptyListEntry* newEmptyListPtr)
 | |
|     {
 | |
|          int rc;   
 | |
|          CommBlock cb;
 | |
|          m_pFile       = pFile;
 | |
|          cb.file.oid   = m_oid;
 | |
|          cb.file.pFile = m_pFile;    
 | |
|          //Set up the header structure 
 | |
|          //Initialize header blokcs
 | |
|          rc = resetBlk(&m_hdrBlock);
 | |
|          m_hdrLbid    = INVALID_LBID; 
 | |
|          m_hdrSbid    = INVALID_NUM;
 | |
|          m_hdrEntry   = INVALID_NUM;
 | |
| 
 | |
|          //Initialize the new Index List header to null 
 | |
|          memset( &m_curIdxRidListHdr, 0, LIST_HDR_SIZE );
 | |
|          //Assign the bit fields for the first entry in the Index List Header
 | |
|          m_curIdxRidListHdr.idxRidListSize.type  = LIST_SIZE_TYPE;
 | |
|          m_curIdxRidListHdr.idxRidListSize.spare = 0x0;
 | |
|          m_curIdxRidListHdr.idxRidListSize.size  = 1;
 | |
|          //Assign the bit fields for the second entry of the Index List Header
 | |
|          m_curIdxRidListHdr.key = key;
 | |
|          //Assign bit fields for the third entry of the Index List Header
 | |
|          m_curIdxRidListHdr.firstIdxRidListEntry.type  =LIST_RID_TYPE;
 | |
|          m_curIdxRidListHdr.firstIdxRidListEntry.spare =0x0;
 | |
|          m_curIdxRidListHdr.firstIdxRidListEntry.rid   =rowId ;
 | |
|          //Assign bit fields for the fourth entry of the Index List Header
 | |
|          m_curIdxRidListHdr.nextIdxRidListPtr.type  = LIST_NOT_USED_TYPE;
 | |
|          m_curIdxRidListHdr.nextIdxRidListPtr.spare =0x0;
 | |
|          m_curIdxRidListHdr.nextIdxRidListPtr.llp   =0x0; 
 | |
|          /* Get assigned space for the header from free manager    
 | |
|           * Get the new block for the new idx list header
 | |
|           * The header needs LIST_HDR_SIZE bytes
 | |
|           */
 | |
|          rc = getSegment(pFile, ENTRY_4, newEmptyListPtr);
 | |
|          if (rc != NO_ERROR)
 | |
|                   return rc;
 | |
|          m_hdrLbid   = newEmptyListPtr->fbo;
 | |
|          m_hdrSbid   = newEmptyListPtr->sbid;
 | |
|          m_hdrEntry  = newEmptyListPtr->entry;
 | |
|       
 | |
|          //Write Index List Header to the file block
 | |
|          //Write LIST_HDR_SIZE bytes in one time.  
 | |
|           
 | |
|          rc = readDBFile( cb, m_hdrBlock.data, m_hdrLbid );  
 | |
|          rc = writeSubBlockEntry( cb, &m_hdrBlock,  m_hdrLbid, m_hdrSbid, 
 | |
|                                   m_hdrEntry,LIST_HDR_SIZE, &m_curIdxRidListHdr );
 | |
|          if (rc!= NO_ERROR)
 | |
|          {
 | |
|              return rc;
 | |
|          } 
 | |
|          //Wrote Header Block Out already, Start Over next time
 | |
|          //Update the flags to indicate there is data on the header block
 | |
|          m_hdrBlock.dirty = true;            
 | |
|          m_hdrBlock.lbid  = m_hdrLbid; 
 | |
|          m_hdrBlock.state = BLK_READ;
 | |
|          m_lastLbid = INVALID_LBID;
 | |
|          //DONE 
 | |
|          return rc;    
 | |
|    };
 | |
|    /****************************************************************
 | |
|     * DESCRIPTION:
 | |
|     *
 | |
|     *                 
 | |
|     * RETURN:
 | |
|     *    success    - successfully created the index list header
 | |
|     *    failure    - it did not create the index list header    
 | |
|     ***********************************************************/   
 | |
|     const int IndexList::updateIndexList(FILE* pFile, const RID& newRid, 
 | |
|                                          const uint64_t& key, 
 | |
|                                          IdxEmptyListEntry* curIdxRidListHdrPtr)
 | |
|     {      
 | |
|          int rc; 
 | |
|          m_pFile = pFile; 
 | |
|          //Initialization
 | |
|          if ( (key!= m_curIdxRidListHdr.key) || (m_hdrBlock.state==BLK_INIT))
 | |
|          {
 | |
|            rc = initGetHdr(key, curIdxRidListHdrPtr);
 | |
|            if (key!= m_curIdxRidListHdr.key)
 | |
|                   return ERR_IDX_LIST_INVALID_KEY;
 | |
|          }
 | |
|          rc = updateIndexList(newRid, key);
 | |
|          if (rc!=NO_ERROR)
 | |
|          {
 | |
|               return rc;
 | |
|          }
 | |
|          //Write everything out
 | |
|          rc = updateIndexListWrite();         
 | |
|          return rc;
 | |
|     };
 | |
|    /****************************************************************
 | |
|     * DESCRIPTION:
 | |
|     * (0) THIS FUNCIION CAN ONLY BE CALLED WITH THE PUBLIC
 | |
|     *
 | |
|     * RETURN:
 | |
|     *    success    - successfully created the index list header
 | |
|     *    failure    - it did not create the index list header    
 | |
|     ***********************************************************/   
 | |
|     const int IndexList::updateIndexList(const RID& newRid, const uint64_t& key)                                                                                   
 | |
|     {      
 | |
|        int rc = NO_ERROR;
 | |
| 
 | |
|        //m_lastLbid==0 or not determines if we can skip from the header,the first
 | |
|        //subblock or go to the last inserted block
 | |
|        if (m_lastLbid ==(uint64_t)INVALID_LBID)
 | |
|        {
 | |
|            rc = updateHdrSub(newRid, key);
 | |
|        }
 | |
|        else // get the lastLbid info from header
 | |
|        {//m_lastLbid > 0, space is in some block now
 | |
|            m_lbid  = m_lastLbid;
 | |
|            m_sbid =  0;
 | |
|            m_entry = 0;
 | |
|            m_segType = LIST_BLOCK_TYPE;
 | |
|            m_curType = LIST_BLOCK_TYPE;
 | |
|            rc = addRidInBlk(newRid);       
 | |
|        }
 | |
|        return rc;
 | |
|     };
 | |
|   
 | |
|    /************************************************
 | |
|     * Description:
 | |
|     * Find a entry for the given rowId and Key
 | |
|     * Then Delete it from the list
 | |
|     * Move the rest of the row id up in the same
 | |
|     * sub block an decrement the count in that subblock
 | |
|     * decrement the header size  
 | |
|     * Converted                                        
 | |
|     * input
 | |
|     *     pFile       -- File Handler     
 | |
|     *     rowId       -- row id
 | |
|     *     key         -- value    
 | |
|     *     curIdxRidListHdrPtr - point to the header    
 | |
|     *     
 | |
|     * return value
 | |
|     *        Success -- 0
 | |
|     *        Fail    -- ERR_IDX_LIST_INVALID_DELETE            
 | |
|     ************************************************/        
 | |
|     const int      IndexList::deleteIndexList( FILE* pFile, const RID& rowId, 
 | |
|                         const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr)
 | |
|     {
 | |
|       int rc =ERR_IDX_LIST_INVALID_DELETE;          
 | |
|       m_pFile = pFile;
 | |
|       
 | |
|       getHdrInfo(curIdxRidListHdrPtr);
 | |
|       if (key!= m_curIdxRidListHdr.key) 
 | |
|       {
 | |
|         memset( m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
 | |
|         m_hdrBlock.dirty = false;
 | |
|         m_hdrBlock.state = BLK_INIT;
 | |
|         return ERR_IDX_LIST_INVALID_KEY;
 | |
|       }                        
 | |
|       rc = deleteIndexList(rowId,key);      
 | |
|       return rc;
 | |
|     }
 | |
|     
 | |
|    /************************************************
 | |
|     * Description:
 | |
|     * Converted - keep the first sub block    
 | |
|     * Find a entry for the given rowId and Key
 | |
|     * Then Delete it from the list
 | |
|     * Move the rest of the row id up in the same
 | |
|     * sub block an decrement the count in that subblock
 | |
|     * decrement the header size                                      
 | |
|     * input
 | |
|     *     pFile       -- File Handler     
 | |
|     *     rowId       -- row id
 | |
|     *     key         -- value    
 | |
|     *     curIdxRidListHdrPtr - point to the header    
 | |
|     *     
 | |
|     * return value
 | |
|     *        Success -- 0
 | |
|     *        Fail    -- ERR_IDX_LIST_INVALID_DELETE            
 | |
|     ************************************************/        
 | |
|     const int      IndexList::deleteIndexList( const RID& rowId,const uint64_t& key) 
 | |
|     {
 | |
|       int rc =ERR_IDX_LIST_INVALID_DELETE;    
 | |
|       RID savedRid ;
 | |
|       DataBlock prevDataBlock;
 | |
|       
 | |
|       CommBlock cb;
 | |
|       cb.file.oid = m_oid;
 | |
|       cb.file.pFile = m_pFile;
 | |
|  
 | |
|       //Check the first row location, 3rd entry
 | |
|       //Because it may be deleted from the delete action
 | |
|       //The header size cannot tell us the rowid size on header
 | |
|       if (m_curIdxRidListHdr.firstIdxRidListEntry.type
 | |
|                                      ==(int)LIST_RID_TYPE)
 | |
|       {        
 | |
|                if (m_curIdxRidListHdr.firstIdxRidListEntry.rid 
 | |
|                       == rowId)
 | |
|                {
 | |
|                    m_curIdxRidListHdr.firstIdxRidListEntry.type 
 | |
|                          =LIST_NOT_USED_TYPE; //not used type
 | |
|                    m_curIdxRidListHdr.firstIdxRidListEntry.rid = 0;
 | |
|                    m_curIdxRidListHdr.idxRidListSize.size--;
 | |
|                    rc = writeSubBlockEntry(cb,&m_hdrBlock,m_hdrLbid,
 | |
|                                                        m_hdrSbid, m_hdrEntry,
 | |
|                                                         LIST_HDR_SIZE, 
 | |
|                                                        &m_curIdxRidListHdr );  
 | |
|                    memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
 | |
|                    m_hdrBlock.dirty = false; 
 | |
|                    m_dLbid   = m_hdrLbid;
 | |
|                    m_dSbid   = m_hdrSbid;
 | |
|                    m_dEntry  = m_hdrEntry+2;
 | |
|                    
 | |
|                    return rc;
 | |
|                }         
 | |
|        };
 | |
|        //Check Header last entry's type 
 | |
|        int type = m_curIdxRidListHdr.nextIdxRidListPtr.type;    
 | |
|        switch (type) 
 | |
|        {
 | |
|            case LIST_NOT_USED_TYPE://Header is not full, no sub-block linked
 | |
|                   //No RowId here
 | |
|                   memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
 | |
|                   m_hdrBlock.dirty = false; 
 | |
|                   m_dLbid = -1LL;
 | |
|                   m_dSbid = -1;
 | |
|                   m_dEntry = -1;
 | |
|                   return ERR_IDX_LIST_INVALID_DELETE;  //not found, failed   	         
 | |
|            case LIST_RID_TYPE:// There is a row id here, Check!	               
 | |
|                   savedRid = m_curIdxRidListHdr.nextIdxRidListPtr.llp;	      
 | |
|                   if (savedRid == rowId)
 | |
|                   {
 | |
|                           m_curIdxRidListHdr.nextIdxRidListPtr.type 
 | |
|                                        =LIST_NOT_USED_TYPE;
 | |
|                           m_curIdxRidListHdr.nextIdxRidListPtr.llp = 0;
 | |
|                           m_curIdxRidListHdr.idxRidListSize.size--;
 | |
|                           rc = writeSubBlockEntry(cb, &m_hdrBlock,m_hdrLbid,
 | |
|                                                   m_hdrSbid, m_hdrEntry, 
 | |
|                                                   LIST_HDR_SIZE, 
 | |
|                                                   &m_curIdxRidListHdr );           
 | |
|                            m_hdrBlock.dirty = false;
 | |
|                            memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
 | |
|                            m_dLbid = m_hdrLbid;
 | |
|                            m_dSbid = m_hdrSbid;
 | |
|                            m_dEntry = 3;
 | |
|                                         
 | |
|                            return rc;
 | |
|                    } 
 | |
|                    else 
 | |
|                    {
 | |
|                            m_hdrBlock.dirty = false;
 | |
|                            memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
 | |
|                            m_dLbid = -1LL;
 | |
|                            m_dSbid = -1;
 | |
|                            m_dEntry = -1;
 | |
|                            return ERR_IDX_LIST_INVALID_DELETE;
 | |
|                    }
 | |
|             case LIST_SUBBLOCK_TYPE://Not found in header, 
 | |
|               rc = deleteInSub(rowId);
 | |
|               if (rc == NO_ERROR)
 | |
|                 return rc;
 | |
|               rc = deleteInBlock(rowId);
 | |
|               return rc;                          
 | |
|               break;
 | |
|           default:
 | |
|               break;       
 | |
|         };//end of switch
 | |
|         return ERR_IDX_LIST_INVALID_DELETE;
 | |
|       }
 | |
|  }
 |