/****************************************************************
    * DESCRIPTION:
    * Private Function for setting the last Fbo on header
    * 
    ***************************************************************/    
    const int  IndexList::readCurBlk()
    {
         int rc = NO_ERROR;
         CommBlock cb;
         
         if (m_lbid == m_hdrLbid)  
           return NO_ERROR;
                   
         cb.file.oid = m_oid;     
         cb.file.pFile = m_pFile;
         
         if ((m_curBlock.lbid == m_lbid) && (m_curBlock.state != BLK_INIT))
           return NO_ERROR;
           
         if (m_curBlock.state == BLK_WRITE)
           rc = writeCurBlk();

         if ((m_curBlock.state == BLK_INIT) || (m_curBlock.lbid != m_lbid))
         {
            memset(m_curBlock.data, 0, sizeof(m_curBlock.data ) );
            rc = readDBFile(cb, m_curBlock.data, m_lbid);
            if (rc != NO_ERROR)
              return rc; 
            m_curBlock.dirty = true;
            m_curBlock.lbid = m_lbid;
            m_curBlock.state = BLK_READ; 
         }
         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. 3
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. 4
0
int DbFileOp::readDBFile( IDBDataFile* pFile,
                          DataBlock* block,
                          const uint64_t lbid,
                          const bool isFbo )
{
     block->dirty = false;
     block->no = lbid;

     Stats::incIoBlockRead();

     return readDBFile( pFile, block->data, lbid, isFbo );
}
Esempio n. 5
0
int DbFileOp::readDBFile( CommBlock& cb,
                          unsigned char* readBuf,
                          const uint64_t lbid ) 
{ 
    CacheKey key;

    if( Cache::getUseCache() )
    {
        if( Cache::cacheKeyExist( cb.file.oid, lbid ) ) {
            key = Cache::getCacheKey( cb.file.oid, lbid );
            RETURN_ON_ERROR( Cache::loadCacheBlock( key, readBuf ) );
            return NO_ERROR;
        }
    }

    RETURN_ON_ERROR( readDBFile( cb.file.pFile, readBuf, lbid ) ); 
    if( Cache::getUseCache() )
    {
        int  fbo = lbid;

        uint16_t  dbRoot;
        uint32_t  partition;
        uint16_t  segment;
        RETURN_ON_ERROR( BRMWrapper::getInstance()->getFboOffset(
            lbid, dbRoot, partition, segment, fbo ) );
      
        if( Cache::getListSize( FREE_LIST ) == 0 ) {
            if ( isDebug( DEBUG_1 ) ) {
                printf( "\nBefore flushing cache " );
                Cache::printCacheList();
            }

            // flush cache to give up more space
            RETURN_ON_ERROR( flushCache() );
            if ( isDebug( DEBUG_1 ) ) {
                printf( "\nAfter flushing cache " );
                Cache::printCacheList();
            }
        }
        RETURN_ON_ERROR( Cache::insertLRUList( cb, lbid, fbo, readBuf ) );
    }

    return NO_ERROR;
}
   /****************************************************************
    * DESCRIPTION:
    * Private Function for getting block zero
    * either it is 0 or get it from BRM    
    * 
    ***************************************************************/         
    const int  IndexList::resetBlkZero(uint64_t& lbid0)
    {
        int rc = NO_ERROR;
        CommBlock cb;
        cb.file.oid   = m_oid;
        cb.file.pFile = m_pFile;
        
        memset( m_blockZero.data, 0, sizeof(m_blockZero.data));        
        m_blockZero.dirty = false;
        m_blockZero.state = BLK_INIT;
        
#ifdef BROKEN_BY_MULTIPLE_FILES_PER_OID
        rc = BRMWrapper::getInstance()->getBrmInfo( m_oid, 0, lbid0 );
#endif
        if (rc != NO_ERROR)
           return rc;
        rc = readDBFile( cb, m_blockZero.data, lbid0 );
        m_blockZero.lbid = lbid0; 
        m_blockZero.state = BLK_READ;
        
        return rc;
    } 
Esempio n. 7
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. 8
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. 9
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. 10
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;
   }
Esempio n. 11
0
int ColumnOpCompress0::readBlock(IDBDataFile* pFile, unsigned char* readBuf, const uint64_t fbo)
{
   return readDBFile(pFile, readBuf, fbo, true);
}
 /************************************************
  * 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;     
 }