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

346 lines
13 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>
#include <inttypes.h>
#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;
}
} // namespace WriteEngine