You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			355 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			355 lines
		
	
	
		
			12 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;
 | 
						|
}
 | 
						|
}
 |