/************************************************ * 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; }
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; }
/************************************************ * No Change * RETURN: * success - successfully created the index list header * failure - it did not create the index list header ***********************************************************/ const int IndexList::addRidInSub(const RID& newRid, IdxRidListPtr& lastIdxRidListPtr) { int rc = NO_ERROR; int maxCount; int count; CommBlock cb; cb.file.oid = m_oid; cb.file.pFile = m_pFile; m_curType = LIST_SUBBLOCK_TYPE; m_segType = LIST_BLOCK_TYPE; m_nextType = lastIdxRidListPtr.type; maxCount = MAX_SUB_RID_CNT; count = lastIdxRidListPtr.count; //For n-array m_curLevel =0; m_curLevelPos = 0; m_curBlkPos = 0; m_parentLbid = INVALID_LBID; if ((count ==maxCount) && (m_nextType==LIST_SIZE_TYPE)) {//Full, need a new segment IdxEmptyListEntry newIdxListEntryPtr; memset(&newIdxListEntryPtr, 0, sizeof(newIdxListEntryPtr)); rc = getSegment( m_pFile, ENTRY_BLK, &newIdxListEntryPtr); if (rc!=NO_ERROR) return rc; lastIdxRidListPtr.type = LIST_BLOCK_TYPE; lastIdxRidListPtr.llp=((IdxRidListPtr*)&newIdxListEntryPtr)->llp; lastIdxRidListPtr.spare=0x0; rc = setNextInfoFromBlk( lastIdxRidListPtr); //New Block initialization m_lbid = newIdxListEntryPtr.fbo; m_sbid = 0; m_entry = 0; m_curType = m_segType; rc = readCurBlk(); //make sure no garbage in the new block last entry IdxRidListPtr idxRidListPtr; memset(&idxRidListPtr, 0, sizeof(idxRidListPtr)); rc = setNextInfoFromBlk( idxRidListPtr); count = 0; if (m_useNarray) rc = initCurBlock(); if (m_lastLbid != m_lbid) { rc = setLastLbid(m_lbid); } }//end if FULL else if (count <maxCount)// if less than maxCount either type =7 or 0 { if (m_lastLbid != INVALID_LBID) { uint64_t zlbid = INVALID_LBID; rc = setLastLbid(zlbid); } } //endif count else if ((count ==maxCount) && (m_nextType==LIST_BLOCK_TYPE)) { m_lbid = ((IdxEmptyListEntry*)&lastIdxRidListPtr)->fbo; m_sbid = 0; m_entry = 0; m_curType = LIST_BLOCK_TYPE; rc = addRidInBlk(newRid); return rc; } rc = insertRid(newRid, count);// count is the position rc = updateCurCount(); rc = updateHdrCount(); return rc; }