1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
mariadb-columnstore-engine/writeengine/index/we_indexlist_common.cpp
2023-03-02 15:59:42 +00:00

1122 lines
31 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. */
/* ========================================================================== */
/* */
/* Filename.c */
/* (c) 2001 Author */
/* */
/* Description */
/* */
/* ========================================================================== */
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "we_indexlist.h"
using namespace std;
namespace WriteEngine
{
/****************************************************************
* DESCRIPTION:
* Private Function for getting the last Fbo on header
*
***************************************************************/
const int IndexList::init()
{
memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
memset(m_curBlock.data, 0, sizeof(m_curBlock.data));
memset(m_nextBlock.data, 0, sizeof(m_nextBlock.data));
memset(m_blockZero.data, 0, sizeof(m_blockZero.data));
memset(m_parentBlock.data, 0, sizeof(m_parentBlock.data));
memset(&m_curIdxRidListHdr, 0, LIST_HDR_SIZE);
m_curIdxRidListHdr.key = INVALID_KEY;
memset(&m_idxRidListArrayPtr, 0, sizeof(IdxRidListArrayPtr));
memset(&m_lastIdxRidListPtr, 0, sizeof(IdxRidListPtr));
m_hdrBlock.dirty = false;
m_curBlock.dirty = false;
m_nextBlock.dirty = false;
m_blockZero.dirty = false;
m_parentBlock.dirty = false;
m_hdrBlock.state = BLK_INIT;
m_curBlock.state = BLK_INIT;
m_nextBlock.state = BLK_INIT;
m_blockZero.state = BLK_INIT;
m_parentBlock.state = BLK_INIT;
m_hdrBlock.lbid = INVALID_LBID;
m_curBlock.lbid = INVALID_LBID;
m_nextBlock.lbid = INVALID_LBID;
m_blockZero.lbid = INVALID_LBID;
m_parentBlock.lbid = INVALID_LBID;
m_lbid = INVALID_LBID;
m_sbid = INVALID_NUM;
m_entry = INVALID_NUM;
m_hdrLbid = INVALID_LBID;
m_hdrSbid = INVALID_NUM;
m_hdrEntry = INVALID_NUM;
m_nextLbid = INVALID_LBID;
m_nextSbid = INVALID_NUM;
m_nextEntry = INVALID_NUM;
m_parentLbid = INVALID_LBID;
m_lastLbid = INVALID_LBID;
return NO_ERROR;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the last Fbo on header
*
***************************************************************/
const int IndexList::initBlksGetHdrBlk()
{
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
memset(m_curBlock.data, 0, sizeof(m_curBlock.data));
memset(m_nextBlock.data, 0, sizeof(m_nextBlock.data));
memset(m_blockZero.data, 0, sizeof(m_blockZero.data));
memset(m_parentBlock.data, 0, sizeof(m_curBlock.data));
m_hdrBlock.dirty = false;
m_curBlock.dirty = false;
m_nextBlock.dirty = false;
m_blockZero.dirty = false;
m_parentBlock.dirty = false;
m_hdrBlock.state = BLK_INIT;
m_curBlock.state = BLK_INIT;
m_nextBlock.state = BLK_INIT;
m_blockZero.state = BLK_INIT;
m_parentBlock.state = BLK_INIT;
// Get the header info if the header exist already
if (m_hdrLbid != (uint64_t)INVALID_LBID)
{
memset(&m_curIdxRidListHdr, 0, LIST_HDR_SIZE);
rc = readSubBlockEntry(cb, &m_hdrBlock, m_hdrLbid, m_hdrSbid, m_hdrEntry, LIST_HDR_SIZE,
&m_curIdxRidListHdr);
m_hdrBlock.dirty = true;
m_hdrBlock.lbid = m_hdrLbid;
m_hdrBlock.state = BLK_READ;
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the last Fbo on header
*
***************************************************************/
const int IndexList::initGetHdr(const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr)
{
int rc;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
rc = init();
m_hdrLbid = curIdxRidListHdrPtr->fbo;
m_hdrSbid = curIdxRidListHdrPtr->sbid;
m_hdrEntry = curIdxRidListHdrPtr->entry;
memset(&m_curIdxRidListHdr, 0, LIST_HDR_SIZE);
rc = readSubBlockEntry(cb, &m_hdrBlock, m_hdrLbid, m_hdrSbid, m_hdrEntry, LIST_HDR_SIZE,
&m_curIdxRidListHdr);
m_hdrBlock.dirty = true;
m_hdrBlock.lbid = m_hdrLbid;
m_hdrBlock.state = BLK_READ;
if (m_curIdxRidListHdr.nextIdxRidListPtr.type == (int)LIST_SUBBLOCK_TYPE)
rc = getLastLbid();
else
m_lastLbid = INVALID_LBID;
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the header
*
***************************************************************/
const int IndexList::getHdrInfo(IdxEmptyListEntry* curIdxRidListHdrPtr)
{
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
// Get the Header block, sub-block and entry info from Index Tree
m_hdrLbid = curIdxRidListHdrPtr->fbo;
m_hdrSbid = curIdxRidListHdrPtr->sbid;
m_hdrEntry = curIdxRidListHdrPtr->entry;
memset(m_hdrBlock.data, 0, sizeof(m_hdrBlock.data));
m_hdrBlock.dirty = false;
m_hdrBlock.state = BLK_INIT;
m_hdrBlock.no = INVALID_NUM;
m_hdrBlock.lbid = INVALID_LBID;
// header is 4 entries LIST_HDR_SIZE bytes
memset(&m_curIdxRidListHdr, 0, LIST_HDR_SIZE);
// Get the old header out
rc = readDBFile(cb, &m_hdrBlock, m_hdrLbid);
m_hdrBlock.dirty = true;
m_hdrBlock.state = BLK_READ;
m_hdrBlock.lbid = m_hdrLbid;
getSubBlockEntry(m_hdrBlock.data, m_hdrSbid, m_hdrEntry, LIST_HDR_SIZE, &m_curIdxRidListHdr);
if (m_curIdxRidListHdr.nextIdxRidListPtr.type == (int)LIST_SUBBLOCK_TYPE)
rc = getLastLbid();
else
m_lastLbid = INVALID_LBID;
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting a segment for LIST
*
***************************************************************/
const int IndexList::resetBlk(DataBlock* dataBlk)
{
memset(dataBlk->data, 0, sizeof(dataBlk->data));
dataBlk->dirty = false;
dataBlk->state = BLK_INIT;
dataBlk->lbid = INVALID_LBID;
return NO_ERROR;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting block zero
* either it is 0 or get it from BRM
*
***************************************************************/
const int IndexList::resetBlkZero(uint64_t& lbid0)
{
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
memset(m_blockZero.data, 0, sizeof(m_blockZero.data));
m_blockZero.dirty = false;
m_blockZero.state = BLK_INIT;
#ifdef BROKEN_BY_MULTIPLE_FILES_PER_OID
rc = BRMWrapper::getInstance()->getBrmInfo(m_oid, 0, lbid0);
#endif
if (rc != NO_ERROR)
return rc;
rc = readDBFile(cb, m_blockZero.data, lbid0);
m_blockZero.lbid = lbid0;
m_blockZero.state = BLK_READ;
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for writing block zero
*
***************************************************************/
const int IndexList::writeBlkZero(uint64_t& lbid0)
{
int rc;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
rc = writeDBFile(cb, m_blockZero.data, lbid0);
memset(m_blockZero.data, 0, sizeof(m_blockZero.data));
m_blockZero.dirty = false;
m_blockZero.state = BLK_INIT;
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting a segment for LIST
*
***************************************************************/
const int IndexList::getSegment(FILE* pFile, const IdxTreeGroupType segmentType, IdxEmptyListEntry* assignPtr)
{
int rc = ERR_IDX_LIST_GET_SEGMT;
CommBlock cb;
uint64_t lbid0;
m_pFile = pFile;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
/*
DataBlock tmpBlock;
IdxEmptyListEntry tmpEntry;
memset(tmpBlock.data,0, 8192);
rc = readSubBlockEntry( pFile, &tmpBlock, 1492798, 31, 31, 8, &tmpEntry );
cout << "common273->tmpEntry.fbo=" << tmpEntry.fbo << " tmpEntry.sbid="
<< tmpEntry.sbid << " tmpEntry.entry=" << tmpEntry.entry << endl;
*/
if (m_hdrLbid != INVALID_LBID)
{
setSubBlockEntry(m_hdrBlock.data, m_hdrSbid, m_hdrEntry, LIST_HDR_SIZE, &m_curIdxRidListHdr);
m_hdrBlock.state = BLK_WRITE;
}
// write everything out before calling free space manager
rc = updateIndexListWrite();
rc = resetBlkZero(lbid0);
rc = m_freemgr.assignSegment(cb, &m_blockZero, LIST, segmentType, assignPtr);
if (rc != NO_ERROR)
return rc;
rc = writeBlkZero(lbid0);
if (segmentType == ENTRY_4)
{
m_hdrLbid = assignPtr->fbo;
m_hdrSbid = assignPtr->sbid;
m_hdrEntry = assignPtr->entry;
return rc;
}
// get the header back for sure
// recover other blocks as it goes
rc = initBlksGetHdrBlk();
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for releasing a segment for LIST
* Only block can be released, not subblock or header
*
***************************************************************/
const int IndexList::releaseSegment()
{
IdxEmptyListEntry releasePtrEntry;
int entryType = 0;
int rc;
uint64_t lbid0;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
memset(&releasePtrEntry, 0, sizeof(IdxEmptyListEntry));
releasePtrEntry.fbo = m_lbid;
releasePtrEntry.sbid = 0;
releasePtrEntry.entry = 0;
releasePtrEntry.spare = 0;
entryType = ENTRY_BLK;
// The following is related to ptr
releasePtrEntry.spare2 = 0;
releasePtrEntry.type = EMPTY_PTR;
releasePtrEntry.group = entryType;
// release free manager
rc = resetBlkZero(lbid0);
rc = m_freemgr.releaseSegment(cb, &m_blockZero, LIST, (const IdxTreeGroupType)entryType, &releasePtrEntry);
rc = writeBlkZero(lbid0);
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::setLastLbid(uint64_t& lastLbid)
{
int rc = NO_ERROR;
uint64_t lbid;
int sbid, entry;
IdxRidListPtr lastFboListPtr;
if (m_curIdxRidListHdr.nextIdxRidListPtr.type != (int)LIST_SUBBLOCK_TYPE)
{
m_lastLbid = INVALID_LBID;
return NO_ERROR;
}
if (m_curType == LIST_SUBBLOCK_TYPE)
{
m_lastLbid = INVALID_LBID;
return NO_ERROR;
}
else
{
m_lastLbid = lastLbid;
}
rc = getSubBlk(lbid, sbid, entry);
// First link
memset(&lastFboListPtr, 0, sizeof(lastFboListPtr));
lastFboListPtr.type = LIST_BLOCK_TYPE;
((IdxEmptyListEntry*)&lastFboListPtr)->fbo = m_lastLbid;
((IdxEmptyListEntry*)&lastFboListPtr)->sbid = 0;
((IdxEmptyListEntry*)&lastFboListPtr)->entry = 0;
lastFboListPtr.spare = 0x0;
rc = setLastFboPtr(lbid, sbid, lastFboListPtr);
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::setLastFboPtr(uint64_t& lbid, int& sbid, IdxRidListPtr& lastFboListPtr)
{
int rc = NO_ERROR;
CommBlock cb;
DataBlock dataBlock;
IdxRidListPtr oldFboListPtr;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
if ((m_hdrBlock.lbid == lbid) && (m_hdrBlock.state >= BLK_READ))
{
setSubBlockEntry(m_hdrBlock.data, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
m_hdrBlock.state = BLK_WRITE;
}
else if ((m_curBlock.lbid == lbid) && (m_curBlock.state >= BLK_READ))
{
setSubBlockEntry(m_curBlock.data, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
m_curBlock.state = BLK_WRITE;
}
else
{
memset(dataBlock.data, 0, sizeof(dataBlock.data));
rc = readSubBlockEntry(cb, &dataBlock, lbid, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &oldFboListPtr);
if (((IdxEmptyListEntry*)&oldFboListPtr)->fbo != m_lastLbid)
{
setSubBlockEntry(dataBlock.data, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
rc = writeDBFile(cb, dataBlock.data, lbid);
}
else
return NO_ERROR;
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the last Fbo on header
*
***************************************************************/
const int IndexList::getLastLbid()
{
int rc = NO_ERROR;
uint64_t lbid;
int sbid, entry;
IdxRidListPtr lastFboListPtr;
if (m_curIdxRidListHdr.nextIdxRidListPtr.type != (int)LIST_SUBBLOCK_TYPE)
{
m_lastLbid = INVALID_LBID;
return NO_ERROR;
}
rc = getSubBlk(lbid, sbid, entry);
// First link
rc = getLastFboPtr(lbid, sbid, lastFboListPtr);
if (lastFboListPtr.type == (int)LIST_BLOCK_TYPE)
{
m_lastLbid = ((IdxEmptyListEntry*)&lastFboListPtr)->fbo;
}
else
m_lastLbid = INVALID_LBID;
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::getLastFboPtr(uint64_t& lbid, int& sbid, IdxRidListPtr& lastFboListPtr)
{
int rc = NO_ERROR;
CommBlock cb;
DataBlock dataBlock;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
if ((m_hdrBlock.lbid == lbid) && (m_hdrBlock.state >= BLK_READ))
{
getSubBlockEntry(m_hdrBlock.data, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
}
else if ((m_curBlock.lbid == lbid) && (m_curBlock.state >= BLK_READ))
{
getSubBlockEntry(m_curBlock.data, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
}
else
{
memset(dataBlock.data, 0, sizeof(dataBlock.data));
dataBlock.dirty = false;
dataBlock.state = BLK_INIT;
rc = readSubBlockEntry(cb, &dataBlock, lbid, sbid, LIST_LAST_LBID_POS, LIST_ENTRY_WIDTH, &lastFboListPtr);
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the sub block
*
***************************************************************/
const int IndexList::getSubBlk()
{
int rc = NO_ERROR;
uint64_t lbid;
int sbid, entry;
RID rowIdArray[ENTRY_PER_SUBBLOCK];
DataBlock dataBlk;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
memset(dataBlk.data, 0, sizeof(dataBlk.data));
rc = getSubBlk(lbid, sbid, entry);
if (lbid != INVALID_LBID)
rc = readSubBlockEntry(cb, &dataBlk, lbid, sbid, 0, BYTE_PER_SUBBLOCK, rowIdArray);
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting the sub block
*
***************************************************************/
const int IndexList::getSubBlk(uint64_t& lbid, int& sbid, int& entry)
{
int rc = NO_ERROR;
if (m_curIdxRidListHdr.nextIdxRidListPtr.type == (int)LIST_SUBBLOCK_TYPE)
{
lbid = ((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
sbid = ((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
entry = ((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;
}
else
{
lbid = INVALID_LBID;
sbid = INVALID_NUM;
entry = INVALID_NUM;
return ERR_IDX_LIST_GET_SUB_BLK;
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for getting a particular block
*
***************************************************************/
const int IndexList::getBlk(uint64_t& lbid)
{
int rc = NO_ERROR;
RID rowIdArray[MAX_BLOCK_ENTRY];
DataBlock dataBlk;
CommBlock cb;
memset(dataBlk.data, 0, sizeof(dataBlk.data));
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
rc = readSubBlockEntry(cb, &dataBlk, lbid, 0, 0, BYTE_PER_BLOCK, rowIdArray);
return rc;
}
/****************************************************************
* DESCRIPTION:
* Update Write in one call
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::updateIndexListWrite()
{
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
// Now write in one place
if (m_hdrBlock.state == BLK_WRITE)
{
// A
rc = writeDBFile(cb, m_hdrBlock.data, m_hdrLbid);
if (rc != NO_ERROR)
return rc;
m_hdrBlock.state = BLK_READ;
}
if (m_curBlock.state == BLK_WRITE)
{
// B
rc = writeDBFile(cb, m_curBlock.data, m_lbid);
if (rc != NO_ERROR)
return rc;
m_curBlock.state = BLK_READ;
}
if (m_parentBlock.state == BLK_WRITE)
{
rc = writeDBFile(cb, m_parentBlock.data, m_parentLbid);
if (rc != NO_ERROR)
return rc;
m_parentBlock.state = BLK_READ;
}
if (m_nextBlock.state == BLK_WRITE)
{
rc = writeDBFile(cb, m_nextBlock.data, m_nextLbid);
if (rc != NO_ERROR)
return rc;
m_nextBlock.state = BLK_READ;
}
return rc;
}
/************************************************
* Description:
* Find a entry for the given rowId and Key
* Converted
* input
* pFile -- File Handler
* rowId -- row id
* key -- value
* curIdxRidListHdrPtr - point to the header
* output
* lbid -- File block id
* sbid -- Sub Block id
* entry -- Entry id
*
*
* return value
* true --found
* false--not found
************************************************/
const int IndexList::findFirstBlk(FILE* pFile, const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr,
uint64_t& lbid)
{
int rc;
CommBlock cb;
int count;
cb.file.oid = m_oid;
cb.file.pFile = pFile;
m_pFile = pFile;
rc = getHdrInfo(curIdxRidListHdrPtr);
if (key != m_curIdxRidListHdr.key)
{
return ERR_IDX_LIST_INVALID_KEY;
;
}
int type = m_curIdxRidListHdr.nextIdxRidListPtr.type;
switch (type)
{
case LIST_NOT_USED_TYPE: // Header is not full, no sub-block linked
lbid = INVALID_LBID;
return NO_ERROR; // not found
case LIST_RID_TYPE: // There is a row id here, Check!
lbid = INVALID_LBID;
return NO_ERROR; // not found
case LIST_SUBBLOCK_TYPE: // Not found in header
// get the lbid sbid and entry out from the header last entry
rc = getSubBlk(m_lbid, m_sbid, m_entry);
m_curType = type;
if (m_lbid != m_hdrLbid)
rc = readCurBlk();
rc = getNextInfoFromBlk(m_lastIdxRidListPtr);
count = m_lastIdxRidListPtr.count; // current count
type = m_lastIdxRidListPtr.type; // block type
if (type == LIST_BLOCK_TYPE)
lbid = ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->fbo;
else
lbid = INVALID_LBID;
return NO_ERROR;
break;
default:
// printf ("FIND FIRST BLOCK got no where, error out !! \n");
break;
}; // end switch
lbid = INVALID_LBID;
return NO_ERROR;
} // end function
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::readCurBlk()
{
int rc = NO_ERROR;
CommBlock cb;
if (m_lbid == m_hdrLbid)
return NO_ERROR;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state != BLK_INIT))
return NO_ERROR;
if (m_curBlock.state == BLK_WRITE)
rc = writeCurBlk();
if ((m_curBlock.state == BLK_INIT) || (m_curBlock.lbid != m_lbid))
{
memset(m_curBlock.data, 0, sizeof(m_curBlock.data));
rc = readDBFile(cb, m_curBlock.data, m_lbid);
if (rc != NO_ERROR)
return rc;
m_curBlock.dirty = true;
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::writeCurBlk()
{
int rc;
CommBlock cb;
if (m_curBlock.state == BLK_WRITE)
{
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
rc = writeDBFile(cb, m_curBlock.data, m_curBlock.lbid);
m_curBlock.state = BLK_READ;
return rc;
}
else
return NO_ERROR;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::updateLastPtrAndParent(const int lastCount)
{
int rc = NO_ERROR;
rc = updateLastPtr(lastCount);
rc = updateParent();
return rc;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::updateParent()
{
int rc;
if (m_useNarray)
{
IdxRidParentListPtr parentIdxListPtr;
memset(&parentIdxListPtr, 0, sizeof(parentIdxListPtr));
parentIdxListPtr.parentLbid = (uint64_t)INVALID_LBID;
rc = getParentInfoFromArray(parentIdxListPtr);
m_parentLbid = (uint64_t)parentIdxListPtr.parentLbid;
// If this block has no parent, then it is the first block
if ((m_parentLbid <= (uint64_t)0) || (m_parentLbid == (uint64_t)INVALID_LBID))
m_parentLbid = m_lbid; // It is truly itself
// The previous lbid m_lbid is full, so we have to go to nextLbid
// and register it to the parent block
rc = updateParentStatus(m_nextLbid);
return rc;
}
else
return NO_ERROR;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::updateLastPtr(const int lastCount)
{
int rc;
if (m_curBlock.state == BLK_INIT)
readCurBlk();
if (m_useNarray)
{
rc = setCurBlkNextPtr(m_nextLbid, lastCount);
rc = writeCurBlk();
}
else
{
((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->fbo = m_nextLbid;
((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->sbid = 0;
((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->entry = 0;
m_lastIdxRidListPtr.type = LIST_BLOCK_TYPE;
m_lastIdxRidListPtr.spare = 0x0;
m_lastIdxRidListPtr.count = lastCount;
setSubBlockEntry(m_curBlock.data, m_sbid, LIST_BLOCK_LLP_POS, LIST_ENTRY_WIDTH, &m_lastIdxRidListPtr);
m_curBlock.state = BLK_WRITE;
rc = writeCurBlk();
}
return rc;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::addRidInBlk(const RID& newRid)
{
int maxCount, count = 0;
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
if (m_useNarray)
maxCount = MAX_BLK_NARRAY_RID_CNT;
else
maxCount = MAX_BLK_RID_CNT;
// Find the last block that has a space or
// No next block linked
rc = findLastBlk(count);
if ((count == maxCount) && (m_nextType == LIST_SIZE_TYPE))
{
// Full, also need a new segment
IdxEmptyListEntry newIdxListEntryPtr;
m_segType = LIST_BLOCK_TYPE;
rc = getSegment(m_pFile, ENTRY_BLK, &newIdxListEntryPtr);
m_nextLbid = ((IdxEmptyListEntry*)&newIdxListEntryPtr)->fbo;
m_nextType = m_segType;
m_lastIdxRidListPtr.llp = ((IdxRidListPtr*)&newIdxListEntryPtr)->llp;
rc = updateLastPtrAndParent(count);
// the new block for insertion and count record
m_lbid = m_nextLbid;
m_sbid = 0;
m_entry = 0;
m_curType = m_nextType;
rc = readCurBlk();
// free manager puts bad entry type at the last entry for new block
// clean it up!
IdxRidListPtr idxRidListPtr;
memset(&idxRidListPtr, 0, sizeof(idxRidListPtr));
rc = setNextInfoFromBlk(idxRidListPtr);
if (m_useNarray)
{
rc = initCurBlock();
}
// Set the count to the beginning
count = 0;
} // end if FULL get new segment
// insert in the current block at the location
if (m_lastLbid != m_lbid)
{
rc = setLastLbid(m_lbid);
}
rc = insertRid(newRid, count);
rc = updateCurCount();
rc = updateHdrCount();
return rc;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::findLastBlk(int& count)
{
int maxCount;
int rc;
if (m_useNarray)
maxCount = MAX_BLK_NARRAY_RID_CNT;
else
maxCount = MAX_BLK_RID_CNT;
rc = readCurBlk();
rc = getNextInfo(count);
while ((count == maxCount) && (m_nextType == LIST_BLOCK_TYPE))
{
// current is a Full link, No space to insert, go to the next one
m_lbid = m_nextLbid;
m_sbid = 0;
m_entry = 0;
rc = readCurBlk();
rc = getNextInfo(count);
} // end of while
return rc;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::insertRid(const RID& newRid, int& pos)
{
int rc = NO_ERROR;
IdxRidListEntry idxRidListEntry;
if (m_curType == LIST_BLOCK_TYPE)
{
m_sbid = 0;
m_entry = 0;
}
memset(&idxRidListEntry, 0, LIST_ENTRY_WIDTH);
idxRidListEntry.type = LIST_RID_TYPE;
idxRidListEntry.spare = 0;
// cout << "line 910:newRid->" << newRid << endl;
idxRidListEntry.rid = newRid;
if (m_lbid != m_hdrLbid)
{
rc = readCurBlk();
setSubBlockEntry(m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListEntry);
m_curBlock.state = BLK_WRITE;
}
else
{
setSubBlockEntry(m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListEntry);
m_hdrBlock.state = BLK_WRITE;
}
return rc;
}
/************************************************
* No Change
* RETURN:
* success - successfully created the index list header
* failure - it did not create the index list header
***********************************************************/
const int IndexList::updateCurCount(int frequency)
{
int rc = NO_ERROR;
int pos = 0;
if (m_curType == LIST_SUBBLOCK_TYPE)
pos = LIST_SUB_LLP_POS;
else if (m_curType == LIST_BLOCK_TYPE)
{
pos = LIST_BLOCK_LLP_POS;
m_sbid = 0;
m_entry = 0;
}
if ((m_useNarray) && (m_curType == LIST_BLOCK_TYPE))
rc = updateCurCountInArray();
else
{
rc = getNextInfoFromBlk(m_lastIdxRidListPtr);
for (int i = 0; i < frequency; i++)
m_lastIdxRidListPtr.count++;
if (m_lbid == m_hdrLbid)
{
setSubBlockEntry(m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &m_lastIdxRidListPtr);
m_hdrBlock.state = BLK_WRITE;
}
else
{
setSubBlockEntry(m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &m_lastIdxRidListPtr);
m_curBlock.state = BLK_WRITE;
};
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::getNextInfo(int& count)
{
int rc;
if ((!m_useNarray) || (m_curType == LIST_SUBBLOCK_TYPE))
{
rc = getNextInfoFromBlk(m_lastIdxRidListPtr);
count = m_lastIdxRidListPtr.count;
m_nextType = m_lastIdxRidListPtr.type;
m_nextLbid = ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->fbo;
}
else
{
rc = getNextInfoFromArray(m_nextIdxListPtr);
count = m_nextIdxListPtr.count;
m_nextType = m_nextIdxListPtr.type;
m_nextLbid = m_nextIdxListPtr.nextLbid;
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function non-array
*
***************************************************************/
const int IndexList::getNextInfoFromBlk(IdxRidListPtr& idxRidListPtr)
{
int rc = NO_ERROR;
int pos = 0;
memset(&idxRidListPtr, 0, sizeof(idxRidListPtr));
if (m_curType == LIST_SUBBLOCK_TYPE)
pos = LIST_SUB_LLP_POS;
else if (m_curType == LIST_BLOCK_TYPE)
pos = LIST_BLOCK_LLP_POS;
if ((m_hdrBlock.lbid == m_lbid) && (m_hdrBlock.state >= BLK_READ))
getSubBlockEntry(m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListPtr);
else if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state >= BLK_READ))
getSubBlockEntry(m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListPtr);
else
return ERR_IDX_LIST_WRONG_BLK;
if ((idxRidListPtr.type != 0) && (idxRidListPtr.type != 4) && (idxRidListPtr.type != 5))
{
// cout << "line 1028->m_lbid=" << m_lbid << " m_sbid =" << m_sbid << " m_entry" <<m_entry<< endl;
// cout <<"line 1029->idxRidListPtr.type = " << idxRidListPtr.type << endl;
memset(&idxRidListPtr, 0, sizeof(idxRidListPtr));
}
return rc;
}
/****************************************************************
* DESCRIPTION:
* Private Function for setting the last Fbo on header
*
***************************************************************/
const int IndexList::setNextInfoFromBlk(IdxRidListPtr& idxRidListPtr)
{
int rc = NO_ERROR;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
int pos = 0;
if (m_curType == LIST_SUBBLOCK_TYPE)
pos = LIST_SUB_LLP_POS;
else if (m_curType == LIST_BLOCK_TYPE)
pos = LIST_BLOCK_LLP_POS;
if (m_lbid == m_hdrLbid)
{
// when sub == hdr
setSubBlockEntry(m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListPtr);
m_hdrBlock.state = BLK_WRITE;
}
else
{
readCurBlk();
if (m_lbid == m_curBlock.lbid)
{
setSubBlockEntry(m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, &idxRidListPtr);
rc = writeDBFile(cb, m_curBlock.data, m_lbid);
m_curBlock.state = BLK_READ;
}
else
return ERR_IDX_LIST_WRONG_LBID_WRITE;
}
return rc;
}
} // namespace WriteEngine