/************************************************
  * No Change    
  * RETURN:
  *    success    - successfully created the index list header
  *    failure    - it did not create the index list header    
  ***********************************************************/ 
  const int IndexList::insertRid(const RID& newRid, int& pos)
  {
     int rc = NO_ERROR;     
     IdxRidListEntry idxRidListEntry;  
     
     if (m_curType == LIST_BLOCK_TYPE)
     {
           m_sbid = 0;
           m_entry = 0;
     }
     memset(&idxRidListEntry, 0, LIST_ENTRY_WIDTH)  ;
     
     idxRidListEntry.type  =LIST_RID_TYPE;
     idxRidListEntry.spare =0;
     //cout << "line 910:newRid->" << newRid << endl;
     
     idxRidListEntry.rid   =newRid;  
     if (m_lbid != m_hdrLbid)  
     {
        rc = readCurBlk();     
        setSubBlockEntry( m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, 
                          &idxRidListEntry );
        m_curBlock.state = BLK_WRITE;
        
     }
     else
     {
        setSubBlockEntry( m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH, 
                          &idxRidListEntry ); 
        m_hdrBlock.state = BLK_WRITE;
     }
     return rc;
  } 
 /************************************************
  * No Change    
  * RETURN:
  *    success    - successfully created the index list header
  *    failure    - it did not create the index list header    
  ***********************************************************/  
  const int  IndexList::updateLastPtr(const int lastCount)  
  { 
       int rc;
       if (m_curBlock.state == BLK_INIT)
            readCurBlk();    
       if (m_useNarray)
       {
          rc = setCurBlkNextPtr(m_nextLbid, lastCount);
          rc = writeCurBlk();            
       }
       else
       {
          ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->fbo  = m_nextLbid;
          ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->sbid = 0;
          ((IdxEmptyListEntry*)&m_lastIdxRidListPtr)->entry= 0;
          m_lastIdxRidListPtr.type= LIST_BLOCK_TYPE;
          m_lastIdxRidListPtr.spare=0x0;
          m_lastIdxRidListPtr.count = lastCount; 
                       
          setSubBlockEntry( m_curBlock.data, m_sbid, 
                            LIST_BLOCK_LLP_POS, LIST_ENTRY_WIDTH , 
                            &m_lastIdxRidListPtr );
          m_curBlock.state = BLK_WRITE;
          rc = writeCurBlk();
       } 
       return rc;  
  }            
Beispiel #3
0
const int DbFileOp::writeSubBlockEntry( CommBlock& cb, DataBlock* block, 
                                        const uint64_t lbid, const int sbid, 
                                        const int entryNo, const int width, 
                                        void* pStruct )
{
    setSubBlockEntry( block->data, sbid, entryNo, width, pStruct );
    block->dirty = false;

    return writeDBFile( cb, block->data, lbid );
}
   /****************************************************************
    * DESCRIPTION:
    * Private Function for setting the last Fbo on header
    * 
    ***************************************************************/    
    const int IndexList::setLastFboPtr(uint64_t& lbid, int& sbid, 
                                       IdxRidListPtr& lastFboListPtr)
    {
      int rc = NO_ERROR;
      CommBlock cb;
      DataBlock dataBlock;
      IdxRidListPtr oldFboListPtr;
      
      cb.file.oid = m_oid;
      cb.file.pFile = m_pFile;

      if ((m_hdrBlock.lbid == lbid) && (m_hdrBlock.state>= BLK_READ))
      {
          setSubBlockEntry(m_hdrBlock.data, sbid, LIST_LAST_LBID_POS, 
                           LIST_ENTRY_WIDTH, &lastFboListPtr);
          m_hdrBlock.state = BLK_WRITE;  
      }
      else  if ((m_curBlock.lbid == lbid) && (m_curBlock.state>= BLK_READ))
      {
          setSubBlockEntry(m_curBlock.data, sbid, LIST_LAST_LBID_POS, 
                           LIST_ENTRY_WIDTH, &lastFboListPtr);
          m_curBlock.state = BLK_WRITE;
      }
      else
      {
          memset( dataBlock.data, 0, sizeof(dataBlock.data));
          rc = readSubBlockEntry(cb, &dataBlock, lbid, sbid, LIST_LAST_LBID_POS,
                                 LIST_ENTRY_WIDTH, &oldFboListPtr);
          if (((IdxEmptyListEntry*)&oldFboListPtr)->fbo !=m_lastLbid)
          {
            setSubBlockEntry(dataBlock.data, sbid, LIST_LAST_LBID_POS,
                                 LIST_ENTRY_WIDTH, &lastFboListPtr);
            rc = writeDBFile(cb, dataBlock.data, lbid);
          }
          else
           return NO_ERROR;
      }
      return rc;
    }    
 /****************************************************************************
  * RETURN:
  *    success    - successfully created the index list header
  *    failure    - it did not create the index list header    
  ***************************************************************************/  
  const int IndexList::updateHdrCount()
  {    
     int rc=NO_ERROR; 
     
     if (m_hdrBlock.state == BLK_INIT)
      return ERR_IDX_LIST_UPDATE_HDR_COUNT;
     m_curIdxRidListHdr.idxRidListSize.size++; 
     setSubBlockEntry( m_hdrBlock.data, m_hdrSbid, 
                       m_hdrEntry, LIST_HDR_SIZE, 
                       &m_curIdxRidListHdr );
     m_hdrBlock.state = BLK_WRITE;
   
     return rc;
  }
 /************************************************
  * No Change    
  * RETURN:
  *    success    - successfully created the index list header
  *    failure    - it did not create the index list header    
  ***********************************************************/  
  const int IndexList::updateCurCount(int frequency)
  {
       int rc = NO_ERROR;
       int pos = 0;
       
       if (m_curType == LIST_SUBBLOCK_TYPE)
           pos = LIST_SUB_LLP_POS;
       else if (m_curType == LIST_BLOCK_TYPE)
       {
           pos = LIST_BLOCK_LLP_POS;
           m_sbid = 0;
           m_entry = 0;
       }
       if ((m_useNarray) && (m_curType == LIST_BLOCK_TYPE))
           rc = updateCurCountInArray();
       else
       {
           rc = getNextInfoFromBlk(m_lastIdxRidListPtr);
           for (int i=0; i< frequency; i++)
             m_lastIdxRidListPtr.count++;
           
           if  (m_lbid==m_hdrLbid)
           {   
              setSubBlockEntry( m_hdrBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH,
                                &m_lastIdxRidListPtr );
              m_hdrBlock.state  = BLK_WRITE;
           }
           else
           {
              setSubBlockEntry(m_curBlock.data, m_sbid, pos, LIST_ENTRY_WIDTH,
                               &m_lastIdxRidListPtr );
              m_curBlock.state =BLK_WRITE;                          
           };
       }
       return rc;
  }  
   /****************************************************************
    * DESCRIPTION:
    * Private Function for setting the last Fbo on header
    * 
    ***************************************************************/    
    const int  IndexList::setNextInfoFromBlk( IdxRidListPtr& idxRidListPtr)
    {
      int rc = NO_ERROR;
      CommBlock cb;

      cb.file.oid = m_oid;
      cb.file.pFile = m_pFile;
      int pos = 0;
     
      if (m_curType == LIST_SUBBLOCK_TYPE)
          pos = LIST_SUB_LLP_POS;
      else if (m_curType == LIST_BLOCK_TYPE)
          pos = LIST_BLOCK_LLP_POS;
          
      if (m_lbid==m_hdrLbid)
      {//when sub == hdr
          setSubBlockEntry( m_hdrBlock.data, m_sbid, 
                            pos, LIST_ENTRY_WIDTH, &idxRidListPtr ); 
          m_hdrBlock.state =BLK_WRITE;                                                   
      }
      else
      {
          readCurBlk();
          if (m_lbid == m_curBlock.lbid)
          {
               setSubBlockEntry( m_curBlock.data, m_sbid, 
                                 pos, LIST_ENTRY_WIDTH, 
                                 &idxRidListPtr );
               rc = writeDBFile(cb, m_curBlock.data, m_lbid ); 
               m_curBlock.state =BLK_READ;
          }
          else
               return ERR_IDX_LIST_WRONG_LBID_WRITE;
       }                
       return rc;
    }  
 /****************************************************************
  * DESCRIPTION:
  * Private Function for getting a segment for LIST
  * 
  ***************************************************************/         
  const int  IndexList::getSegment( FILE* pFile, 
                                    const IdxTreeGroupType segmentType, 
                                    IdxEmptyListEntry* assignPtr )
  {
    int rc = ERR_IDX_LIST_GET_SEGMT;
    CommBlock cb;
    uint64_t lbid0; 
    
    m_pFile = pFile;
    cb.file.oid   = m_oid;
    cb.file.pFile = m_pFile;
    /*
    DataBlock tmpBlock;
    IdxEmptyListEntry tmpEntry;
    memset(tmpBlock.data,0, 8192);
    rc = readSubBlockEntry( pFile, &tmpBlock, 1492798, 31, 31, 8, &tmpEntry );
    cout << "common273->tmpEntry.fbo=" << tmpEntry.fbo << " tmpEntry.sbid=" 
         << tmpEntry.sbid <<  " tmpEntry.entry=" << tmpEntry.entry << endl;
     */
    if (m_hdrLbid != INVALID_LBID)
    {
       setSubBlockEntry(m_hdrBlock.data, m_hdrSbid, 
                        m_hdrEntry, LIST_HDR_SIZE, 
                        &m_curIdxRidListHdr );
       m_hdrBlock.state = BLK_WRITE;
    }
    //write everything out before calling free space manager
    rc = updateIndexListWrite();     
    rc = resetBlkZero(lbid0);
    rc = m_freemgr.assignSegment( cb, &m_blockZero, LIST, segmentType,  
                                  assignPtr);
    if (rc!= NO_ERROR)
       return rc;
    rc = writeBlkZero(lbid0);
    if (segmentType==ENTRY_4)
    {
       m_hdrLbid = assignPtr->fbo;
       m_hdrSbid = assignPtr->sbid;
       m_hdrEntry = assignPtr->entry;
       return rc;
    }
    //get the header back for sure
    //recover other blocks as it goes
    rc = initBlksGetHdrBlk();
    return rc;   
  } 
Beispiel #9
0
   /**
    * 
    * blank out all stats, set types and groups of null pointers in block zero
    */
   const int FreeMgr::initBlockzero( DataBlock* blockZero)
   {
       IdxEmptyListEntry Pointer; 
       uint64_t blankVal = 0;
       
       memset(blockZero->data, 0, sizeof(blockZero->data));
        
       nullPtr( &Pointer );
       Pointer.type = EMPTY_LIST;

       Pointer.group = ENTRY_BLK;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_BLK), 8, &Pointer); 
       
       Pointer.group = ENTRY_32;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_32), 8, &Pointer); 
            
       Pointer.group = ENTRY_16;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_16), 8, &Pointer); 
            
       Pointer.group = ENTRY_8;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_8), 8, &Pointer); 
            
       Pointer.group = ENTRY_4;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_4), 8, &Pointer); 
            
       Pointer.group = ENTRY_2;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_2), 8, &Pointer); 
            
       Pointer.group = ENTRY_1;
       setSubBlockEntry( blockZero->data, 0, calcPtrOffset(ENTRY_1+ENTRY_1), 8, &Pointer); 

       //all stat locations are contiguous and after the pointers in block zero
       
       for (int idx = calcStatOffset( ENTRY_1 ); idx < calcStatOffset( ENTRY_32 )+1; idx++)
       {
           setSubBlockEntry( blockZero->data, 0, idx, 8, &blankVal); 
       }

           
       return NO_ERROR;
   }
Beispiel #10
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;
   }
Beispiel #11
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;
   }
Beispiel #12
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;

   }
Beispiel #13
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;
   }
Beispiel #14
0
   const int FreeMgr::init( CommBlock &cb, int freemgrType) 
   {
     
       /**
        * Tree has 6 chains, (1,2,4,8,16,32 entries) starting at entry 1 in sb0 of block0
        * List has 3 chains (4,32,1024 entries) starting at first entry of file
        *
        * Starting at Block 1, add each subblock after sb0 to the free list in sb0
        * then go back and build the smaller chains on demand. This way we make sure all SBs
		* are in a chain somewhere.. but this is not best behaviour when allocating blocks
        *
       **/

        int         rc;    // return code from file ops
        DataBlock   blockZero;
        DataBlock   workBlock;
        int         sbIdx;
        uint64_t     blkIdx;
        IdxEmptyListEntry emptyEntry;  // populate the chains with pointer to empty entries
        IdxEmptyListEntry nextPointer; // pointer at end of sub-block of pointers to emptyEntries
        uint64_t     numBlocks; 
        FILE*       indexFile;

        indexFile = cb.file.pFile;

        if (!indexFile) // Make sure that we have non-null filehandle
        {
//             printf("DBG: File handle is null\n");
            return ERR_INVALID_PARAM;
        }
        if (freemgrType!=TREE && freemgrType!=LIST){
//             printf("DBG: Bad type in freeMgr Init\n");
            return ERR_INVALID_PARAM;
        }

        numBlocks = getFileSize( indexFile )/BYTE_PER_BLOCK ;
        
//         printf ("DBG: File size: %lu Total blocks: %llu (%u)\n", getFileSize( indexFile ), numBlocks, BYTE_PER_BLOCK);
//         printf ("DBG: Adding sub-blocks: %llu \n",  numBlocks * 32);

		// Clear the list of pointers in sb0
        initBlockzero( &blockZero );

        // initialize the non varying fields
        nullPtr(&emptyEntry);
        emptyEntry.type = EMPTY_PTR;
        emptyEntry.group = ENTRY_32;

        // nextPointer identifies next sub-block with empty pointers
        // initially there is no next sub-block so zero it out
        nullPtr(&nextPointer);
        nextPointer.type = EMPTY_LIST;
        nextPointer.group = ENTRY_32;
        nextPointer.entry = ENTRY_PER_SUBBLOCK-1;  // last entry on the list.. think of the list as a stack

        if (initType == 0){
            if( isDebug( DEBUG_3 )) { printf("\nOld style init\n"); }
            
        for ( blkIdx = numBlocks-1; blkIdx > 0; blkIdx-- )
        {
            emptyEntry.fbo  = blkIdx;// map fbo to lbid before storage
//             emptyEntry.fbo  = mapLBID( cb, blkIdx, rc );// map fbo to lbid before storage
//             if (rc != NO_ERROR ){ printf("DBG: Error resolving LBID for OID: %u FBO: %llu\n", cb.file.oid, blkIdx-1 ); return rc; }

            if( isDebug( DEBUG_3 )) { cout<<"DBG: Working on block "<<emptyEntry.fbo<<"\n"; }
            memset(workBlock.data, 0, sizeof(workBlock.data));

            /** 
             * each block after zeroth block uses sb0 to store entry list
             * first entry (#0) is the llp to additional sblks with entries
             * entries 1-31 are pointers
             **/
                			
			// sb0 is used for initial map, so start at sb1
            for (sbIdx=1; sbIdx < BYTE_PER_BLOCK/BYTE_PER_SUBBLOCK; sbIdx++)  
            {
                if( isDebug( DEBUG_3 )) { printf("DBG: Working on subblock %u\n", sbIdx); }
                emptyEntry.sbid = sbIdx;
                emptyEntry.type = EMPTY_PTR;
				// store pointer in sb0 -  replace this with a releaseSubblock call
                setSubBlockEntry( workBlock.data, 0, sbIdx, 8, &emptyEntry);  
                if( isDebug( DEBUG_2 )) {
                    cout<<"DBG: Init sb fbo "<<emptyEntry.fbo<<" sbid "<<emptyEntry.sbid<<" entry "<<emptyEntry.entry<<"\n";
                }
            }
			// having stored all pointers, store linkptr
            setSubBlockEntry( workBlock.data, 0, 0, 8, &nextPointer);  
//             nextPointer.fbo = mapLBID( cb, blkIdx, rc ); // remember this block ID
            nextPointer.fbo = blkIdx; // remember this block ID
//             if (rc != NO_ERROR ){ printf("DBG: Error resolving LBID for OID: %u FBO: %llu\n", cb.file.oid, blkIdx-1 ); return rc; }

            rc = writeDBFile( cb, workBlock.data, emptyEntry.fbo );
            if (rc != NO_ERROR){ return rc; }

        }

		// chain for segments of sub block size
        setSubBlockEntry( blockZero.data, 0, calcPtrOffset(ENTRY_32), 8, &nextPointer); 
        
        /**
         * the next algorithm uses the release sub-block method and does not layout the map on particular boundaries.
         **/
        
        } else if (initType  == 1) { // new style - use release 
            if( isDebug( DEBUG_3 )) { printf("\nNew style\n"); }
            
            for ( blkIdx = numBlocks-1; blkIdx > 0; blkIdx-- )
            {
                
                emptyEntry.fbo  = blkIdx;// map fbo to lbid before storage

//                 emptyEntry.fbo  = mapLBID( cb, blkIdx, rc );// map fbo to lbid before storage
//                 if (rc != NO_ERROR ){ printf("DBG: Error resolving LBID for OID: %u FBO: %llu\n", cb.file.oid, blkIdx-1 ); return rc; }

                if( isDebug( DEBUG_3 )) { cout<<"DBG: Working on block "<<emptyEntry.fbo<<"\n"; }
                memset(workBlock.data, 0, sizeof(workBlock.data));
            
                for (sbIdx=BYTE_PER_BLOCK/BYTE_PER_SUBBLOCK-1; sbIdx >-1; sbIdx--)  
                {
                    if( isDebug( DEBUG_3 )) { printf("DBG: Working on subblock %u\n", sbIdx); }
                    emptyEntry.sbid = sbIdx;
                    emptyEntry.type = EMPTY_PTR;
                // store pointer in sb0 -  replace this with a releaseSubblock call
                rc = releaseSubblock( cb, &blockZero, freemgrType, &emptyEntry );
                if (rc != NO_ERROR){ printf("Error releasing sb\n"); return rc; }
                }
            }

            /**
             * the next algorithm uses the release sub-block method and does not layout the map on particular boundaries.
             * It also allows pieces to be allocated
            **/
        

        } else  if (initType  == 2){
                /** The following calls to init accept FBO not LBID..
                 * This makes it easier to work on a range of blocks
                 **/
                // use the first block of the new range for sub-block chain
                // and the rest for block chain
            rc = init( cb, &blockZero,  freemgrType,  ENTRY_32,  1, 50);
            if ( rc != NO_ERROR ) { return rc; }
            rc = init( cb, &blockZero,  freemgrType,  ENTRY_BLK, 51, numBlocks-52);
            if ( rc != NO_ERROR ) { return rc; }

        } 
        // now write sb0 back to disk
        if ( isDebug( DEBUG_2 ))
        { 
            printf("Writing SB0 back to disk\n"); 
            printMemSubBlock( &blockZero, 0 );
        }
        
        uint64_t lbid = mapLBID( cb, 0, rc);
        if (rc != NO_ERROR ){ return rc; }

        rc = writeDBFile( cb, blockZero.data, lbid );
        if (rc != NO_ERROR)
        { 
            return rc; 
        }
       
        return NO_ERROR;

   }
 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:
   * RETURN:
   *    success    - successfully created the index list header
   *    failure    - it did not create the index list header    
   ***********************************************************/
    const int IndexList::updateHdrSub(const RID& newRid, const uint64_t &key)
    {             
       int rc = ERR_IDX_LIST_INVALID_UP_HDR;
       CommBlock cb;
       cb.file.oid = m_oid;     
       cb.file.pFile = m_pFile;
       
       if (m_curIdxRidListHdr.firstIdxRidListEntry.type
                      == (int)LIST_NOT_USED_TYPE)
       {
                m_curIdxRidListHdr.firstIdxRidListEntry.type =LIST_RID_TYPE;
                m_curIdxRidListHdr.firstIdxRidListEntry.rid = newRid;
                m_curIdxRidListHdr.idxRidListSize.size++;
                if (m_hdrBlock.lbid == m_hdrLbid)
                    rc = writeSubBlockEntry( cb, &m_hdrBlock,  m_hdrLbid, 
                                             m_hdrSbid, m_hdrEntry,
                                             LIST_HDR_SIZE,
                                             &m_curIdxRidListHdr );
                else
                    return ERR_IDX_LIST_WRONG_LBID_WRITE;
                m_hdrBlock.state = BLK_READ;
                return rc;       
        };//Done      
        //Check Header last entry's type and go to different next step 
        m_nextType = m_curIdxRidListHdr.nextIdxRidListPtr.type;   
        switch (m_nextType) 
        {
             case LIST_NOT_USED_TYPE://Header is not full
                //insert row id into header last enty 
                  m_curIdxRidListHdr.nextIdxRidListPtr.type=LIST_RID_TYPE;
                  m_curIdxRidListHdr.nextIdxRidListPtr.llp= newRid; 
                  m_curIdxRidListHdr.idxRidListSize.size++; 
                  if (m_hdrBlock.lbid == m_hdrLbid)                  
                   rc =writeSubBlockEntry( cb, &m_hdrBlock,m_hdrLbid, 
                                           m_hdrSbid, m_hdrEntry,                                            
                                           LIST_HDR_SIZE, &m_curIdxRidListHdr);
                  else 
                   return ERR_IDX_LIST_WRONG_LBID_WRITE;
                   
                  m_hdrBlock.state = BLK_READ;
                  m_lastLbid = INVALID_LBID;
                  break;
             case LIST_RID_TYPE://Header is full, need a new sub-block  	      
                  RID oldRid ;
                  IdxEmptyListEntry newIdxListEntry;
                  oldRid = m_curIdxRidListHdr.nextIdxRidListPtr.llp;    	         	      
                  //need a sub block                   
                  m_segType = LIST_SUBBLOCK_TYPE;
                  
                  rc= moveRidsToNewSub(m_pFile, oldRid,newRid,&newIdxListEntry);
                  if (rc!=NO_ERROR)
                    return rc;
                  //update header count twice
                  m_curIdxRidListHdr.nextIdxRidListPtr.type = m_segType;
                  m_curIdxRidListHdr.nextIdxRidListPtr.llp = 
                                   ((IdxRidListHdrPtr*)&newIdxListEntry)->llp;
                  m_curIdxRidListHdr.nextIdxRidListPtr.spare= 0;
                  m_curIdxRidListHdr.idxRidListSize.size++; 
                  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;
                  m_hdrBlock.state = BLK_READ;        
                  m_lastLbid = INVALID_LBID;
                  if (m_curBlock.state==BLK_WRITE)
                  {
                    rc = writeDBFile( cb, m_curBlock.data, m_lbid );
                    m_curBlock.state = BLK_READ;
                  }
                   
                  break;
             case LIST_SUBBLOCK_TYPE: //first one is a sub block
             		     
                    m_lbid= ((IdxEmptyListEntry*)
                              &(m_curIdxRidListHdr.nextIdxRidListPtr))->fbo;
                    m_sbid=((IdxEmptyListEntry*)
                              &(m_curIdxRidListHdr.nextIdxRidListPtr))->sbid;
                    m_entry=((IdxEmptyListEntry*)
                              &(m_curIdxRidListHdr.nextIdxRidListPtr))->entry;     
                    m_curType = m_nextType;  
                    m_segType = LIST_BLOCK_TYPE;        
                    rc =readCurBlk();      
                    rc = getNextInfoFromBlk(m_lastIdxRidListPtr);  
                    rc = addRidInSub(newRid, m_lastIdxRidListPtr);
                    break;                              	      
             default:
                    rc=ERR_IDX_LIST_INVALID_UP_HDR;
                    break;	
         }	//end of switch
      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::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;     
 }