/****************************************************************
  * 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::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 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;
    }
Esempio n. 4
0
const int DbFileOp::readSubBlockEntry( CommBlock& cb, DataBlock* block, 
                                       const uint64_t lbid, const int sbid, 
                                       const int entryNo, const int width, 
                                       void* pStruct )
{
    RETURN_ON_ERROR( readDBFile( cb, block->data, lbid ) );
    getSubBlockEntry( block->data, sbid, entryNo, width, pStruct );

    return NO_ERROR;
}
Esempio n. 5
0
   const int FreeMgr::releaseSubblock( CommBlock &cb, DataBlock* blockZero, const int freemgr_type,  IdxEmptyListEntry* assignPtr ) 
   {
       int         rc;    // return code from file ops
       DataBlock   workBlock;
       DataBlock   extraBlock;
       int          listOffset; // entry in block zero of head pointer
       IdxEmptyListEntry emptyPtr, emptyMap ;
       uint64_t     numBlocks;
       FILE*       indexFile;
               
       indexFile = cb.file.pFile;
       /**
        * Release sub-block - handle de-allocation of only sub-blocks
        * This makes the assign/release code for smaller segments simpler and 
        * separates the tasks of handling the list containers and the list contents
        * When called, we look at the bucket indicated as head of chain and if it full
        * or not present (no room left in chain) then insert the returned SB as a bucket and 
        * move the head pointer
        **/
       
       
       //if( isDebug( DEBUG_1 )) { printf("DBG: releaseSubblock\n"); }
       if( isDebug( DEBUG_2 )) { 
           cout<<"DBG: releasing sb fbo "<<assignPtr->fbo<<" sbid "<<assignPtr->sbid<<" entry "<<assignPtr->entry<<" from "<<((freemgr_type==LIST)?"LIST":"TREE")<<" (type is "<<((assignPtr->type==EMPTY_PTR)?"EMPTY_PTR":"Not EMPTY_PTR")<<")\n";
       }
       if (!assignPtr){
//            printf ("DBG: Bad pointer: assignPtr is zero\n");
           return ERR_INVALID_PARAM;
       }

       if (!blockZero){
           printf ("DBG: Bad pointer: pointer for blockZero is zero\n");
           return ERR_INVALID_PARAM;
       }

       numBlocks = getFileSize( indexFile )/BYTE_PER_BLOCK ;
/*       if (assignPtr->fbo > numBlocks)
       {
       if( isDebug( DEBUG_1 )) { printf("DBG: Weirdness in releaseSubblock.. assignPtr.fbo > numBlocks (%llu %llu)\n", assignPtr->fbo, numBlocks );}
           return ERR_FM_BAD_FBO;
       }*/
       if (assignPtr->type != EMPTY_PTR)
       {
           printf("DBG: Weirdness in releaseSubblock.. tried to return a pointer with type %i (expected %i)\n", (unsigned int)assignPtr->type, EMPTY_PTR );
           return ERR_FM_BAD_TYPE;
       }
       if ( assignPtr->group != ENTRY_32 )
       {
           printf("DBG: Weirdness in releaseSubblock.. tried to return a pointer from group %i to subblock group\n", (unsigned int)assignPtr->group );
           return ERR_INVALID_PARAM;
       }           
       //find the start of the chain
       listOffset = calcPtrOffset( ENTRY_32 );

       getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
       if( isDebug( DEBUG_2 )) { 
          cout<<"DBG: EM (sb release 1) sb fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
       }

       //sub block is full or chain empty
       if (emptyPtr.entry == ENTRY_PER_SUBBLOCK-1 || emptyPtr.fbo==0)
       { 
       // change type from EMPTY_PTR to EMPTY_LIST 
           assignPtr->type = EMPTY_LIST;
           
           //if( isDebug( DEBUG_1 )) { printf("DBG: No room in subblock chain - need to add a sub-block\n");  }
           if( isDebug( DEBUG_2 )) { 
                   cout<<"DBG: Change head pointer to fbo "<<assignPtr->fbo<<" sbid "<<assignPtr->sbid<<" entry "<<assignPtr->entry<<"\n";
           }
           
           // change head pointer to released segment
           setSubBlockEntry( blockZero, 0, listOffset, 8, assignPtr );
           blockZero->dirty = 1;
           
           // read in released segment to set llp of new block to point to current head of chain
           rc = readDBFile( cb, extraBlock.data, assignPtr->fbo );
           if (rc != NO_ERROR){ 
               if (isDebug( DEBUG_1 )){
                   cout<<"DBG: File error during releaseSegment (2), rc: "<<rc<<" fbo/lbid: "<<assignPtr->fbo<<"\n"; 
               }
               return rc;
           }
           
           if( isDebug( DEBUG_2 )) { 
               cout<<"DBG: Set LLP for fbo "<<assignPtr->fbo<<" sbid "<<assignPtr->sbid<<" entry "<<assignPtr->entry<<"to fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
           }
           if( isDebug( DEBUG_3)){
               printf("Before\n");
               printMemSubBlock( &extraBlock, assignPtr->sbid );
           }
           
           emptyPtr.type = EMPTY_LIST;
           //memset( extraBlock.data, 0, BYTE_PER_SUBBLOCK);
           setSubBlockEntry( extraBlock.data, assignPtr->sbid, 0, 8, &emptyPtr );
           rc = writeDBFile( cb, &extraBlock, assignPtr->fbo );
           if (rc != NO_ERROR){ return rc; }
           
           if( isDebug( DEBUG_2 )) { 
               getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyMap );
               cout<<"DBG: EM (sb release 2) sb fbo "<<emptyMap.fbo<<" sbid "<<emptyMap.sbid<<" entry "<<emptyMap.entry<<"\n";
           }
           if( isDebug( DEBUG_3)){
               printf("After\n");
               printMemSubBlock( &extraBlock, assignPtr->sbid );
           }
           
       }
       else 
       { // 
           emptyPtr.entry++;
           rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
           if (rc != NO_ERROR) { 
               if (isDebug( DEBUG_1 ))
               {
                   printf("DBG: File error during releaseSubblock\n"); 
               }
               return rc;
           }
           
           if( isDebug( DEBUG_3)){
               printf("Before\n");
               printMemSubBlock( &workBlock, emptyPtr.sbid );
           }

           setSubBlockEntry( workBlock.data, emptyPtr.sbid, emptyPtr.entry, 8, assignPtr );
           rc = writeDBFile( cb, &workBlock, emptyPtr.fbo );
           if (rc != NO_ERROR){ return rc; }

           if( isDebug( DEBUG_2 )) { 
               cout<<"DBG: setting emptyPtr sb fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
           }
           if( isDebug( DEBUG_3)){
               printf("After\n");
               printMemSubBlock( &workBlock, emptyPtr.sbid );
           }
           
           emptyPtr.type = EMPTY_LIST;
           emptyPtr.group = ENTRY_32;

           setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
           blockZero->dirty = 1;

       }
       uint64_t count;
       
       getSubBlockEntry( blockZero, 0, calcStatOffset(ENTRY_32) , 8, &count );
       count++;
       setSubBlockEntry( blockZero, 0, calcStatOffset(ENTRY_32) , 8, &count );
               

       return NO_ERROR;
   }
Esempio n. 6
0
   const int FreeMgr::releaseSegment( CommBlock &cb, DataBlock* blockZero, const int freemgr_type, const IdxTreeGroupType segmentType,  IdxEmptyListEntry* assignPtr )
   {
       int         rc;    // return code from file ops
       DataBlock   workBlock;
       DataBlock   extraBlock;
       int          listOffset; // entry in block zero of head pointer
       IdxEmptyListEntry emptyPtr;
       IdxEmptyListEntry newSb; 
       uint64_t     numBlocks;
       FILE*       indexFile;
               
       indexFile = cb.file.pFile;

       if (!assignPtr){
//            printf ("DBG: Bad pointer: assignPtr is zero\n");
           return ERR_INVALID_PARAM;
       }

       if (!blockZero){
//            printf ("DBG: Bad pointer: blockZero is zero\n");
           return ERR_INVALID_PARAM;
       }
       if( isDebug( DEBUG_3 )) { printf("DBG: release ENTRY_%i segment \n", 1<<(unsigned int)segmentType); }
       if( isDebug( DEBUG_2 )) 
       { 
           cout<<"DBG: releasing fbo "<<assignPtr->fbo<<" sbid "<<assignPtr->sbid<<" entry "<<assignPtr->entry<<" from "<<((freemgr_type==LIST)?"LIST":"TREE")<<" chain ENTRY_"<<(1<<segmentType)<<" (type is "<<((assignPtr->type==EMPTY_PTR)?"EMPTY_PTR":"Not EMPTY_PTR")<<")\n";
       }
       
       numBlocks = getFileSize( indexFile )/BYTE_PER_BLOCK ;

       /*       if (assignPtr->fbo > numBlocks)
       {
           if( isDebug( DEBUG_1 )) { printf("DBG: Weirdness in releaseSegment.. assignPtr.fbo > numBlocks (%llu %llu)\n", assignPtr->fbo, numBlocks );};
           return ERR_FM_BAD_FBO;
       }*/
       
       if (assignPtr->type != EMPTY_PTR)
       {
//            printf("DBG: Weirdness in releaseSegment.. tried to return a pointer with type %i (expected %i)\n", (unsigned int)assignPtr->type, EMPTY_PTR );
           assignPtr->type = EMPTY_PTR;
           //            return ERR_FM_BAD_TYPE; // do not exit
       }
       if ( assignPtr->group != (uint64_t)segmentType )
       {
//            printf("DBG: Weirdness in releaseSegment.. tried to return a pointer from group %i to group %i\n", (unsigned int)assignPtr->group, segmentType );
           return ERR_FM_RELEASE_ERR;
       }
       
       //find the start of the chain
       if (segmentType == ENTRY_32)
       {
           rc = releaseSubblock( cb, blockZero, freemgr_type, assignPtr);
           if (rc != NO_ERROR)
           { 
//                    printf("DBG: Error releasing sb\n");
           }
           return rc;
       }
               
       listOffset = calcPtrOffset( segmentType );
       if (freemgr_type==LIST && !(segmentType== ENTRY_4 || segmentType== ENTRY_BLK))
       {
           printf("DBG: Assign segment size illegal %i\n", (unsigned int)segmentType);
           return ERR_INVALID_PARAM; // should not have got here so quit with error
       }

       getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );

/*       if (emptyPtr.fbo > numBlocks)
       {
       if( isDebug( DEBUG_1 )) { printf("DBG: Weirdness in releaseSegment.. emptyPtr.fbo > numBlocks (%llu %llu)\n", emptyPtr.fbo, numBlocks );}
           return ERR_FM_BAD_FBO;
       }*/
       
       //sub block is full or chain never started
       if (emptyPtr.entry == ENTRY_PER_SUBBLOCK-1 || emptyPtr.fbo==0)
       { 
           if( isDebug( DEBUG_3 ))
           { 
               printf("DBG: No room in chain %i - need to add a sub-block\n", (unsigned int)segmentType);
           }
           if( isDebug( DEBUG_2 )) 
           { 
               cout<<"DBG: Empty ptr fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
           }
            //ask for a new sb to extend chain
               rc = assignSubblock( cb, blockZero, freemgr_type, &newSb);
               if (rc != NO_ERROR) { printf("DBG: Error extending chain\n");  return rc; }
               if( isDebug( DEBUG_2 )) 
               { 
                   cout<<"DBG: release segment, new SB is fbo "<<newSb.fbo<<" sbid "<<newSb.sbid<<" entry "<<newSb.entry<<"\n";
               }
               rc = readDBFile( cb, extraBlock.data, newSb.fbo );
               if (rc != NO_ERROR)
               { 
                   if (isDebug( DEBUG_1 )){printf("DBG: File error during releaseSegment (3)\n");}
                   return rc; 
               }
               
               emptyPtr.type = EMPTY_LIST; // writing into the LLP field so set type accordingly
               setSubBlockEntry( extraBlock.data, newSb.sbid, 0, 8, &emptyPtr );
               setSubBlockEntry( extraBlock.data, newSb.sbid, 1, 8, assignPtr );
               rc = writeDBFile( cb, &extraBlock, newSb.fbo );
               if (rc != NO_ERROR)
               { 
                   if (isDebug( DEBUG_1 )){printf("DBG: File error during releaseSegment (4)\n");}
                   return rc; 
               }
               
               newSb.entry = 1;
               newSb.type = EMPTY_LIST;
               newSb.group = segmentType;

               setSubBlockEntry( blockZero, 0, listOffset, 8, &newSb );
               blockZero->dirty = 1;

               uint64_t count;
               getSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
               count++;
               setSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
               

               return NO_ERROR ;
            
       }
       else 
       { // 
           emptyPtr.entry++;
           rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
           if (rc != NO_ERROR){ 
               if (isDebug( DEBUG_1 )){ printf("DBG: File error during releaseSegment\n"); }
               return rc; 
           }

           if( isDebug( DEBUG_2 )) { 
               cout<<"DBG: Empty map ENTRY_"<<( 1<<segmentType)<<" is fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
           }
           setSubBlockEntry( workBlock.data, emptyPtr.sbid, emptyPtr.entry, 8, assignPtr );
           rc = writeDBFile( cb, workBlock.data, emptyPtr.fbo );
           if (rc != NO_ERROR){ return rc; }
           
           emptyPtr.type = EMPTY_LIST;
           emptyPtr.group = segmentType;

           setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
           blockZero->dirty = 1;//sub block is full or chain never started

       }

       uint64_t count;
       getSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
       count++;
       setSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
               

       return NO_ERROR;
   }
Esempio n. 7
0
   const int FreeMgr::assignSubblock( CommBlock &cb, DataBlock* blockZero, const int freemgrType,  IdxEmptyListEntry* assignPtr ) 
   {
       int          rc;    // return code from file ops
       DataBlock    workBlock, tempBlock;
       int          listOffset; // entry in block zero of head pointer
       IdxEmptyListEntry emptyEntry;
       IdxEmptyListEntry emptyPtr, emptyMap;
       IdxEmptyListEntry newBlock;
       uint64_t      numBlocks;
       FILE* indexFile;
               
       indexFile = cb.file.pFile;

       /**
        * Separated subblock assignment out from general segment assignment
        * Reduces the hoops to jump through
        **/
       
       numBlocks = getFileSize( indexFile )/BYTE_PER_BLOCK ;
       if( isDebug( DEBUG_3 )) { printf("DBG: Assign subblock \n"); }
       
       //find the start of the chain
       listOffset = calcPtrOffset( ENTRY_32 );
       
       getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
       if( isDebug( DEBUG_2 ))
       {
           cout<<"DBG: EM (start assign) sb fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
       }

       if (emptyPtr.type != EMPTY_LIST ){
           return ERR_FM_BAD_TYPE;
       }   
//        if (emptyPtr.fbo > numBlocks)
//        {
//            if( isDebug( DEBUG_1 )) { printf("DBG: Weirdness in assignSubblock.. emptyPtr.fbo > numBlocks\n"); }
//            return ERR_FM_BAD_FBO;
//        }

       // follow the chain to the empty entry
       rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
       if (rc != NO_ERROR)
       { 
//            printf("DBG: RC Weirdness: rc is %i", rc); 
           return rc; 
       }
           
       getSubBlockEntry( &workBlock, emptyPtr.sbid, emptyPtr.entry, 8, &emptyEntry );
       if( isDebug( DEBUG_2 )) 
       { 
           cout<<"DBG: Next avail sb fbo "<<emptyEntry.fbo<<" sbid "<<" entry "<<emptyEntry.entry<<"\n";
       }

           if (emptyEntry.fbo == 0) // then nowhere to go.. exit
           {
               //if( isDebug( DEBUG_1 )) { printf("DBG: No space in subblock list\n"); }
               if( isDebug( DEBUG_2 )) { 
                   cout<<"DBG: fbo "<<emptyEntry.fbo<<" sbid "<<emptyEntry.sbid<<" entry "<<emptyEntry.entry<<"\n";
               }
               
               //-- try and assign from BLOCK list 
//                printf("Go ask for a block\n");
               rc = assignSegment( cb, blockZero, freemgrType, ENTRY_BLK, &newBlock);

//                rc = extendFreespace( indexFile, blockZero, freemgrType );

               if (rc != NO_ERROR){ 
                   if( isDebug( DEBUG_1 )) { printf("DBG: Could not get block from block list\n"); }
                   return rc;
               }
               // got a block so now split it
               newBlock.entry = 0;
               newBlock.group = ENTRY_32;
               newBlock.type = EMPTY_PTR;
               emptyEntry = newBlock;

               //-- assign almost all sub blocks - keep last one
               int sbIdx;
               for (sbIdx=BYTE_PER_BLOCK/BYTE_PER_SUBBLOCK-1; sbIdx >0; sbIdx--)  
               {
                   if( isDebug( DEBUG_3 )) { cout<<"DBG: Working on fbo "<<newBlock.fbo<<" sbid "<<sbIdx<<"\n"; }
                   emptyEntry.sbid = sbIdx;
                   emptyEntry.type = EMPTY_PTR;
                   rc = releaseSubblock( cb, blockZero, freemgrType, &emptyEntry );
                   if (rc != NO_ERROR)
                   { 
                       printf("DBG: Error releasing sb\n"); 
                       return rc; 
                   }
               }
               emptyEntry.sbid=0;
           }

           if ((emptyEntry.type != EMPTY_LIST) && (emptyEntry.type != EMPTY_PTR))
           {
               if( isDebug( DEBUG_0 )) 
               { 
                   printf("WTF: Bad entry in in subblock list- type is %i (expected %i or %i)\n",  (unsigned int)emptyEntry.type, EMPTY_PTR, EMPTY_LIST); 
               }
               if( isDebug( DEBUG_2 )) 
               {
                   cout<<"DBG: fbo "<<emptyEntry.fbo<<" sbid "<<emptyEntry.sbid<<" entry "<<emptyEntry.entry<<"\n"; 
               }
               return ERR_FM_BAD_TYPE;
           }
           
           if (emptyEntry.type == EMPTY_PTR)
           {
               // this is what we expect normally
               emptyPtr.entry--; // only decrement if we didn't just drain a bucket 
               setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
               memcpy(assignPtr, &emptyEntry, 8);

           } else if (emptyEntry.type == EMPTY_LIST && emptyPtr.entry == 0 )
           {
               if (emptyPtr.entry >0) printf("\nWTF!! %i\n", (unsigned int) emptyPtr.entry);
                // reached end of this bucket (should release it for re-use)
               // this is not the typical case..
               if( isDebug( DEBUG_3 )) { 
                   cout<<"DBG: Drained bucket sb fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
               }
               //blank the llp
               rc = readDBFile( cb, tempBlock.data, emptyPtr.fbo );
               if (rc != NO_ERROR) { 
                   if (isDebug( DEBUG_1 )){ cout<<"DBG: File error during releaseSubblock, fbo/lbid: "<<emptyPtr.fbo<<"\n"; }
                   return rc; 
               }
               
               nullPtr(&emptyMap); // zero out the entry

               setSubBlockEntry( tempBlock.data, emptyPtr.sbid, 0, 8, &emptyMap );
               rc = writeDBFile( cb, &tempBlock, emptyPtr.fbo );
               if (rc != NO_ERROR){ return rc; }

               memcpy(assignPtr, &emptyPtr, 8);
               assignPtr->type = EMPTY_PTR;
               
               if( isDebug( DEBUG_2 )) { 
                cout<<"DBG: Change head pointer to fbo "<<emptyEntry.fbo<<" sbid "<<emptyEntry.sbid<<" entry "<<emptyEntry.entry<<"\n";
               }
               setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyEntry );
           } else 
           {
               printf("DBG: Weirdness - not list and not ptr\n"); 
           }
//            printf("DBG: Assigned sb fbo %llu sbid %u entry %u\n", assignPtr->fbo, (unsigned int)assignPtr->sbid, (unsigned int)assignPtr->entry);
           
           getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyMap );
           if(isDebug(DEBUG_3)){ 
               cout<<"DBG: EM (sb assign 1) sb fbo "<<emptyMap.fbo<<" sbid "<<emptyMap.sbid<<" entry "<<emptyMap.entry<<"\n";
           }

           blockZero->dirty = 1;
           
           uint64_t count;
           getSubBlockEntry( blockZero, 0, calcStatOffset(ENTRY_32) , 8, &count );
           count--;
           setSubBlockEntry( blockZero, 0, calcStatOffset(ENTRY_32) , 8, &count );

           
           // -- workblock may have changed on disk since it was read.. making the writeDBfile dangerous without a readDBfile first
           nullPtr(&emptyMap); // zero out the entry
           readDBFile( cb, &workBlock, emptyPtr.fbo );
           setSubBlockEntry( workBlock.data, emptyPtr.sbid, emptyPtr.entry+1, 8, &emptyMap );
           rc = writeDBFile( cb, &workBlock, emptyPtr.fbo );
           // --
//            if( isDebug( DEBUG_3 )) { printf("DBG: Assign subblock -- all done\n"); }

           return NO_ERROR;

   }
Esempio n. 8
0
   const int FreeMgr::assignSegment( CommBlock &cb, DataBlock* blockZero, const int freemgr_type, const IdxTreeGroupType segmentType, IdxEmptyListEntry* assignPtr )
   {
       int          rc;    // return code from file ops
       DataBlock    workBlock;
       int          listOffset; // entry in block zero of head pointer
       IdxEmptyListEntry emptyEntry;
       IdxEmptyListEntry emptyPtr;
       IdxEmptyListEntry emptyMap;
       uint64_t          numBlocks;
       IdxEmptyListEntry newSb;
       FILE* indexFile;
               
       indexFile = cb.file.pFile;

       if( isDebug( DEBUG_3 )) { 
           printf("DBG: Assign ENTRY_%i segment in %s\n", 1<<(unsigned int)segmentType,(freemgr_type==LIST)?"LIST":"TREE");
       }
       
/* Check all input parameters are ok   */
       if (!blockZero){
           if( isDebug( DEBUG_1 )) { printf ("DBG: Bad pointer: blockZero is zero\n"); }
           return ERR_INVALID_PARAM;
       }
       
       if (!assignPtr)
       {
           if( isDebug( DEBUG_1 )) {  printf ("DBG: Bad pointer: assignPtr is zero\n"); }
           return ERR_INVALID_PARAM;
       }
       if (freemgr_type != TREE && freemgr_type!= LIST)
       {
           if( isDebug( DEBUG_0 )) { printf ("DBG: assignSegment: Must be TREE or LIST\n");}
           return ERR_INVALID_PARAM;
       }
           
       numBlocks = getFileSize( indexFile )/BYTE_PER_BLOCK ;
       //find the start of the chain
       if (segmentType == ENTRY_32)
       {
           rc = assignSubblock( cb, blockZero, freemgr_type, assignPtr);
           if (rc != NO_ERROR)
           { 
               if( isDebug( DEBUG_1 )) { printf("DBG: Error assigning sb (rc=%i)\n", rc); }
           }
           return rc;
       }
               
       listOffset = calcPtrOffset( segmentType );
       if (freemgr_type==LIST && !(segmentType== ENTRY_4 || segmentType== ENTRY_BLK))
       {
           if( isDebug( DEBUG_1 )) { printf("DBG: Assign segment size illegal %i\n", (unsigned int)segmentType); }
           return ERR_INVALID_PARAM; // should not have got here so quit with error
       }
       
       // read Empty Map in sb0
       getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
       if( isDebug( DEBUG_2 )) { 
           cout<<"DBG: Empty map ENTRY_"<<(1<<segmentType)<<"  was fbo "<<emptyPtr.fbo<<" sbid "<<(unsigned int)emptyPtr.sbid<<" entry "<<(unsigned int)emptyPtr.entry<<"\n";
       }

/*       if (emptyPtr.fbo > numBlocks)
       {
           printf("DBG: Weirdness in assignSegment.. emptyPtr.fbo > numBlocks\n");
           return ERR_FM_BAD_FBO;
       }*/
       
       // check to see if queue has been built
       // if not then assign a container block, add LLP in entry 0 pointing to nothing
       if (emptyPtr.fbo == 0){
           if( isDebug( DEBUG_3 )) { printf("DBG: Need to add sb to chain and entries to sb\n"); }
           
           // cannot assign more space to block list from a smaller list.. need to extend the file
           if ( segmentType == ENTRY_BLK ) {
               if ( isDebug( DEBUG_1 )){ printf("Out of space in BLOCK list, quitting\n"); }
               rc = extendFreespace( cb, blockZero, freemgr_type );
               if (rc != NO_ERROR){ 
                   if (isDebug( DEBUG_3 )){ printf("DBG: Error extending file\n"); }
                   return rc; 
               }
           }
           
           rc = assignSubblock( cb, blockZero, freemgr_type, &emptyPtr);
           if (rc != NO_ERROR){ printf("DBG: Error extending chain\n"); 
               return rc; 
           }
           rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
           if (rc != NO_ERROR){ /*printf("DBG: Error reading newly allocated sb\n");*/ 
               return rc; 
           }
           // update map to point to new bucket
           setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr); 

           nullPtr(&emptyEntry);
           emptyEntry.type = EMPTY_LIST;
           emptyEntry.group = segmentType;

           setSubBlockEntry( workBlock.data, emptyPtr.sbid, 0, 8, &emptyEntry);  // store head ptr

           rc = writeDBFile( cb, workBlock.data, emptyPtr.fbo );
           if (rc != NO_ERROR){ return rc; }
           if( isDebug( DEBUG_2 )) { 
		cout<<"DBG: Added fbo "<<emptyPtr.fbo<<" sbid "<<(unsigned int)emptyPtr.sbid<<" as bucket to chain ENTRY_"<<(1<<segmentType)<<"in"<<((freemgr_type==LIST)?"LIST":"TREE")<<"\n";
           }
       }

       // follow the chain to the head container 
       rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
       if (rc != NO_ERROR)
       { 
           if( isDebug( DEBUG_1 )) { cout<<"DBG: Error reading block ("<<emptyPtr.fbo<<") during segmentAssign: rc is "<<rc; }
           return rc; 
       }
       
       getSubBlockEntry( &workBlock, emptyPtr.sbid, emptyPtr.entry, 8, &emptyEntry );
           
       if ((emptyEntry.type != EMPTY_LIST) && (emptyEntry.type != EMPTY_PTR))
       {
           if( isDebug( DEBUG_0 )) { 
               printf("WTF: Bad entry in ENTRY_%i chain - type is %i (expected %i or %i)\n",  1<<segmentType, (unsigned int)emptyEntry.type, EMPTY_PTR, EMPTY_LIST );
               printMemSubBlock( &workBlock, emptyPtr.sbid );
           }
           if( isDebug( DEBUG_2 )) { 
               cout<<"DBG: fbo "<<emptyEntry.fbo<<" sbid "<<(unsigned int)emptyEntry.sbid<<" entry "<< (unsigned int)emptyEntry.entry<<" chain ENTRY_"<<(1<<segmentType)<<"in"<<((freemgr_type==LIST)?"LIST":"TREE")<<"\n";
           }

           return ERR_FM_BAD_TYPE;
       }
       
       if ((emptyEntry.fbo == 0) && (emptyEntry.type == EMPTY_PTR))
       {
           if ( isDebug( DEBUG_0 )) {printf("DBG: Bad entry in %i list - found EMPTY_PTR but indicates block 0\n",  1<<segmentType );}
           return ERR_FM_BAD_TYPE;
       }

       if ((emptyEntry.fbo == 0) && (emptyEntry.type == EMPTY_LIST)) 
       {
           /**
            * if at the end of the rainbow, in a bucket with no entries, fill the bucket
            * Allocate a sub block and split it into parts
           **/
           
           // cannot assign more space to block list from a smaller list.. need to extend the file
           if ( segmentType == ENTRY_BLK ) {
               if ( isDebug( DEBUG_1 )){ printf("\nNeed to extend block\n");}
               if ( isDebug( DEBUG_1 )){ printf("Out of space in BLOCK list\n"); }
               rc = extendFreespace( cb, blockZero, freemgr_type );
               if (rc != NO_ERROR){ 
                   if (isDebug( DEBUG_3 )){ printf("DBG: Error extending file\n"); }
                   return rc; 
               }
               getSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
               rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );
               getSubBlockEntry( &workBlock, emptyPtr.sbid, emptyPtr.entry, 8, &emptyEntry );

           } else {
           
           rc = assignSubblock( cb, blockZero, freemgr_type, &newSb);
           if (rc != NO_ERROR){ 
//                printf("DBG: Error extending chain\n"); 
               return rc; 
           }
           if (newSb.entry != 0){
               printf("WTF: Entry should be 0 after assign from sb list, instead is %i", (unsigned int)newSb.entry);
               return ERR_FM_ASSIGN_ERR;
           }
           if (isDebug(DEBUG_2)){
               cout<<"DBG: added fbo "<<newSb.fbo<<" sbid "<<(unsigned int)newSb.sbid<<" entry "<<(unsigned) newSb.entry<<" to "<<segmentType<<" list - need to split "<<(1<<(ENTRY_32-segmentType))<<"times\n";
           }
           
           newSb.entry = 0;
           newSb.group = segmentType;
           newSb.type = EMPTY_PTR;
           emptyEntry = newSb;

           int idx, inc;
           inc = 1<<segmentType;
           for (idx=0; idx < ENTRY_PER_SUBBLOCK - inc; idx+= inc){
               if( isDebug( DEBUG_3 )) { printf ("DBG: split..%i-%i\n", idx, idx+inc-1 );}
               newSb.entry = idx;
               releaseSegment( cb, blockZero, freemgr_type, segmentType,  &newSb );
           }
           emptyEntry.entry = idx;
           if( isDebug( DEBUG_3 )) 
           { 
               printf ("DBG: split and return..%i-%i\n", idx, idx+inc-1);
           }
           if( isDebug( DEBUG_2 )) 
           { 
             cout<<"DBG: Assigned fbo "<< emptyEntry.fbo<<" sbid "<<(unsigned int)emptyEntry.sbid<<" entry "<<(unsigned int)emptyEntry.entry<<" to chain ENTRY_"<<(1<<segmentType)<<"\n";
           }
           memcpy(assignPtr, &emptyEntry, 8);
           
           uint64_t count;
           getSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
           count--;
           setSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );

           return NO_ERROR;
       }
       }
       /**
        * got here because we didn't need to populate a chain and did not fall into any traps
        * so either we are at the end of bucket or we have a valid entry
        **/
       if (emptyEntry.type == EMPTY_LIST) // reached end of this segment (should release it for re-use)
           {
               /**
                * release bucket
                **/
               if( isDebug( DEBUG_2 )) { 
                   cout<<"DBG: Need to release sb fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" from chain ENTRY_"<<(1<<segmentType)<<" in "<<((freemgr_type==LIST)?"LIST":"TREE")<<"\n";
               }
               // when we stored the ptr in the empty map, we tweaked group, must change it back
               emptyPtr.type = EMPTY_PTR;
               emptyPtr.group = ENTRY_32;
               rc = releaseSubblock( cb, blockZero, freemgr_type, &emptyPtr );
               if (rc != NO_ERROR)
               { 
                   printf("Error releasing sb\n");
                   return rc; 
               }
               emptyPtr = emptyEntry;
               rc = readDBFile( cb, workBlock.data, emptyPtr.fbo );

               if (rc != NO_ERROR){ 
                   printf("DBG: Error following chain\n");
                   return rc; 
               }
               getSubBlockEntry( &workBlock, emptyPtr.sbid, emptyPtr.entry, 8, &emptyEntry );

           } 

       if (emptyEntry.type == EMPTY_PTR)
       {
       
           emptyPtr.entry--; 
           blockZero->dirty = 1;
           setSubBlockEntry( blockZero, 0, listOffset, 8, &emptyPtr );
           
           if( isDebug( DEBUG_3 )) { 
               printf("DBG: Empty entry is now %u\n",(unsigned int)emptyPtr.entry);
           }
           if( isDebug( DEBUG_2 )) 
           { 
               cout<<"DBG: Assigned fbo "<<emptyEntry.fbo<<" sbid "<<emptyEntry.sbid<<" entry "<<emptyEntry.entry<<" from chain ENTRY_"<<(1<<segmentType)<<"\n";
               cout<<"DBG: Empty map ENTRY_"<<(1<<segmentType)<<" now fbo "<<emptyPtr.fbo<<" sbid "<<emptyPtr.sbid<<" entry "<<emptyPtr.entry<<"\n";
           }
           memcpy(assignPtr, &emptyEntry, 8);
         
           // -- workblock may have changed on disk since it was read.. making the writeDBfile dangerous without a readDBfile first
          nullPtr(&emptyMap); // zero out the entry
          readDBFile( cb, &workBlock, emptyPtr.fbo );
          setSubBlockEntry( workBlock.data, emptyPtr.sbid, emptyPtr.entry+1, 8, &emptyMap );
          rc = writeDBFile( cb, &workBlock, emptyPtr.fbo );
           // --
           
           uint64_t count;
           getSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );
           count--;
           setSubBlockEntry( blockZero, 0, calcStatOffset(segmentType) , 8, &count );

           return NO_ERROR;
       }
       
       return ERR_FM_ASSIGN_ERR;
   }
   /************************************************
    * 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
     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:
  * 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:
    * 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::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;
 }