Exemple #1
0
   // PD_TRACE_DECLARE_FUNCTION ( SDB__DMSROUNIT_INSRCD, "_dmsReorgUnit::insertRecord" )
   INT32 _dmsReorgUnit::insertRecord ( BSONObj &obj,
                                       _pmdEDUCB *cb, UINT32 attributes )
   {
      INT32 rc                     = SDB_OK ;
      PD_TRACE_ENTRY ( SDB__DMSROUNIT_INSRCD );
      UINT32 dmsrecordSize         = 0 ;
      ossValuePtr recordPtr        = 0 ;
      ossValuePtr prevPtr          = 0 ;
      dmsOffset offset             = DMS_INVALID_OFFSET ;
      dmsOffset recordOffset       = DMS_INVALID_OFFSET ;
      dmsExtent *currentExtent     = (dmsExtent*)_pCurrentExtent ;
      BOOLEAN isCompressed         = FALSE ;
      const CHAR *compressedData   = NULL ;
      INT32 compressedDataSize     = 0 ;

      if ( obj.objsize() + DMS_RECORD_METADATA_SZ >
           DMS_RECORD_MAX_SZ )
      {
         rc = SDB_CORRUPTED_RECORD ;
         goto error ;
      }

      if ( OSS_BIT_TEST ( attributes, DMS_MB_ATTR_COMPRESSED ) )
      {
         rc = dmsCompress ( cb, obj, NULL, 0, &compressedData,
                            &compressedDataSize ) ;
         PD_RC_CHECK ( rc, PDERROR,
                       "Failed to compress record, rc = %d: %s",
                       rc, obj.toString().c_str() ) ;
         dmsrecordSize = compressedDataSize + sizeof(INT32) ;
         if ( dmsrecordSize > (UINT32)(obj.objsize()) )
         {
            dmsrecordSize = obj.objsize() ;
         }
         else
         {
            isCompressed = TRUE ;
         }
      }
      else
      {
         dmsrecordSize = obj.objsize() ;
      }
      dmsrecordSize += DMS_RECORD_METADATA_SZ ;
      dmsrecordSize *= DMS_RECORD_OVERFLOW_RATIO ;
      dmsrecordSize = OSS_MIN(DMS_RECORD_MAX_SZ, ossAlignX(dmsrecordSize,4)) ;
   alloc:
      if ( !_pCurrentExtent )
      {
         rc = _allocateExtent ( dmsrecordSize <<
                                DMS_RECORDS_PER_EXTENT_SQUARE ) ;
         if ( rc )
         {
            PD_LOG ( PDERROR, "Failed to allocate new extent in reorg file, "
                     "rc = %d", rc ) ;
            goto error ;
         }
         currentExtent = (dmsExtent*)_pCurrentExtent ;
      }
      if ( dmsrecordSize > (UINT32)currentExtent->_freeSpace )
      {
         rc = _flushExtent () ;
         if ( rc )
         {
            PD_LOG ( PDERROR, "Failed to flush extent, rc = %d", rc ) ;
            goto error ;
         }
         goto alloc ;
      }
      recordOffset = _currentExtentSize - currentExtent->_freeSpace ;
      recordPtr = ((ossValuePtr)currentExtent) + recordOffset ;
      if ( currentExtent->_freeSpace - (INT32)dmsrecordSize <
           (INT32)DMS_MIN_RECORD_SZ &&
           currentExtent->_freeSpace <= (INT32)DMS_RECORD_MAX_SZ )
      {
         dmsrecordSize = (UINT32)currentExtent->_freeSpace ;
      }

      DMS_RECORD_SETSTATE ( recordPtr, DMS_RECORD_FLAG_NORMAL ) ;
      DMS_RECORD_RESETATTR ( recordPtr ) ;
      DMS_RECORD_SETMYOFFSET ( recordPtr, recordOffset ) ;
      DMS_RECORD_SETSIZE ( recordPtr, dmsrecordSize ) ;
      if ( isCompressed )
      {
         DMS_RECORD_SETATTR ( recordPtr, DMS_RECORD_FLAG_COMPRESSED ) ;
         DMS_RECORD_SETDATA ( recordPtr, compressedData, compressedDataSize ) ;
      }
      else
      {
         DMS_RECORD_SETDATA ( recordPtr, obj.objdata(), obj.objsize() ) ;
      }
      DMS_RECORD_SETNEXTOFFSET ( recordPtr, DMS_INVALID_OFFSET ) ;
      DMS_RECORD_SETPREVOFFSET ( recordPtr, DMS_INVALID_OFFSET ) ;
      currentExtent->_recCount ++ ;
      currentExtent->_freeSpace -= dmsrecordSize ;
      offset = currentExtent->_lastRecordOffset ;
      if ( DMS_INVALID_OFFSET != offset )
      {
         prevPtr = ((ossValuePtr)currentExtent) + offset ;
         DMS_RECORD_SETNEXTOFFSET ( prevPtr, recordOffset ) ;
         DMS_RECORD_SETPREVOFFSET ( recordPtr, offset ) ;
      }
      currentExtent->_lastRecordOffset = recordOffset ;
      offset = currentExtent->_firstRecordOffset ;
      if ( DMS_INVALID_OFFSET == offset )
      {
         currentExtent->_firstRecordOffset = recordOffset ;
      }
   done :
      PD_TRACE_EXITRC ( SDB__DMSROUNIT_INSRCD, rc );
      return rc ;
   error :
      goto done ;
   }
   // PD_TRACE_DECLARE_FUNCTION ( SDB__DMS_LOBDIRECTOUTBUF_DOIT, "_dmsLobDirectOutBuffer::doit" )
   INT32 _dmsLobDirectOutBuffer::doit( const tuple **pTuple )
   {
      INT32 rc = SDB_OK ;
      PD_TRACE_ENTRY( SDB__DMS_LOBDIRECTOUTBUF_DOIT ) ;

      rc = prepare() ;
      if ( rc )
      {
         goto error ;
      }

      if ( _aligned )
      {
         INT32 offset1 = -1 ;
         INT32 offset2 = -1 ;
         UINT32 readLen = 0 ;
         INT64 fOffset = 0 ;

         if ( _t.offset != _usrOffset )
         {
            offset1 = _t.offset ;
         }
         if ( _t.size != _usrSize )
         {
            offset2 = _t.offset + _t.size - OSS_FILE_DIRECT_IO_ALIGNMENT ;
         }

         if ( offset1 >= 0 && offset2 >= 0 &&
              offset2 - offset1 <= DMS_SEQ_READ_FAN_THRESHOLD &&
              _pageID >= 0 &&
              0 == ( _newestMask & UTIL_WRITE_NEWEST_BOTH ) )
         {
            UINT32 len = OSS_FILE_DIRECT_IO_ALIGNMENT + offset2 - offset1 ;
            fOffset = _pFile->pageID2Offset( _pageID, (UINT32)offset1 ) ;
            rc = _pFile->readRaw( fOffset, len, _t.buf, readLen, _cb, TRUE ) ;
            if ( rc )
            {
               PD_LOG( PDERROR, "Read date[PageID:%u, Offset:%u, Len:%u] "
                       "failed, rc: %d", _pageID, offset1, len, rc ) ;
               goto error ;
            }
            offset1 = -1 ;
            offset2 = -1 ;
         }

         if ( offset1 >= 0 )
         {
            if ( OSS_BIT_TEST( _newestMask, UTIL_WRITE_NEWEST_HEADER ) )
            {
               ossMemset( _t.buf, 0, _usrOffset - offset1 ) ;
            }
            else
            {
               fOffset = _pFile->pageID2Offset( _pageID, (UINT32)offset1 ) ;
               rc = _pFile->readRaw( fOffset, OSS_FILE_DIRECT_IO_ALIGNMENT,
                                     _t.buf, readLen, _cb, TRUE ) ;
               if ( rc )
               {
                  PD_LOG( PDERROR, "Read date[PageID:%u, Offset:%u, Len:%u] "
                          "failed, rc: %d", _pageID, offset1,
                          OSS_FILE_DIRECT_IO_ALIGNMENT, rc ) ;
                  goto error ;
               }
            }
         }

         if ( offset2 >= 0 )
         {
            if ( OSS_BIT_TEST( _newestMask, UTIL_WRITE_NEWEST_TAIL ) )
            {
               ossMemset( _t.buf + offset2 - _t.offset,
                          0,
                          _t.size - ( _usrSize + _usrOffset - _t.offset ) ) ;
            }
            else
            {
               fOffset = _pFile->pageID2Offset( _pageID, (UINT32)offset2 ) ;
               rc = _pFile->readRaw( fOffset, OSS_FILE_DIRECT_IO_ALIGNMENT,
                                     _t.buf + offset2 - _t.offset, readLen,
                                     _cb, TRUE ) ;
               if ( rc )
               {
                  PD_LOG( PDERROR, "Read date[PageID:%u, Offset:%u, Len:%u] "
                          "failed, rc: %d", _pageID, offset2,
                          OSS_FILE_DIRECT_IO_ALIGNMENT, rc ) ;
                  goto error ;
               }
            }
         }

         ossMemcpy( _t.buf + _usrOffset - _t.offset,
                    _usrBuf, _usrSize ) ;
      }

      if ( pTuple )
      {
         *pTuple = &_t ;
      }

   done:
      PD_TRACE_EXITRC( SDB__DMS_LOBDIRECTOUTBUF_DOIT, rc ) ;
      return rc ;
   error:
      goto done ;
   }