/**************************************************************************** Desc: ****************************************************************************/ RCODE TestBase::openTestState( const char * pszDibName) { RCODE rc = FERR_OK; CREATE_OPTS createOpts; if( RC_BAD( rc = gv_FlmSysData.pFileSystem->doesFileExist( pszDibName))) { // Create the database f_memset( &createOpts, 0, sizeof( CREATE_OPTS)); if( RC_BAD( rc = FlmDbCreate( pszDibName, NULL, NULL, NULL, NULL, &createOpts, &m_hDb))) { goto Exit; } } else { // Open the existing database if( RC_BAD( rc = FlmDbOpen( pszDibName, NULL, NULL, 0, NULL, &m_hDb))) { goto Exit; } } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ void FlagSet::init( FLMBYTE ** ppucElemArray, FLMUINT uiNumElems) { reset(); if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * uiNumElems, &m_ppucElemArray))) { flmAssert( 0); } if( RC_BAD( f_alloc( sizeof( FLMBOOL) * uiNumElems, &m_pbFlagArray))) { flmAssert( 0); } f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * uiNumElems); for( FLMUINT uiLoop = 0; uiLoop < uiNumElems; uiLoop++) { if( RC_BAD( f_alloc( f_strlen( (char *)ppucElemArray[ uiLoop]) + 1, &m_ppucElemArray[ uiLoop]))) { flmAssert( 0); } f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)ppucElemArray[uiLoop]); } m_uiNumElems = uiNumElems; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE TestBase::initCleanTestState( const char * pszDibName) { RCODE rc = FERR_OK; CREATE_OPTS createOpts; // Create the database f_memset( &createOpts, 0, sizeof( CREATE_OPTS)); if ( RC_BAD( rc = FlmDbCreate( pszDibName, NULL, NULL, NULL, NULL, &createOpts, &m_hDb))) { if( rc == FERR_FILE_EXISTS) { if( RC_BAD( rc = FlmDbRemove( pszDibName, NULL, NULL, TRUE))) { goto Exit; } } if( RC_BAD( rc = FlmDbCreate( pszDibName, NULL, NULL, NULL, NULL, &createOpts, &m_hDb))) { goto Exit; } } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE ArgList::expandArgs( char ** ppszArgs, FLMUINT uiNumArgs) { RCODE rc = FERR_OK; FLMUINT uiLoop; for( uiLoop = 0; uiLoop < uiNumArgs; uiLoop++) { if( ppszArgs[uiLoop][0] == '@') { if( RC_BAD( rc = expandFileArgs( &ppszArgs[uiLoop][ 1]))) { goto Exit; } } else { if( RC_BAD( rc = addArg( ppszArgs[ uiLoop]))) { goto Exit; } } } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ FlagSet::FlagSet( const FlagSet& fs) { if( RC_BAD( f_alloc( sizeof( FLMBYTE *) * fs.m_uiNumElems, &m_ppucElemArray))) { flmAssert( 0); } if( RC_BAD( f_alloc( sizeof( FLMBOOL) * fs.m_uiNumElems, &m_pbFlagArray))) { flmAssert( 0); } f_memset( m_pbFlagArray, 0, sizeof( FLMBOOL) * fs.m_uiNumElems); for( FLMUINT uiLoop = 0; uiLoop < fs.m_uiNumElems; uiLoop++) { if( RC_BAD( f_alloc( f_strlen( (char *)fs.m_ppucElemArray[uiLoop]) + 1, &m_ppucElemArray[ uiLoop]))) { flmAssert( 0); } f_strcpy( (char *)m_ppucElemArray[uiLoop], (char *)fs.m_ppucElemArray[uiLoop]); } m_uiNumElems = fs.m_uiNumElems; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE ArgList::addArg( const char * pszArg) { RCODE rc = FERR_OK; if( m_uiNumEntries >= m_uiCapacity) { if( RC_BAD( rc = resize())) { goto Exit; } } if( RC_BAD( rc = f_alloc( f_strlen( pszArg) + 1, &m_ppszArgs[ m_uiNumEntries]))) { goto Exit; } f_strcpy( m_ppszArgs[ m_uiNumEntries++], pszArg); Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE IFlmTestLogger::appendString( const char * pszString) { RCODE rc = FERR_OK; char * pszTemp = NULL; if ( RC_BAD( rc = f_alloc( f_strlen( pszString) + 3, &pszTemp))) { goto Exit; } f_sprintf( pszTemp, "%s\n", pszString); if( RC_BAD( rc = f_filecat( m_szFilename, pszString))) { goto Exit; } Exit: if ( pszTemp) { f_free( &pszTemp); } return rc; }
/**************************************************************************** Desc: ****************************************************************************/ RCODE ArgList::resize( void) { RCODE rc = FERR_OK; FLMUINT uiLoop; char ** ppszTemp = NULL; if( RC_BAD( rc = f_alloc( m_uiCapacity * GROW_FACTOR * sizeof(char*), &ppszTemp))) { goto Exit; } m_uiCapacity *= GROW_FACTOR; for( uiLoop = 0; uiLoop < m_uiNumEntries; uiLoop++) { if( RC_BAD( rc = f_alloc( f_strlen( m_ppszArgs[ uiLoop]) + 1, &ppszTemp[ uiLoop]))) { f_free( &ppszTemp); goto Exit; } f_strcpy( ppszTemp[uiLoop], m_ppszArgs[uiLoop]); } f_free( &m_ppszArgs); m_ppszArgs = ppszTemp; Exit: return( rc); }
/**************************************************************************** Desc: Checks if the current database has any UNIQUE indexes that need to checked. Also does duplicate processing for the record. ****************************************************************************/ RCODE F_Db::processDupKeys( F_INDEX * pIndex) { RCODE rc = NE_SFLM_OK; // Sort and remove duplicates if (m_uiKrefCount > 1) { if (RC_BAD( rc = krefQuickSort( this, pIndex, m_pKrefTbl, 0, m_uiKrefCount - 1))) { goto Exit; } if (RC_BAD( rc = krefKillDups( this, pIndex, m_pKrefTbl, &m_uiKrefCount))) { goto Exit; } } Exit: return( rc); }
/*************************************************************************** Desc: This routine verifies the LFH blocks. *****************************************************************************/ RCODE F_DbCheck::verifyLFHBlocks( FLMBOOL * pbStartOverRV) { RCODE rc = NE_XFLM_OK; m_Progress.ui32LfNumber = 0; m_Progress.ui32LfType = 0; m_Progress.i32CheckPhase = XFLM_CHECK_LFH_BLOCKS; m_Progress.bStartFlag = TRUE; if (RC_BAD( rc = chkCallProgFunc())) { goto Exit; } m_Progress.bStartFlag = FALSE; f_yieldCPU(); // Go through the LFH blocks. if (RC_BAD( rc = verifyBlkChain( &m_pDbInfo->m_LFHBlocks, XFLM_LOCALE_LFH_LIST, (FLMUINT)m_pDb->m_pDatabase->m_lastCommittedDbHdr.ui32FirstLFBlkAddr, BT_LFH_BLK, pbStartOverRV)) || *pbStartOverRV) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Compose a key buffer from the vector's components. ****************************************************************************/ RCODE XFLAPI F_DataVector::outputKey( IF_Db * ifpDb, FLMUINT uiIndexNum, FLMUINT, // uiMatchFlags, //VISIT: Need to remove this from the interface. FLMBYTE * pucKeyBuf, FLMUINT uiKeyBufSize, FLMUINT * puiKeyLen) { RCODE rc = NE_XFLM_OK; IXD * pIxd; if (RC_BAD( rc = ((F_Db *)ifpDb)->m_pDict->getIndex( uiIndexNum, NULL, &pIxd, TRUE))) { goto Exit; } if (RC_BAD( rc = outputKey( pIxd, XFLM_MATCH_IDS | XFLM_MATCH_DOC_ID, pucKeyBuf, uiKeyBufSize, puiKeyLen, 0))) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Set a FLMUINT64 value for a vector element. ****************************************************************************/ RCODE XFLAPI F_DataVector::setUINT64( FLMUINT uiElementNumber, FLMUINT64 ui64Num) { RCODE rc = NE_XFLM_OK; FLMBYTE ucStorageBuf [FLM_MAX_NUM_BUF_SIZE]; FLMUINT uiStorageLen; uiStorageLen = sizeof( ucStorageBuf); if (RC_BAD( rc = flmNumber64ToStorage( ui64Num, &uiStorageLen, ucStorageBuf, FALSE, FALSE))) { goto Exit; } if (RC_BAD( rc = storeValue( uiElementNumber, XFLM_NUMBER_TYPE, ucStorageBuf, uiStorageLen))) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Reinsert all entries given a new root block. Caller will release 'this'. Used ONLY for building the first ROOT and two leaves of the tree. ****************************************************************************/ RCODE F_BtreeLeaf::split( F_BtreeRoot * pNewRoot) // New Non-leaf root { RCODE rc = NE_FLM_OK; FLMBYTE * pucEntry; FLMUINT uiPos; FLMUINT uiEntryCount = entryCount(); FLMUINT uiMid = (uiEntryCount + 1) >> 1; if (RC_BAD( rc = pNewRoot->setupTree( ENTRY_POS(uiMid), ACCESS_BTREE_LEAF, NULL, NULL))) { goto Exit; } for (uiPos = 0; uiPos < uiEntryCount; uiPos++) { pucEntry = ENTRY_POS( uiPos); if ((rc = pNewRoot->search( pucEntry)) != NE_FLM_NOT_FOUND) { rc = RC_SET_AND_ASSERT( NE_FLM_FAILURE); goto Exit; } if (RC_BAD( rc = pNewRoot->insert( pucEntry))) { goto Exit; } } Exit: return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE FLMAPI f_rwlockCreate( F_RWLOCK * phReadWriteLock) { RCODE rc = NE_FLM_OK; F_RWLOCK_IMP * pReadWriteLock = NULL; if( RC_BAD( rc = f_calloc( sizeof( F_RWLOCK_IMP), &pReadWriteLock))) { goto Exit; } pReadWriteLock->hMutex = F_MUTEX_NULL; if( RC_BAD( rc = f_mutexCreate( &pReadWriteLock->hMutex))) { goto Exit; } *phReadWriteLock = (F_RWLOCK)pReadWriteLock; pReadWriteLock = NULL; Exit: if( pReadWriteLock) { f_rwlockDestroy( (F_RWLOCK *)&pReadWriteLock); } return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_FSRestore::openBackupSet( void) { RCODE rc = NE_SFLM_OK; flmAssert( m_bSetupCalled); flmAssert( !m_pMultiFileHdl); if( RC_BAD( rc = FlmAllocMultiFileHdl( &m_pMultiFileHdl))) { goto Exit; } if( RC_BAD( rc = m_pMultiFileHdl->openFile( m_szBackupSetPath))) { m_pMultiFileHdl->Release(); m_pMultiFileHdl = NULL; goto Exit; } m_ui64Offset = 0; m_bOpen = TRUE; Exit: return( rc); }
/*************************************************************************** Desc: This routine reads the header information in a FLAIM database, verifies the password, and returns the file header and log header information. *****************************************************************************/ RCODE flmGetHdrInfo( F_SuperFileHdl * pSFileHdl, XFLM_DB_HDR * pDbHdr, FLMUINT32 * pui32CalcCRC) { RCODE rc = NE_XFLM_OK; IF_FileHdl * pCFileHdl = NULL; if( RC_BAD( rc = pSFileHdl->getFileHdl( 0, FALSE, &pCFileHdl))) { goto Exit; } if( RC_BAD( rc = flmReadAndVerifyHdrInfo( NULL, pCFileHdl, pDbHdr, pui32CalcCRC))) { goto Exit; } Exit: if( pCFileHdl) { pCFileHdl->Release(); } return( rc); }
/**************************************************************************** Desc: This routine allocates a new F_Database object and links it into its hash buckets. NOTE: This routine assumes that the global mutex has already been locked. It may unlock it temporarily if there is an error, but will always relock it before exiting. ****************************************************************************/ RCODE F_DbSystem::allocDatabase( const char * pszDbPath, const char * pszDataDir, FLMBOOL bTempDb, F_Database ** ppDatabase) { RCODE rc = NE_XFLM_OK; F_Database * pDatabase = NULL; if ((pDatabase = f_new F_Database( bTempDb)) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; } if (RC_BAD( rc = pDatabase->setupDatabase( pszDbPath, pszDataDir))) { goto Exit; } *ppDatabase = pDatabase; Exit: if (RC_BAD( rc)) { if (pDatabase) { pDatabase->freeDatabase(); } } return( rc); }
/**************************************************************************** Desc: See if any F_INDEX structures need indexing in the background. ****************************************************************************/ RCODE F_Db::startBackgroundIndexing( void) { RCODE rc = NE_SFLM_OK; FLMBOOL bStartedTrans = FALSE; FLMUINT uiIndexNum; F_INDEX * pIndex; if (RC_BAD( rc = checkState( __FILE__, __LINE__))) { goto Exit; } if (m_eTransType != SFLM_NO_TRANS) { if (!okToCommitTrans()) { rc = RC_SET( NE_SFLM_ABORT_TRANS); goto Exit; } } else { // Need to have at least a read transaction going. if (RC_BAD( rc = beginTrans( SFLM_READ_TRANS))) { goto Exit; } bStartedTrans = TRUE; } for (uiIndexNum = 1, pIndex = m_pDict->m_pIndexTbl; uiIndexNum <= m_pDict->m_uiHighestIndexNum; uiIndexNum++, pIndex++) { // Restart any indexes that are off-line but not suspended if ((pIndex->uiFlags & (IXD_OFFLINE | IXD_SUSPENDED)) == IXD_OFFLINE) { flmAssert( flmBackgroundIndexGet( m_pDatabase, uiIndexNum, FALSE) == NULL); if (RC_BAD( rc = startIndexBuild( uiIndexNum))) { goto Exit; } } } Exit: if (bStartedTrans) { (void)abortTrans(); } return( rc); }
/**************************************************************************** Desc: ****************************************************************************/ RCODE F_IOBufferMgr::setupBufferMgr( FLMUINT uiMaxBuffers, FLMUINT uiMaxBytes, FLMBOOL bReuseBuffers) { RCODE rc = NE_FLM_OK; f_assert( uiMaxBuffers); f_assert( uiMaxBytes); if( RC_BAD( rc = f_mutexCreate( &m_hMutex))) { goto Exit; } #if !defined( FLM_UNIX) && !defined( FLM_NLM) if( RC_BAD( rc = f_semCreate( &m_hAvailSem))) { goto Exit; } #endif m_uiMaxBuffers = uiMaxBuffers; m_uiMaxBufferBytes = uiMaxBytes; m_bReuseBuffers = bReuseBuffers; Exit: return( rc); }
/*************************************************************************** Desc: This routine reads through the blocks in the AVAIL list and verifies that we don't have a loop or some other corruption in the list. *****************************************************************************/ RCODE F_DbCheck::verifyAvailList( FLMBOOL * pbStartOverRV) { RCODE rc = NE_XFLM_OK; m_Progress.ui32LfNumber = 0; m_Progress.ui32LfType = 0; m_Progress.i32CheckPhase = XFLM_CHECK_AVAIL_BLOCKS; m_Progress.bStartFlag = TRUE; if (RC_BAD( rc = chkCallProgFunc())) { goto Exit; } m_Progress.bStartFlag = FALSE; f_yieldCPU(); if (RC_BAD( rc = verifyBlkChain( &m_pDbInfo->m_AvailBlocks, XFLM_LOCALE_AVAIL_LIST, m_pDb->m_uiFirstAvailBlkAddr, BT_FREE, pbStartOverRV)) || *pbStartOverRV) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Stores a new value for the specified name (or creates a new name/value pair) in the list of INI_STRUCTs ****************************************************************************/ RCODE FTKAPI F_IniFile::setParam( const char * pszParamName, const char * pszParamVal) { RCODE rc = NE_FLM_OK; INI_LINE * pLine; f_assert( m_bReady); // If the parameter exists in the list, just store the new value. // Othewise, create a new INI_LINE and add it to the list pLine = findParam( pszParamName); if( !pLine) { if( RC_BAD( rc = setParamCommon( &pLine, pszParamName))) { goto Exit; } } if( RC_BAD( rc = toAscii( &pLine->pszParamValue, pszParamVal))) { goto Exit; } Exit: return( rc); }
/**************************************************************************** Desc: Recover a database on startup. ****************************************************************************/ RCODE F_Database::doRecover( F_Db * pDb, IF_RestoreClient * pRestoreObj, IF_RestoreStatus * pRestoreStatus) { RCODE rc = NE_XFLM_OK; XFLM_DB_HDR * pLastCommittedDbHdr; // At this point, m_lastCommittedDbHdr contains the header // that was read from disk, which will be the state of the // header as of the last completed checkpoint. Therefore, // we copy it into m_checkpointDbHdr. pLastCommittedDbHdr = &m_lastCommittedDbHdr; f_memcpy( &m_checkpointDbHdr, pLastCommittedDbHdr, sizeof( XFLM_DB_HDR)); // Do a physical rollback on the database to restore the last // checkpoint. if (RC_BAD( rc = pDb->physRollback( (FLMUINT)pLastCommittedDbHdr->ui32RblEOF, (FLMUINT)pLastCommittedDbHdr->ui32RblFirstCPBlkAddr, TRUE, pLastCommittedDbHdr->ui64RflLastCPTransID))) { goto Exit; } pLastCommittedDbHdr->ui32RblFirstCPBlkAddr = 0; pLastCommittedDbHdr->ui32RblEOF = (FLMUINT32)m_uiBlockSize; if (RC_BAD( rc = writeDbHdr( pDb->m_pDbStats, pDb->m_pSFileHdl, pLastCommittedDbHdr, &m_checkpointDbHdr, TRUE))) { goto Exit; } // Set uiFirstLogCPBlkAddress to zero to indicate that no // physical blocks have been logged for the current checkpoint. // The above call to flmPhysRollback will have set the log header // to the same thing. m_uiFirstLogCPBlkAddress = 0; // Set the checkpointDbHdr to be the same as the log header f_memcpy( &m_checkpointDbHdr, pLastCommittedDbHdr, sizeof( XFLM_DB_HDR)); // Open roll forward log and redo the transactions that // occurred since the last checkpoint, if any. if( RC_BAD( rc = m_pRfl->recover( pDb, pRestoreObj, pRestoreStatus))) { goto Exit; } Exit: return( rc); }
RCODE FTKAPI F_DirHdl::next( void) { char szFoundPath[ F_PATH_MAX_SIZE]; char szDummyPath[ F_PATH_MAX_SIZE]; FLMUINT uiSearchAttributes; FLMUINT uiFoundAttrib; IF_FileSystem * pFileSystem = f_getFileSysPtr(); if( RC_BAD( m_rc)) { goto Exit; } uiSearchAttributes = F_IO_FA_NORMAL | F_IO_FA_RDONLY | F_IO_FA_ARCHIVE | F_IO_FA_DIRECTORY; for( ;;) { if( m_bFirstTime) { m_bFirstTime = FALSE; if( RC_BAD( m_rc = f_fileFindFirst( m_szDirectoryPath, uiSearchAttributes, &m_FindData, szFoundPath, &uiFoundAttrib))) { goto Exit; } m_bFindOpen = TRUE; m_uiAttrib = uiFoundAttrib; } else { if( RC_BAD( m_rc = f_fileFindNext( &m_FindData, szFoundPath, &uiFoundAttrib))) { goto Exit; } m_uiAttrib = uiFoundAttrib; } if( RC_BAD( m_rc = pFileSystem->pathReduce( szFoundPath, szDummyPath, m_szFileName))) { goto Exit; } if( pFileSystem->doesFileMatch( m_szFileName, m_szPattern)) { break; } } Exit: return( m_rc); }
/**************************************************************************** Desc : Retrieves the current transaction number of a database Notes: This routine should only be called only from within an update transaction since read transactions are not assigned a transaction number. ****************************************************************************/ FLMEXP RCODE FLMAPI FlmDbGetTransId( HFDB hDb, FLMUINT * puiTrNumRV) { RCODE rc = FERR_OK; FDB * pDb = (FDB *)hDb; FLMBOOL bIgnore; if (IsInCSMode( hDb)) { fdbInitCS( pDb); CS_CONTEXT * pCSContext = pDb->pCSContext; FCL_WIRE Wire( pCSContext, pDb); // Send a request to get the transaction ID. if (RC_BAD( rc = Wire.sendOp( FCS_OPCLASS_DATABASE, FCS_OP_GET_TRANS_ID))) { goto Exit; } if (RC_BAD( rc = Wire.sendTerminate())) { goto Transmission_Error; } // Read the response if (RC_BAD( rc = Wire.read())) { goto Transmission_Error; } *puiTrNumRV = Wire.getTransId(); rc = Wire.getRCode(); goto Exit; Transmission_Error: pCSContext->bConnectionGood = FALSE; goto Exit; } if (RC_BAD( rc = fdbInit( pDb, FLM_UPDATE_TRANS, FDB_TRANS_GOING_OK, 0, &bIgnore))) { goto Exit; } *puiTrNumRV = pDb->LogHdr.uiCurrTransID; Exit: flmExit( FLM_DB_GET_TRANS_ID, pDb, rc); return( rc); }
/**************************************************************************** Desc: Make sure the vector array is allocated at least up to the element number that is passed in. ****************************************************************************/ RCODE F_DataVector::allocVectorArray( FLMUINT uiElementNumber) { RCODE rc = NE_XFLM_OK; if (uiElementNumber >= m_uiNumElements) { // May need to allocate a new vector array if (uiElementNumber >= m_uiVectorArraySize) { FLMUINT uiNewArraySize = uiElementNumber + 32; F_VECTOR_ELEMENT * pNewVector; if (m_pVectorElements == &m_VectorArray [0]) { if (RC_BAD( rc = f_alloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT), &pNewVector))) { goto Exit; } if (m_uiNumElements) { f_memcpy( pNewVector, m_pVectorElements, m_uiNumElements * sizeof( F_VECTOR_ELEMENT)); } } else { pNewVector = m_pVectorElements; if (RC_BAD( rc = f_realloc( uiNewArraySize * sizeof( F_VECTOR_ELEMENT), &pNewVector))) { goto Exit; } } m_pVectorElements = pNewVector; m_uiVectorArraySize = uiNewArraySize; } // Initialized everything between the old last element and // the new element, including the new element, to zeroes. f_memset( &m_pVectorElements [m_uiNumElements], 0, sizeof( F_VECTOR_ELEMENT) * (uiElementNumber - m_uiNumElements + 1)); m_uiNumElements = uiElementNumber + 1; } Exit: return( rc); }
/**************************************************************************** Desc: This routine obtains exclusive access to a database by creating a .lck file. FLAIM holds the .lck file open as long as the database is open. When the database is finally closed, it deletes the .lck file. This is only used for 3.x databases. ****************************************************************************/ RCODE flmCreateLckFile( const char * pszFilePath, IF_FileHdl ** ppLockFileHdlRV) { RCODE rc = NE_XFLM_OK; char szLockPath [F_PATH_MAX_SIZE]; char szDbBaseName [F_FILENAME_SIZE]; char * pszFileExt; IF_FileHdl * pLockFileHdl = NULL; char szFilePathStr[ F_PATH_MAX_SIZE]; if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathToStorageString( pszFilePath, szFilePathStr))) { goto Exit; } // Extract the 8.3 name and put a .lck extension on it to create // the full path for the .lck file. if (RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathReduce( szFilePathStr, szLockPath, szDbBaseName))) { goto Exit; } pszFileExt = &szDbBaseName [0]; while ((*pszFileExt) && (*pszFileExt != '.')) pszFileExt++; f_strcpy( pszFileExt, ".lck"); if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->pathAppend( szLockPath, szDbBaseName))) { goto Exit; } if( RC_BAD( rc = gv_XFlmSysData.pFileSystem->createLockFile( szLockPath, &pLockFileHdl))) { goto Exit; } *ppLockFileHdlRV = (IF_FileHdl *)pLockFileHdl; pLockFileHdl = NULL; Exit: if (pLockFileHdl) { (void)pLockFileHdl->closeFile(); pLockFileHdl->Release(); pLockFileHdl = NULL; } return( rc); }
/****************************************************************** Desc: Implements the addChar function of the DynamicBuffer class *******************************************************************/ RCODE F_DynamicBuffer::addChar( char ucCharacter) { RCODE rc = FERR_OK; if (!m_bSetup) { flmAssert( 0); rc = RC_SET( FERR_FAILURE); goto Exit; } f_mutexLock( m_hMutex); // Is there room for just one more character plus a terminator? if ((m_uiBuffSize - m_uiUsedChars) > 1) { m_pucBuffer[ m_uiUsedChars++] = ucCharacter; m_pucBuffer[ m_uiUsedChars] = 0; } else { // Allocate a new buffer or increase the size of the existing one. if( !m_uiBuffSize) { if( RC_BAD( rc = f_alloc( 50, &m_pucBuffer))) { goto Exit; } m_uiBuffSize = 50; } else { if( RC_BAD( rc = f_realloc( m_uiBuffSize + 50, &m_pucBuffer))) { goto Exit; } m_uiBuffSize += 50; } m_pucBuffer[ m_uiUsedChars++] = ucCharacter; m_pucBuffer[ m_uiUsedChars] = 0; } Exit: if ( m_bSetup) { f_mutexUnlock( m_hMutex); } return( rc); }
/**************************************************************************** Desc: Setup two child blocks for a root block. ****************************************************************************/ RCODE F_BtreeRoot::setupTree( FLMBYTE * pucMidEntry, // If !NULL entry to insert into root. eDynRSetBlkTypes eBlkType, // Leaf or non-leaf F_BtreeBlk ** ppLeftBlk, // (out) F_BtreeBlk ** ppRightBlk) // (out) { RCODE rc = NE_FLM_OK; F_BtreeBlk * pLeftBlk = NULL; F_BtreeBlk * pRightBlk = NULL; if (RC_BAD( rc = newBlk( &pLeftBlk, eBlkType))) { goto Exit; } if (RC_BAD( rc = newBlk( &pRightBlk, eBlkType))) { goto Exit; } if (eBlkType == ACCESS_BTREE_NON_LEAF) { ((F_BtreeNonLeaf *)pRightBlk)->lemBlk( lemBlk()); } // Fix up the linkages pLeftBlk->nextBlk( pRightBlk->blkAddr()); pRightBlk->prevBlk( pLeftBlk->blkAddr()); lemBlk( pRightBlk->blkAddr()); if (pucMidEntry) { // Add the midentry to the root block. Search to position and insert. searchEntry( pucMidEntry); insertEntry( pucMidEntry, pLeftBlk->blkAddr()); } m_uiLevels++; if (ppLeftBlk) { *ppLeftBlk = pLeftBlk; } if (ppRightBlk) { *ppRightBlk = pRightBlk; } Exit: return( rc); }
/**************************************************************************** Desc: Set auto turn off keep RFL flag. ****************************************************************************/ RCODE XFLAPI F_Db::setAutoTurnOffKeepRflFlag( FLMBOOL bAutoTurnOff ) { RCODE rc = NE_XFLM_OK; FLMBOOL bStartedTrans = FALSE; // See if the database is being forced to close if (RC_BAD( rc = checkState( __FILE__, __LINE__))) { goto Exit; } // Start an update transaction. Must not already be one going. if (m_eTransType != XFLM_NO_TRANS) { rc = RC_SET( NE_XFLM_TRANS_ACTIVE); goto Exit; } if (RC_BAD( rc = beginTrans( XFLM_UPDATE_TRANS))) { goto Exit; } bStartedTrans = TRUE; // Change the uncommitted log header m_pDatabase->m_uncommittedDbHdr.ui8RflAutoTurnOffKeep = (FLMUINT8)(bAutoTurnOff ? (FLMUINT8)1 : (FLMUINT8)0); // Commit the transaction. bStartedTrans = FALSE; if (RC_BAD( rc = commitTrans( 0, FALSE))) { goto Exit; } Exit: if (bStartedTrans) { abortTrans(); } return( rc); }
/*************************************************************************** Desc: *****************************************************************************/ RCODE F_Database::startMaintThread( void) { RCODE rc = NE_SFLM_OK; char szThreadName[ F_PATH_MAX_SIZE]; char szBaseName[ 32]; flmAssert( !m_pMaintThrd); flmAssert( m_hMaintSem == F_SEM_NULL); // Generate the thread name if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->pathReduce( m_pszDbPath, szThreadName, szBaseName))) { goto Exit; } f_sprintf( (char *)szThreadName, "Maintenance (%s)", (char *)szBaseName); // Create the maintenance semaphore if( RC_BAD( rc = f_semCreate( &m_hMaintSem))) { goto Exit; } // Start the thread. if( RC_BAD( rc = gv_SFlmSysData.pThreadMgr->createThread( &m_pMaintThrd, F_Database::maintenanceThread, szThreadName, 0, 0, this, NULL, 32000))) { goto Exit; } // Signal the thread to check for any queued work f_semSignal( m_hMaintSem); Exit: if( RC_BAD( rc)) { if( m_hMaintSem != F_SEM_NULL) { f_semDestroy( &m_hMaintSem); } } return( rc); }