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_find_delete.cpp
2016-01-06 14:08:59 -06:00

1068 lines
45 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>
#ifndef _MSC_VER
#include <inttypes.h>
#endif
#include "we_indextree.h"
#include "we_indexlist.h"
using namespace std;
namespace WriteEngine
{
/************************************************
* 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::deleteInSub( const RID& rowId)
{
int rc =ERR_IDX_LIST_INVALID_DELETE;
DataBlock prevDataBlock;
int pos =0, totalbytes=0;
IdxRidListPtr* lastIdxRidListPtr;
int type;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
//get thelbid sbid and entry out from the header last entry
//First Sub-block
m_lbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
m_sbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
m_entry=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;
//Read the pointer entry at LIST_SUB_LLP_POS location
IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY];
IdxRidListEntry newRowIdArray[MAX_BLOCK_ENTRY];
memset(rowIdArray,0,BYTE_PER_BLOCK);
memset(newRowIdArray,0,BYTE_PER_BLOCK);
//First link
pos = LIST_SUB_LLP_POS;
totalbytes = SUBBLOCK_TOTAL_BYTES;
m_entryGroup = ENTRY_32;
if (m_lbid!=m_hdrLbid)
{
rc = readDBFile(cb, &m_curBlock, m_lbid );
if (rc != NO_ERROR)
return rc;
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid,
m_sbid, 0, totalbytes,
rowIdArray);
if (rc != NO_ERROR)
return rc;
m_curBlock.dirty=true;
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
}
else
{
if (m_hdrBlock.state >= BLK_READ)
getSubBlockEntry(m_hdrBlock.data, m_sbid,
0, totalbytes, rowIdArray );
else
return ERR_IDX_LIST_INVALID_DELETE;
}
lastIdxRidListPtr=(IdxRidListPtr*)&rowIdArray[pos];
int count;
type = lastIdxRidListPtr->type; //next type
count = lastIdxRidListPtr->count;//current count
for (int i=0; i<count; i++)
{
if (rowIdArray[i].rid == rowId)
{//found
m_dLbid = m_lbid;
m_dSbid = m_sbid;
m_dEntry= i;
rc = NO_ERROR;
memcpy(&newRowIdArray[0],
&rowIdArray[0], totalbytes);
lastIdxRidListPtr->count--;
if (lastIdxRidListPtr->count==0)
{
if (type == LIST_SIZE_TYPE)
{
//header has no link
m_curIdxRidListHdr.nextIdxRidListPtr.type
=LIST_NOT_USED_TYPE;
m_curIdxRidListHdr.nextIdxRidListPtr.llp= 0;
}
}//header's link block has nothing now
else //still have more
{
memcpy(&rowIdArray[i],&newRowIdArray[i+1],(count-(i+1))*LIST_ENTRY_WIDTH);
}
//last row id entry now moved up, so not used
rowIdArray[count-1].type =LIST_NOT_USED_TYPE;
rowIdArray[count-1].rid =0;
rowIdArray[count-1].spare =0;
//header update the size
m_curIdxRidListHdr.idxRidListSize.size--;
if (m_lbid!=m_hdrLbid)
{
setSubBlockEntry( m_curBlock.data,
m_sbid,0, totalbytes,
rowIdArray );
rc = writeDBFile( cb, m_curBlock.data, m_lbid);
if (rc != NO_ERROR)
return rc;
m_curBlock.state =BLK_READ;
rc = writeSubBlockEntry(cb,&m_hdrBlock,
m_hdrLbid,m_hdrSbid,
m_hdrEntry,
LIST_HDR_SIZE,
&m_curIdxRidListHdr );
if (rc != NO_ERROR)
return rc;
m_hdrBlock.state = BLK_READ;
}
else
{//m_lbid==m_hdrLbid
setSubBlockEntry( m_hdrBlock.data,
m_sbid,0, totalbytes,
rowIdArray );
setSubBlockEntry( m_hdrBlock.data,
m_hdrSbid,m_hdrEntry,
LIST_HDR_SIZE,
&m_curIdxRidListHdr);
m_hdrBlock.state = BLK_WRITE;
rc = writeDBFile( cb, m_hdrBlock.data,
m_hdrLbid);
if (rc != NO_ERROR)
return rc;
m_hdrBlock.state = BLK_READ;
} //end if m_lbid==m_hdrHdrLbid
m_dEntry = i;
return rc;
}//endif found
}//end for
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::deleteInBlock(const RID& rowId)
{
int width =LIST_ENTRY_WIDTH;
int rc =ERR_IDX_LIST_INVALID_DELETE;
IdxRidListPtr* lastIdxRidListPtr;
IdxRidListPtr lastSubIdxRidListPtr;
bool found;
int type, count;
IdxRidListPtr prevIdxRidListPtr;
int prevSbid, prevEntry, prevType;
uint64_t prevLbid;
DataBlock prevDataBlock;
int pos =0, totalbytes=0;
int preTotalBytes, prevPos ;
//IdxRidNextListPtr *nextIdxListPtr;
IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY];
IdxRidListEntry newRowIdArray[MAX_BLOCK_ENTRY];
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
//This is the sub block info
prevLbid = m_lbid;
prevSbid = m_sbid;
prevEntry = m_entry;
prevPos = LIST_SUB_LLP_POS;
preTotalBytes = SUBBLOCK_TOTAL_BYTES;
if (prevLbid == m_hdrLbid)
{
if (m_hdrBlock.state >=BLK_READ)
getSubBlockEntry(m_hdrBlock.data, m_sbid,
prevPos, LIST_ENTRY_WIDTH, &lastSubIdxRidListPtr );
else
return ERR_IDX_LIST_INVALID_DELETE;
}
else
{
if (m_curBlock.state >=BLK_READ)
getSubBlockEntry(m_curBlock.data, m_sbid,
prevPos, LIST_ENTRY_WIDTH, &lastSubIdxRidListPtr );
else
return ERR_IDX_LIST_INVALID_DELETE;
}
found = false;
m_lbid = ((IdxEmptyListEntry*)&lastSubIdxRidListPtr)->fbo;
m_sbid = 0;
m_entry = 0;
type = lastSubIdxRidListPtr.type;
count = lastSubIdxRidListPtr.count;
pos = LIST_BLOCK_LLP_POS;
totalbytes = BYTE_PER_BLOCK;
//Not found in the first sub
while ((!found) &&(type==LIST_BLOCK_TYPE))
{
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, 0, 0,
totalbytes, rowIdArray);
if (rc != NO_ERROR)
return rc;
m_curBlock.dirty = true;
m_curBlock.state =BLK_READ;
m_curBlock.lbid = m_lbid;
prevType = type; //Save it just in case not found here
lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos];
type = lastIdxRidListPtr->type;
count = lastIdxRidListPtr->count;
//prepared for not found in current block
//find out what is the next type
//Next Type is needed here
for (int i=0; i<count; i++)
{
if (rowIdArray[i].rid == rowId)
{//found the rowid
memcpy(&newRowIdArray[0],&rowIdArray[0],totalbytes);
found = true;
m_dLbid = m_lbid;
m_dSbid = m_sbid;
m_dEntry = i;
lastIdxRidListPtr->count--;
if (lastIdxRidListPtr->count==0)
{
if (!m_useNarray)
{
//get the previous value out, could be a sub block
if (prevLbid == m_hdrLbid)
getSubBlockEntry(m_hdrBlock.data, prevSbid,
prevPos, LIST_ENTRY_WIDTH,
&prevIdxRidListPtr);
else if (prevLbid == m_lbid)
getSubBlockEntry(m_curBlock.data, prevSbid,
prevPos, LIST_ENTRY_WIDTH,
&prevIdxRidListPtr);
else
rc = readSubBlockEntry(cb, &prevDataBlock, prevLbid,
prevSbid, prevPos, LIST_ENTRY_WIDTH,
&prevIdxRidListPtr);
if (rc != NO_ERROR)
return rc;
//check the type before set
if (type == LIST_BLOCK_TYPE)
{
((IdxEmptyListEntry*)&prevIdxRidListPtr)->fbo
= ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
((IdxEmptyListEntry*)&prevIdxRidListPtr)->sbid
= ((IdxEmptyListEntry*)lastIdxRidListPtr)->sbid;
((IdxEmptyListEntry*)&prevIdxRidListPtr)->entry
= ((IdxEmptyListEntry*)lastIdxRidListPtr)->entry;
//safety check
prevIdxRidListPtr.type= type;
}
else // If no more links, the current one is gone also
{
if (prevIdxRidListPtr.count>0)
{
prevIdxRidListPtr.type =0;
prevIdxRidListPtr.llp = 0;
}
else
{//In case it is a sub block, not released with 0 count
prevIdxRidListPtr.type =LIST_NOT_USED_TYPE;
prevIdxRidListPtr.llp = 0;
}
}//end if type =LIST_SUBBLOCK_TYPE,LIST_BLOCK_TYPE
//;set to LIST_NOT_USED_TYPE--unused before release
lastIdxRidListPtr->type=LIST_NOT_USED_TYPE;
lastIdxRidListPtr->llp =0;
if (prevPos == LIST_BLOCK_LLP_POS)
{
if (prevLbid<m_lastLbid)
rc = setLastLbid(prevLbid);
}
}
} //end if count==0
else
{
memcpy(&rowIdArray[i],&newRowIdArray[i+1],(count-(i+1))*LIST_ENTRY_WIDTH);
if (m_lastLbid > m_lbid)
rc = setLastLbid(m_lbid);
}//count check
//Found rowId
rowIdArray[count-1].type=LIST_NOT_USED_TYPE;
rowIdArray[count-1].rid =0;
m_curIdxRidListHdr.idxRidListSize.size--;
//Write Out Put in another routine
if ((prevLbid==m_hdrLbid) && (m_lbid != m_hdrLbid))
{// AAC --3
if (!m_useNarray)
{
if (lastIdxRidListPtr->count ==0)
{
setSubBlockEntry( m_hdrBlock.data, prevSbid,
prevPos, width,
&prevIdxRidListPtr );
}
}
setSubBlockEntry( m_curBlock.data, m_sbid,
0, totalbytes,
rowIdArray );
setSubBlockEntry( m_hdrBlock.data, m_hdrSbid,
m_hdrEntry, LIST_HDR_SIZE,
&m_curIdxRidListHdr );
rc = writeDBFile( cb, m_hdrBlock.data, m_hdrLbid);
if (rc != NO_ERROR)
return rc;
rc = writeDBFile( cb, m_curBlock.data, m_lbid);
if (rc != NO_ERROR)
return rc;
m_hdrBlock.state = BLK_READ;
m_curBlock.state = BLK_READ;
}
else
{ //ABC --
if (!m_useNarray)
{
if (lastIdxRidListPtr->count ==0)
{
setSubBlockEntry( prevDataBlock.data, prevSbid,
prevPos, LIST_ENTRY_WIDTH,
&prevIdxRidListPtr );
rc = writeDBFile( cb, prevDataBlock.data,prevLbid);
if (rc != NO_ERROR)
return rc;
}
}
setSubBlockEntry( m_curBlock.data, m_sbid,
0, totalbytes,
rowIdArray );
setSubBlockEntry( m_hdrBlock.data, m_hdrSbid,
m_hdrEntry, LIST_HDR_SIZE,
&m_curIdxRidListHdr );
rc = writeDBFile( cb, m_hdrBlock.data, m_hdrLbid);
if (rc != NO_ERROR)
return rc;
rc = writeDBFile( cb, m_curBlock.data, m_lbid);
memset(m_hdrBlock.data,0,
sizeof(m_hdrBlock.data));
if (rc != NO_ERROR)
return rc;
m_hdrBlock.state = BLK_READ;
m_curBlock.state = BLK_READ;
} //last case A B C --end 5
//Done with writing to disk
// Now we need to release the segment
if (!m_useNarray)
{
if (lastIdxRidListPtr->count ==0)
{
rc = releaseSegment();
if (rc != NO_ERROR)
return rc;
}// end release segment when count ==0
}
m_entry =i; //for use in findRow ID
return rc; //DONE !!!found then we return, no need to go on
}//FOUND THE ROWID returned !!!!
}//for loop i not found continue to i++
//NOT FOUND in this block go to next block
//assigning the current llp as previous llp:lbid, sbid, entry
prevLbid = m_lbid;
prevSbid = 0;
prevEntry = 0;
prevPos = pos;
preTotalBytes = totalbytes;
m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
m_sbid = 0;
m_entry = 0;
}// end while
if (!found)
rc = ERR_IDX_LIST_INVALID_DELETE;
return rc;
}
/************************************************
* Description:
* Converted
* Find an 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( FILE* pFile, const RID& rowId,
const uint64_t& key, IdxEmptyListEntry* curIdxRidListHdrPtr,
uint64_t& lbid, int&sbid, int& entry)
{
int rc =ERR_IDX_LIST_INVALID_DELETE;
bool found = false;
m_pFile = pFile;
getHdrInfo(curIdxRidListHdrPtr);
if (key!= m_curIdxRidListHdr.key)
{
return ERR_IDX_LIST_INVALID_KEY;
}
uint64_t dlbid =-1LL;
int dsbid = -1;
int dentry = -1;
rc = deleteIndexList(rowId,key,dlbid,dsbid,dentry);
if (rc!=NO_ERROR)
{
lbid=-1LL;
sbid =-1;
entry=-1;
found = false;
return rc;
}
else
{
lbid = dlbid;
sbid = dsbid;
entry = dentry;
}
return rc;
}
/************************************************
* Description:
* No change
* 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,
uint64_t& lbid, int&sbid, int& entry)
{
int rc =ERR_IDX_LIST_INVALID_DELETE;
rc = deleteIndexList(rowId,key);
lbid = m_dLbid;
sbid = m_dSbid;
entry = m_dEntry;
return rc;
}
/************************************************
* Description:
* Converted
* Find all of the row Id or toke from list
* input
* pFile -- File Handler
* curIdxRidListHdrPtr - point to the header
*
* return value
* Success -- 0
* Fail -- ERR_IDX_LIST_INVALID_DELETE
************************************************/
const int IndexList::getRIDArrayFromListHdr(FILE* pFile, uint64_t& key,
IdxEmptyListEntry* curIdxRidListHdrPtr,
RID* ridArray, int& size)
{
int rc=NO_ERROR;
int arrayCount = 0;
IdxRidNextListPtr *nextIdxListPtr = NULL;
m_pFile = pFile;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
rc = getHdrInfo(curIdxRidListHdrPtr);
if (m_curIdxRidListHdr.idxRidListSize.size==0)
{size =0; return NO_ERROR;}
if (key!= m_curIdxRidListHdr.key)
{
return ERR_IDX_LIST_WRONG_KEY;
}
// cout << "IndexList::getRIDArrayFromListHdr->KEY ------>" << key << endl;
//Check the first row location, 3rd enty
if (m_curIdxRidListHdr.firstIdxRidListEntry.type==(int)LIST_RID_TYPE)
{
ridArray[arrayCount]= (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid;
//cout<<" IndexList::getRIDArrayFromListHdr->header Lbid->" << m_hdrLbid <<" count->" << arrayCount <<endl;
arrayCount++;
//cout << "RID = " << (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid << endl;
};
//Check Header last entry's type
int type = m_curIdxRidListHdr.nextIdxRidListPtr.type;
switch (type)
{
case LIST_RID_TYPE:// There is a row id here, Check!
ridArray[arrayCount]=(RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp;
//cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl;
arrayCount++;
//cout << "RID = " << (RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp << endl;
size = arrayCount;
return NO_ERROR;
case LIST_SUBBLOCK_TYPE://Not found in header, so go to the sub-block
//get thelbid sbid and entry out from the header last entry
m_lbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
m_sbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
m_entry=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;
m_curType = type;
//Read the pointer entry at LIST_SUB_LLP_POS location
IdxRidListPtr *lastIdxRidListPtr;
IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY];
memset(rowIdArray,0,BYTE_PER_BLOCK);
int pos =0, totalbytes=0;
pos = LIST_SUB_LLP_POS;
totalbytes = SUBBLOCK_TOTAL_BYTES;
if (m_lbid!=m_hdrLbid)
{
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid,
m_sbid, 0, totalbytes,
rowIdArray);
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
m_curBlock.dirty = true;
}
else
getSubBlockEntry(m_hdrBlock.data, m_sbid,
0, totalbytes,
rowIdArray );
int type, count;
lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos];
type = lastIdxRidListPtr->type;
count = lastIdxRidListPtr->count;
//cout << "count->" << count << endl;
//type should be LIST_BLOCK_TYPE from now on
for (int i=0; i<count; i++)
{
ridArray[arrayCount]= (RID)(rowIdArray[i].rid);
//cout << "RID =" << (RID)(rowIdArray[i].rid) << endl;
//cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl;
arrayCount++;
}
//cout << " Lbid->" << m_lbid ;
//cout << " count->" << count << endl;
m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
while (type ==LIST_BLOCK_TYPE)
{
//cout << " Lbid->" << m_lbid ;
pos = LIST_BLOCK_LLP_POS;
totalbytes = BYTE_PER_BLOCK;
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, 0 , 0,
totalbytes, rowIdArray);
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
m_curBlock.dirty = true;
if (!m_useNarray)
{
lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos];
type = lastIdxRidListPtr->type;
count = lastIdxRidListPtr->count;
}
else
{
nextIdxListPtr = (IdxRidNextListPtr *)&rowIdArray[pos];
type = nextIdxListPtr->type;
count = nextIdxListPtr->count;
}
//cout << " count->" << count << endl;
for (int i=0; i<count; i++)
{
ridArray[arrayCount]=(RID)(rowIdArray[i].rid) ;
//cout << "RID =" << (RID)(rowIdArray[i].rid) << endl;
//cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl;
arrayCount++;
}
if (type ==LIST_BLOCK_TYPE)
{
if (m_useNarray)
m_lbid = nextIdxListPtr->nextLbid;
else
m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
}
}//end while
};//end of switch
size = arrayCount;
return rc;
}//end getRIDArrayFromListHdr
const int IndexList::getRIDArrayFromListHdrNarray(FILE* pFile, uint64_t& key,
IdxEmptyListEntry* curIdxRidListHdrPtr,
RID* ridArray, int& size, bool flag)
{
int rc=NO_ERROR;
IdxRidNextListPtr *nextIdxListPtr;
int pos =0, totalbytes=0;
IdxRidListPtr *lastIdxRidListPtr;
IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY*10];
int type=0, count=0;
m_pFile = pFile;
CommBlock cb;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
if (flag)
{
rc = getHdrInfo(curIdxRidListHdrPtr);
if (m_curIdxRidListHdr.idxRidListSize.size==0)
{size =0; return NO_ERROR;}
if (key!= m_curIdxRidListHdr.key)
{
return ERR_IDX_LIST_WRONG_KEY;
}
// cout << "IndexList::getRIDArrayFromListHdr->KEY ------>" << key << endl;
//Check the first row location, 3rd enty
if (m_curIdxRidListHdr.firstIdxRidListEntry.type==(int)LIST_RID_TYPE)
{
ridArray[size]= (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid;
//cout<<" IndexList::getRIDArrayFromListHdr->header Lbid->" << m_hdrLbid <<" count->" << arrayCount <<endl;
size++;
//cout << "RID = " << (RID)m_curIdxRidListHdr.firstIdxRidListEntry.rid << endl;
};
//Check Header last entry's type
int type = m_curIdxRidListHdr.nextIdxRidListPtr.type;
switch (type)
{
case LIST_RID_TYPE:// There is a row id here, Check!
ridArray[size]=(RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp;
//cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl;
size++;
//cout << "RID = " << (RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp << endl;
return NO_ERROR;
case LIST_SUBBLOCK_TYPE://Not found in header, so go to the sub-block
//get thelbid sbid and entry out from the header last entry
m_lbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
m_sbid=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
m_entry=((IdxEmptyListEntry*)&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;
m_curType = type;
//Read the pointer entry at LIST_SUB_LLP_POS location
memset(rowIdArray,0,BYTE_PER_BLOCK);
pos = LIST_SUB_LLP_POS;
totalbytes = SUBBLOCK_TOTAL_BYTES;
if (m_lbid!=m_hdrLbid)
{
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid,
m_sbid, 0, totalbytes,
rowIdArray);
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
m_curBlock.dirty = true;
}
else
getSubBlockEntry(m_hdrBlock.data, m_sbid,
0, totalbytes,
rowIdArray );
lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos];
type = lastIdxRidListPtr->type;
count = lastIdxRidListPtr->count;
//cout << "count->" << count << endl;
//type should be LIST_BLOCK_TYPE from now on
for (int i=0; i<count; i++)
{
ridArray[size]= (RID)(rowIdArray[i].rid);
//cout << "RID =" << (RID)(rowIdArray[i].rid) << endl;
//cout<<"arrayCount->" << arrayCount << "rid->" << ridArray[arrayCount]<<endl;
size++;
}
//cout << " Lbid->" << m_lbid ;
//cout << " count->" << count << endl;
m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
m_curType = type;
}//end of switch
}//end if flag
if (m_curType ==LIST_BLOCK_TYPE)
{
pos = LIST_BLOCK_LLP_POS;
totalbytes = BYTE_PER_BLOCK;
rc = readSubBlockEntry(cb, &m_curBlock, m_lbid, 0 , 0,
totalbytes, rowIdArray);
m_curBlock.lbid = m_lbid;
m_curBlock.state = BLK_READ;
m_curBlock.dirty = true;
nextIdxListPtr = (IdxRidNextListPtr *)&rowIdArray[pos];
type = nextIdxListPtr->type;
count = nextIdxListPtr->count;
for (int i=0; i<count; i++)
{
ridArray[size]=(RID)(rowIdArray[i].rid) ;
size++;
}
IdxRidListArrayPtr idxRidListArrayPtr;
int curLevel = 0, curCount=0;
memset(&idxRidListArrayPtr, 0, sizeof(idxRidListArrayPtr));
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<TOTAL_NUM_ARRAY_PTR; i++)
{
m_lbid = idxRidListArrayPtr.childIdxRidListPtr[i].childLbid;
int type = idxRidListArrayPtr.childIdxRidListPtr[i].type;
if ((m_lbid != (uint64_t)INVALID_LBID) &&(type == LIST_BLOCK_TYPE))
{
m_curType=LIST_BLOCK_TYPE;
getRIDArrayFromListHdrNarray(pFile,key,curIdxRidListHdrPtr,
ridArray, size, false);
}
}
}//end if block
return rc;
}//end getRIDArrayFromListHdrNarray
/*---------------------------------------------------------------------
* Description: Output the info of this company to an abstract stream
*
* Input: None
*
* Output: None
*
* Comments: None
*
* Return Code: the abstract output stream
*------------------------------------------------------------------*/
ostream& operator<<(ostream& os, IndexList& rhs)
{
os << rhs.m_curIdxRidListHdr.idxRidListSize.size << "\t"
<< rhs.m_curIdxRidListHdr.key << "\t"
<< rhs.m_curIdxRidListHdr.firstIdxRidListEntry.type << "\t"
<< rhs.m_curIdxRidListHdr.firstIdxRidListEntry.rid << "\t"
<< rhs.m_curIdxRidListHdr.nextIdxRidListPtr.type << "\t"
<< rhs.m_curIdxRidListHdr.nextIdxRidListPtr.llp << "\t"
<<endl;
return os;
}
/************************************************
* 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
************************************************/
bool IndexList::findRowId(FILE* pFile, const RID& rowId, const uint64_t& key,
IdxEmptyListEntry* curIdxRidListHdrPtr,
uint64_t& lbid, int& sbid, int& entry)
{
bool found = false;
int rc;
m_pFile = pFile;
rc = getHdrInfo(curIdxRidListHdrPtr);
if (key!= m_curIdxRidListHdr.key)
{
return false;
}
found = findRowId(rowId, key, lbid, sbid, entry);
return found;
}
/************************************************
* 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
************************************************/
bool IndexList::findRowId(const RID& rowId, const int64_t& key,
int64_t& lbid, int& sbid, int& entry)
{
bool found = false;
int rc;
RID savedRid;
CommBlock cb;
int count;
uint64_t prevLbid;
int prevType;
cb.file.oid = m_oid;
cb.file.pFile = m_pFile;
//Check the first row location, 3rd enty--0,1,2
if (m_curIdxRidListHdr.firstIdxRidListEntry.type== (int)LIST_RID_TYPE)
{
if (m_curIdxRidListHdr.firstIdxRidListEntry.rid == rowId)
{
lbid = m_hdrLbid;
sbid = m_hdrSbid;
entry = m_hdrEntry+2;
found = true;
return found;
}
}; //endif type=LIST_RID_TYPE
//Check Header last entry's type
int type = m_curIdxRidListHdr.nextIdxRidListPtr.type;
int pos =0, totalbytes =0;
switch (type)
{
case LIST_NOT_USED_TYPE://Header is not full, no sub-block linked
//No RowId here then on
lbid=-1LL;
sbid =-1;
entry =-1;
found =false;
return found; //not found
case LIST_RID_TYPE:// There is a row id here, Check!
savedRid = (RID)m_curIdxRidListHdr.nextIdxRidListPtr.llp;
if (savedRid == rowId)
{
lbid = m_hdrLbid;
sbid = m_hdrSbid;
entry = m_hdrEntry+3;
found =true;
return found;
}
else
{
lbid=-1LL;
sbid = -1;
entry =-1;
found = false;
return found;
}
case LIST_SUBBLOCK_TYPE://Not found in header
//get the lbid sbid and entry out from the header last entry
m_lbid =((IdxEmptyListEntry*)
&(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
m_sbid =((IdxEmptyListEntry*)
&(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
m_entry=((IdxEmptyListEntry*)
&(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;
//Read the pointer entry at LIST_SUB_LLP_POS
//reserve enough space for rowIdArray
IdxRidListPtr *lastIdxRidListPtr;
IdxRidListEntry rowIdArray[MAX_BLOCK_ENTRY];
memset(rowIdArray, 0, BYTE_PER_BLOCK);
//first link
pos = LIST_SUB_LLP_POS;
totalbytes = SUBBLOCK_TOTAL_BYTES;
//check if the sub block is on the header block
if (m_lbid != m_hdrLbid)
{
rc = readSubBlockEntry( cb, &m_curBlock, m_lbid, m_sbid, 0,
totalbytes, rowIdArray);
m_curBlock.dirty = true;
m_curBlock.state = BLK_READ;
}
else
{
getSubBlockEntry(m_hdrBlock.data, m_sbid,
0, totalbytes, rowIdArray );
}
lastIdxRidListPtr =(IdxRidListPtr *) &rowIdArray[pos];
prevLbid = m_lbid; //sub block
prevType = type; //sub block
count = lastIdxRidListPtr->count; //current count
type = lastIdxRidListPtr->type; //block
found = false;
//look inside the first sub block
for (int i=0; i<count; i++)
{
if (rowIdArray[i].rid == rowId)
{
found = true;
lbid = m_lbid;
sbid = m_sbid;
entry = i;
return found;
}
}
while ((!found) &&(type==LIST_BLOCK_TYPE))
{//There are more to check on the next link
m_lbid = ((IdxEmptyListEntry*)lastIdxRidListPtr)->fbo;
m_sbid = 0;
m_entry = 0;
pos = LIST_BLOCK_LLP_POS;
totalbytes = BYTE_PER_BLOCK;
if ((m_lbid !=m_hdrLbid) && (m_lbid != prevLbid))
{ // the only case for block
rc = readSubBlockEntry( cb, &m_curBlock, m_lbid,
m_sbid, 0, totalbytes,
rowIdArray);
m_curBlock.dirty=true;
}
else
{
printf("error in findRowID\n");
return false;
}
prevType = type;
lastIdxRidListPtr=(IdxRidListPtr *) &rowIdArray[pos];
type = lastIdxRidListPtr->type;
count = lastIdxRidListPtr->count;
found = false;
for (int i=0; i<count; i++)
{
if (rowIdArray[i].rid == rowId)
{
found = true;
lbid = m_lbid;
sbid = m_sbid;
entry = i;
return found;
}
}//end for i
prevLbid = m_lbid;
} //end while
break;
default:
printf ("FIND ROWID got no where, error out !! \n");
break;
}; //end switch
lbid =INVALID_LBID;
sbid =INVALID_NUM;
entry=INVALID_NUM;
found = false;
return found;
} //end function
} //end of namespace