From dae150e693099b549a330e3dfdc6b29c9cdef878 Mon Sep 17 00:00:00 2001 From: ahodgkinson Date: Mon, 17 Jul 2006 20:35:20 +0000 Subject: [PATCH] SQL changes. Updated everything so that it builds on Windows and uses the new FTK interfaces. git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@674 0109f412-320b-0410-ab79-c3e0c5ffbbe6 --- sql/make.exe | Bin 0 -> 241664 bytes sql/src/createdatabase.cpp | 2 +- sql/src/fcache.h | 601 ++----------------------------------- sql/src/fdbcopy.cpp | 14 +- sql/src/fdict.cpp | 2 +- sql/src/fdict.h | 2 +- sql/src/fdllmain.cpp | 4 +- sql/src/ffilehdr.cpp | 8 + sql/src/filesys.h | 4 - sql/src/flaimsys.h | 52 ++-- sql/src/flbackup.cpp | 36 +-- sql/src/flclose.cpp | 2 +- sql/src/flconvrt.cpp | 3 + sql/src/flerror.cpp | 3 + sql/src/flindex.cpp | 7 +- sql/src/flreduce.cpp | 3 +- sql/src/frow.cpp | 195 +----------- sql/src/fslfileu.cpp | 99 +++--- sql/src/fstructs.h | 53 +--- sql/src/fsysdata.cpp | 168 ++++------- sql/src/kybuild.cpp | 10 +- sql/src/opendatabase.cpp | 20 +- sql/src/recover.cpp | 8 +- sql/src/rfl.cpp | 87 +++--- sql/src/rfl.h | 6 +- sql/src/scache.cpp | 311 +++++++------------ sql/src/sqleval.cpp | 2 +- sql/src/sqloptimize.cpp | 16 +- sql/src/sqlstatement.cpp | 15 +- sql/src/translog.cpp | 59 ++-- sql/src/updaterow.cpp | 2 +- sql/src/whereclause.cpp | 6 +- 32 files changed, 427 insertions(+), 1373 deletions(-) create mode 100644 sql/make.exe diff --git a/sql/make.exe b/sql/make.exe new file mode 100644 index 0000000000000000000000000000000000000000..54d888d7630b6072ef9730e674afa5ce77325365 GIT binary patch literal 241664 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 = calcBlkCRC( pBlkHdr, SIZEOF_STD_BLK_HDR); if (RC_BAD( rc = m_pSFileHdl->writeBlock( (FLMUINT)pBlkHdr->ui32BlkAddr, - uiBlkSize, pucBuf, NULL, &uiWriteBytes))) + uiBlkSize, pucBuf, &uiWriteBytes))) { goto Exit; } diff --git a/sql/src/fcache.h b/sql/src/fcache.h index c984721..94c3487 100644 --- a/sql/src/fcache.h +++ b/sql/src/fcache.h @@ -121,12 +121,6 @@ public: { } -#ifdef FLM_CACHE_PROTECT - virtual void protectCachedItem( void) = 0; - - virtual void unprotectCachedItem( void) = 0; -#endif - private: F_CachedItem * m_pPrevInGlobal; @@ -175,19 +169,9 @@ public: FINLINE void linkGlobalAsMRU( F_CachedItem * pItem) { -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif - if ((pItem->m_pNextInGlobal = m_pMRUItem) != NULL) { -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->unprotectCachedItem(); -#endif pItem->m_pNextInGlobal->m_pPrevInGlobal = pItem; -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->protectCachedItem(); -#endif } else { @@ -196,9 +180,6 @@ public: } pItem->m_pPrevInGlobal = NULL; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif m_pMRUItem = pItem; flmAssert( pItem != pItem->m_pPrevInGlobal); flmAssert( pItem != pItem->m_pNextInGlobal); @@ -220,19 +201,9 @@ public: flmAssert( m_pLastMRUItem); -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif - if( m_pLastMRUItem->m_pNextInGlobal) { -#ifdef FLM_CACHE_PROTECT - m_pLastMRUItem->m_pNextInGlobal->unprotectCachedItem(); -#endif m_pLastMRUItem->m_pNextInGlobal->m_pPrevInGlobal = pItem; -#ifdef FLM_CACHE_PROTECT - m_pLastMRUItem->m_pNextInGlobal->protectCachedItem(); -#endif pItem->m_pNextInGlobal = m_pLastMRUItem->m_pNextInGlobal; } else @@ -241,21 +212,11 @@ public: m_pLRUItem = pItem; } -#ifdef FLM_CACHE_PROTECT - m_pLastMRUItem->unprotectCachedItem(); -#endif m_pLastMRUItem->m_pNextInGlobal = pItem; -#ifdef FLM_CACHE_PROTECT - m_pLastMRUItem->protectCachedItem(); -#endif pItem->m_pPrevInGlobal = m_pLastMRUItem; m_pLastMRUItem = pItem; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif - flmAssert( pItem != pItem->m_pPrevInGlobal); flmAssert( pItem != pItem->m_pNextInGlobal); } @@ -267,19 +228,9 @@ public: FINLINE void linkGlobalAsLRU( F_CachedItem * pItem) { -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif - if ((pItem->m_pPrevInGlobal = m_pLRUItem) != NULL) { -#ifdef FLM_CACHE_PROTECT - pItem->m_pPrevInGlobal->unprotectCachedItem(); -#endif pItem->m_pPrevInGlobal->m_pNextInGlobal = pItem; -#ifdef FLM_CACHE_PROTECT - pItem->m_pPrevInGlobal->protectCachedItem(); -#endif } else { @@ -291,9 +242,6 @@ public: } pItem->m_pNextInGlobal = NULL; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif m_pLRUItem = pItem; flmAssert( pItem != pItem->m_pPrevInGlobal); @@ -323,13 +271,7 @@ public: { flmAssert( pItem != m_pLRUItem); -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->unprotectCachedItem(); -#endif pItem->m_pNextInGlobal->m_pPrevInGlobal = pItem->m_pPrevInGlobal; -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->protectCachedItem(); -#endif } else { @@ -340,27 +282,15 @@ public: { flmAssert( pItem != m_pMRUItem); -#ifdef FLM_CACHE_PROTECT - pItem->m_pPrevInGlobal->unprotectCachedItem(); -#endif pItem->m_pPrevInGlobal->m_pNextInGlobal = pItem->m_pNextInGlobal; -#ifdef FLM_CACHE_PROTECT - pItem->m_pPrevInGlobal->protectCachedItem(); -#endif } else { m_pMRUItem = pItem->m_pNextInGlobal; } -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif pItem->m_pNextInGlobal = NULL; pItem->m_pPrevInGlobal = NULL; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif } // Moves a cached item one step closer to the MRU slot in the global list. @@ -381,57 +311,27 @@ public: if (pPrevItem->m_pPrevInGlobal) { -#ifdef FLM_CACHE_PROTECT - pPrevItem->m_pPrevInGlobal->unprotectCachedItem(); -#endif pPrevItem->m_pPrevInGlobal->m_pNextInGlobal = pItem; -#ifdef FLM_CACHE_PROTECT - pPrevItem->m_pPrevInGlobal->protectCachedItem(); -#endif } else { m_pMRUItem = pItem; } -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif pItem->m_pPrevInGlobal = pPrevItem->m_pPrevInGlobal; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif -#ifdef FLM_CACHE_PROTECT - pPrevItem->unprotectCachedItem(); -#endif pPrevItem->m_pPrevInGlobal = pItem; pPrevItem->m_pNextInGlobal = pItem->m_pNextInGlobal; -#ifdef FLM_CACHE_PROTECT - pPrevItem->protectCachedItem(); -#endif if (pItem->m_pNextInGlobal) { -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->unprotectCachedItem(); -#endif pItem->m_pNextInGlobal->m_pPrevInGlobal = pPrevItem; -#ifdef FLM_CACHE_PROTECT - pItem->m_pNextInGlobal->protectCachedItem(); -#endif } else { m_pLRUItem = pPrevItem; } -#ifdef FLM_CACHE_PROTECT - pItem->unprotectCachedItem(); -#endif pItem->m_pNextInGlobal = pPrevItem; -#ifdef FLM_CACHE_PROTECT - pItem->protectCachedItem(); -#endif } } @@ -466,13 +366,13 @@ public: FINLINE void incrTotalBytes( FLMUINT uiIncrAmount) { - m_pSlabManager->incrementTotalBytesAllocated( uiIncrAmount, FALSE); + m_pSlabManager->incrementTotalBytesAllocated( uiIncrAmount); } FINLINE void decrTotalBytes( FLMUINT uiDecrAmount) { - m_pSlabManager->decrementTotalBytesAllocated( uiDecrAmount, FALSE); + m_pSlabManager->decrementTotalBytesAllocated( uiDecrAmount); } FINLINE FLMUINT totalBytes( void) @@ -588,11 +488,11 @@ public: { } - void relocate( + void FLMAPI relocate( void * pvOldAlloc, void * pvNewAlloc); - FLMBOOL canRelocate( + FLMBOOL FLMAPI canRelocate( void * pvOldAlloc); }; @@ -653,14 +553,6 @@ public: } } - FINLINE void getUsageStats( - FLM_SLAB_USAGE * pUsage) - { - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager->lockMutex(); - f_memcpy( pUsage, &m_Usage, sizeof( FLM_SLAB_USAGE)); - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager->unlockMutex(); - } - private: RCODE initHashTbl( void); @@ -831,20 +723,6 @@ public: ~F_CachedBlock(); -#ifdef FLM_CACHE_PROTECT - FINLINE void protectCachedItem( void) - { - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->protectBuffer( this); - } -#endif - -#ifdef FLM_CACHE_PROTECT - FINLINE void unprotectCachedItem( void) - { - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->unprotectBuffer( this); - } -#endif - FINLINE FLMUINT memSize( void) { return( gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->getTrueSize( @@ -913,13 +791,7 @@ public: gv_SFlmSysData.pBlockCacheMgr->m_Usage.uiOldVerCount--; } -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_ui64HighTransID = ui64NewTransID; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Determines if a cache block is needed by a read transaction. @@ -938,27 +810,14 @@ public: if ((m_pNextInReplaceList = gv_SFlmSysData.pBlockCacheMgr->m_pMRUReplace) != NULL) { -#ifdef FLM_CACHE_PROTECT - m_pNextInReplaceList->unprotectCachedItem(); -#endif m_pNextInReplaceList->m_pPrevInReplaceList = this; -#ifdef FLM_CACHE_PROTECT - m_pNextInReplaceList->protectCachedItem(); -#endif } else { gv_SFlmSysData.pBlockCacheMgr->m_pLRUReplace = this; } -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_pPrevInReplaceList = NULL; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif - gv_SFlmSysData.pBlockCacheMgr->m_pMRUReplace = this; gv_SFlmSysData.pBlockCacheMgr->m_uiReplaceableCount++; gv_SFlmSysData.pBlockCacheMgr->m_uiReplaceableBytes += memSize(); @@ -972,26 +831,14 @@ public: if ((m_pPrevInReplaceList = gv_SFlmSysData.pBlockCacheMgr->m_pLRUReplace) != NULL) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInReplaceList->unprotectCachedItem(); -#endif m_pPrevInReplaceList->m_pNextInReplaceList = this; -#ifdef FLM_CACHE_PROTECT - m_pPrevInReplaceList->protectCachedItem(); -#endif } else { gv_SFlmSysData.pBlockCacheMgr->m_pMRUReplace = this; } -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_pNextInReplaceList = NULL; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif gv_SFlmSysData.pBlockCacheMgr->m_pLRUReplace = this; gv_SFlmSysData.pBlockCacheMgr->m_uiReplaceableCount++; gv_SFlmSysData.pBlockCacheMgr->m_uiReplaceableBytes += memSize(); @@ -1007,19 +854,9 @@ public: if( (pPrevSCache = m_pPrevInReplaceList) != NULL) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if( pPrevSCache->m_pPrevInReplaceList) { -#ifdef FLM_CACHE_PROTECT - pPrevSCache->m_pPrevInReplaceList->unprotectCachedItem(); -#endif pPrevSCache->m_pPrevInReplaceList->m_pNextInReplaceList = this; -#ifdef FLM_CACHE_PROTECT - pPrevSCache->m_pPrevInReplaceList->protectCachedItem(); -#endif } else { @@ -1028,24 +865,12 @@ public: m_pPrevInReplaceList = pPrevSCache->m_pPrevInReplaceList; -#ifdef FLM_CACHE_PROTECT - pPrevSCache->unprotectCachedItem(); -#endif pPrevSCache->m_pPrevInReplaceList = this; pPrevSCache->m_pNextInReplaceList = m_pNextInReplaceList; -#ifdef FLM_CACHE_PROTECT - pPrevSCache->protectCachedItem(); -#endif if( m_pNextInReplaceList) { -#ifdef FLM_CACHE_PROTECT - m_pNextInReplaceList->unprotectCachedItem(); -#endif m_pNextInReplaceList->m_pPrevInReplaceList = pPrevSCache; -#ifdef FLM_CACHE_PROTECT - m_pNextInReplaceList->protectCachedItem(); -#endif } else { @@ -1053,9 +878,6 @@ public: } m_pNextInReplaceList = pPrevSCache; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } } @@ -1066,9 +888,6 @@ public: { if( m_ui16Flags) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif if( (m_ui16Flags &= ~ui16FlagsToClear) == 0) { if( !m_pPrevInGlobal || @@ -1082,9 +901,6 @@ public: linkToReplaceListAsLRU(); } } -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } } @@ -1096,18 +912,12 @@ public: { flmAssert( ui16FlagsToSet); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif if( !m_ui16Flags) { unlinkFromReplaceList(); } m_ui16Flags |= ui16FlagsToSet; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Set the dirty flag on a cache block. @@ -1178,9 +988,6 @@ public: FLMUINT) // uiThreadId) #endif { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif #ifdef FLM_DEBUG if (m_pUseList || @@ -1236,10 +1043,6 @@ public: gv_SFlmSysData.pBlockCacheMgr->m_uiBlocksUsed--; } } - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Tests if a block can be freed from cache. @@ -1319,8 +1122,7 @@ public: void * operator new( FLMSIZET uiSize, - FLMUINT uiBlockSize, - FLMBOOL bAllocMutexLocked = FALSE) + FLMUINT uiBlockSize) #if !defined( FLM_NLM) throw() #endif @@ -1417,6 +1219,10 @@ private: } #endif + static void FLMAPI objectAllocInit( + void * pvAlloc, + FLMUINT uiSize); + // Link a cached block into the global list as the MRU item. This routine // assumes that the block cache mutex has already been locked. @@ -1506,29 +1312,16 @@ private: FINLINE void linkToHashBucket( F_CachedBlock ** ppSCacheBucket) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - #ifdef SCACHE_LINK_CHECKING checkHashLinks( ppSCacheBucket); #endif m_pPrevInHashBucket = NULL; if ((m_pNextInHashBucket = *ppSCacheBucket) != NULL) { -#ifdef FLM_CACHE_PROTECT - m_pNextInHashBucket->unprotectCachedItem(); -#endif m_pNextInHashBucket->m_pPrevInHashBucket = this; -#ifdef FLM_CACHE_PROTECT - m_pNextInHashBucket->protectCachedItem(); -#endif } + *ppSCacheBucket = this; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Unlink a cache block from its hash bucket. This routine assumes @@ -1536,10 +1329,6 @@ private: FINLINE void unlinkFromHashBucket( F_CachedBlock ** ppSCacheBucket) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - #ifdef SCACHE_LINK_CHECKING checkHashUnlinks( ppSCacheBucket); #endif @@ -1550,24 +1339,12 @@ private: if (m_pNextInHashBucket) { -#ifdef FLM_CACHE_PROTECT - m_pNextInHashBucket->unprotectCachedItem(); -#endif m_pNextInHashBucket->m_pPrevInHashBucket = m_pPrevInHashBucket; -#ifdef FLM_CACHE_PROTECT - m_pNextInHashBucket->protectCachedItem(); -#endif } if (m_pPrevInHashBucket) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInHashBucket->unprotectCachedItem(); -#endif m_pPrevInHashBucket->m_pNextInHashBucket = m_pNextInHashBucket; -#ifdef FLM_CACHE_PROTECT - m_pPrevInHashBucket->protectCachedItem(); -#endif } else { @@ -1576,10 +1353,6 @@ private: m_pNextInHashBucket = NULL; m_pPrevInHashBucket = NULL; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } void unlinkCache( @@ -1646,6 +1419,7 @@ private: // that indicate various things about the // block's current state. FLMUINT16 m_ui16BlkSize; // Block size + FLMBOOL m_bCanRelocate; // Can the block be moved in memory // NOTE: Keep debug items at the END of the structure. @@ -1679,11 +1453,11 @@ public: { } - void relocate( + void FLMAPI relocate( void * pvOldAlloc, void * pvNewAlloc); - FLMBOOL canRelocate( + FLMBOOL FLMAPI canRelocate( void * pvOldAlloc); }; @@ -1702,11 +1476,11 @@ public: { } - void relocate( + void FLMAPI relocate( void * pvOldAlloc, void * pvNewAlloc); - FLMBOOL canRelocate( + FLMBOOL FLMAPI canRelocate( void * pvOldAlloc); }; @@ -1725,11 +1499,11 @@ public: { } - void relocate( + void FLMAPI relocate( void * pvOldAlloc, void * pvNewAlloc); - FLMBOOL canRelocate( + FLMBOOL FLMAPI canRelocate( void * pvOldAlloc); }; @@ -1808,14 +1582,6 @@ public: } } - FINLINE void getUsageStats( - FLM_SLAB_USAGE * pUsage) - { - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager->lockMutex(); - f_memcpy( pUsage, &m_Usage, sizeof( FLM_SLAB_USAGE)); - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager->unlockMutex(); - } - private: // Hash function for hashing to rows in row cache. @@ -1994,18 +1760,6 @@ public: ~F_Row(); -#ifdef FLM_CACHE_PROTECT - FINLINE void protectCachedItem( void) - { - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->protectCell( this); - } - - FINLINE void unprotectCachedItem( void) - { - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->unprotectCell( this); - } -#endif - // This method assumes that the row cache mutex has been locked. FINLINE FLMBOOL canBeFreed( void) @@ -2067,27 +1821,15 @@ public: FINLINE void setRowAndDataPtr( FLMBYTE * pucActualAlloc) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif *((F_Row **)(pucActualAlloc)) = this; m_pucColumnData = pucActualAlloc + allocOverhead(); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } FINLINE void setColumnListPtr( FLMBYTE * pucActualAlloc) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif *((F_Row **)(pucActualAlloc)) = this; m_pColumns = (F_COLUMN_ITEM *)(pucActualAlloc + allocOverhead()); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } FINLINE FLMUINT64 getRowId( void) @@ -2113,13 +1855,7 @@ public: FINLINE void setOffsetIndex( FLMUINT uiOffsetIndex) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiOffsetIndex = uiOffsetIndex; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } FINLINE FLMUINT32 getBlkAddr( void) @@ -2130,13 +1866,7 @@ public: FINLINE void setBlkAddr( FLMUINT32 ui32BlkAddr) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_ui32BlkAddr = ui32BlkAddr; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } FINLINE FLMBOOL isRightVersion( @@ -2217,27 +1947,15 @@ public: // Assumes that the row cache mutex has already been locked. FINLINE void incrRowUseCount( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags = (m_uiCacheFlags & (~(NCA_COUNTER_BITS))) | (((m_uiCacheFlags & NCA_COUNTER_BITS) + 1)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void decrRowUseCount( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags = (m_uiCacheFlags & (~(NCA_COUNTER_BITS))) | (((m_uiCacheFlags & NCA_COUNTER_BITS) - 1)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } void setRowDirty( @@ -2551,49 +2269,25 @@ private: // Assumes that the row cache mutex has already been locked. FINLINE void setReadingIn( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags |= NCA_READING_IN; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unsetReadingIn( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags &= (~(NCA_READING_IN)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void setUncommitted( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags |= NCA_UNCOMMITTED; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unsetUncommitted( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags &= (~(NCA_UNCOMMITTED)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. @@ -2605,49 +2299,25 @@ private: // Assumes that the row cache mutex has already been locked. FINLINE void setLatestVer( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags |= NCA_LATEST_VER; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unsetLatestVer( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags &= (~(NCA_LATEST_VER)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void setPurged( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags |= NCA_PURGED; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unsetPurged( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags &= (~(NCA_PURGED)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. @@ -2659,25 +2329,13 @@ private: // Assumes that the row cache mutex has already been locked. FINLINE void setLinkedToDatabase( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags |= NCA_LINKED_TO_DATABASE; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unsetLinkedToDatabase( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiCacheFlags &= (~(NCA_LINKED_TO_DATABASE)); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. @@ -2692,24 +2350,12 @@ private: { if (m_pNextInGlobal) { -#ifdef FLM_CACHE_PROTECT - m_pNextInGlobal->unprotectCachedItem(); -#endif m_pNextInGlobal->m_pPrevInGlobal = m_pPrevInGlobal; -#ifdef FLM_CACHE_PROTECT - m_pNextInGlobal->protectCachedItem(); -#endif } if (m_pPrevInGlobal) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInGlobal->unprotectCachedItem(); -#endif m_pPrevInGlobal->m_pNextInGlobal = m_pNextInGlobal; -#ifdef FLM_CACHE_PROTECT - m_pPrevInGlobal->protectCachedItem(); -#endif } else { @@ -2717,14 +2363,8 @@ private: (F_Row *)m_pNextInGlobal; } -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_pPrevInGlobal = NULL; m_pNextInGlobal = NULL; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Link a row to an F_Database list at the head of the list. @@ -2732,22 +2372,12 @@ private: FINLINE void linkToDatabaseAtHead( F_Database * pDatabase) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (!pDatabase->m_pLastDirtyRow || rowIsDirty()) { m_pPrevInDatabase = NULL; if ((m_pNextInDatabase = pDatabase->m_pFirstRow) != NULL) { -#ifdef FLM_CACHE_PROTECT - pDatabase->m_pFirstRow->unprotectCachedItem(); -#endif pDatabase->m_pFirstRow->m_pPrevInDatabase = this; -#ifdef FLM_CACHE_PROTECT - pDatabase->m_pFirstRow->protectCachedItem(); -#endif } else { @@ -2769,22 +2399,10 @@ private: m_pPrevInDatabase = pDatabase->m_pLastDirtyRow; m_pNextInDatabase = m_pPrevInDatabase->m_pNextInDatabase; -#ifdef FLM_CACHE_PROTECT - m_pPrevInDatabase->unprotectCachedItem(); -#endif m_pPrevInDatabase->m_pNextInDatabase = this; -#ifdef FLM_CACHE_PROTECT - m_pPrevInDatabase->protectCachedItem(); -#endif if (m_pNextInDatabase) { -#ifdef FLM_CACHE_PROTECT - m_pNextInDatabase->unprotectCachedItem(); -#endif m_pNextInDatabase->m_pPrevInDatabase = this; -#ifdef FLM_CACHE_PROTECT - m_pNextInDatabase->protectCachedItem(); -#endif } else { @@ -2794,9 +2412,6 @@ private: m_pDatabase = pDatabase; setLinkedToDatabase(); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Link a row to an F_Database list at the end of the list. @@ -2804,23 +2419,13 @@ private: FINLINE void linkToDatabaseAtEnd( F_Database * pDatabase) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - // Row cannot be a dirty row. flmAssert( !rowIsDirty()); m_pNextInDatabase = NULL; if( (m_pPrevInDatabase = pDatabase->m_pLastRow) != NULL) { -#ifdef FLM_CACHE_PROTECT - pDatabase->m_pLastRow->unprotectCachedItem(); -#endif pDatabase->m_pLastRow->m_pNextInDatabase = this; -#ifdef FLM_CACHE_PROTECT - pDatabase->m_pLastRow->protectCachedItem(); -#endif } else { @@ -2830,10 +2435,6 @@ private: pDatabase->m_pLastRow = this; m_pDatabase = pDatabase; setLinkedToDatabase(); - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Unlink a row from its F_Database list. @@ -2842,10 +2443,6 @@ private: { if( rowLinkedToDatabase()) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - // If this is the last dirty row, change the database's // last dirty pointer to point to the previous row, if any. @@ -2859,13 +2456,7 @@ private: if( m_pNextInDatabase) { -#ifdef FLM_CACHE_PROTECT - m_pNextInDatabase->unprotectCachedItem(); -#endif m_pNextInDatabase->m_pPrevInDatabase = m_pPrevInDatabase; -#ifdef FLM_CACHE_PROTECT - m_pNextInDatabase->protectCachedItem(); -#endif } else { @@ -2874,13 +2465,7 @@ private: if( m_pPrevInDatabase) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInDatabase->unprotectCachedItem(); -#endif m_pPrevInDatabase->m_pNextInDatabase = m_pNextInDatabase; -#ifdef FLM_CACHE_PROTECT - m_pPrevInDatabase->protectCachedItem(); -#endif } else { @@ -2891,10 +2476,6 @@ private: m_pNextInDatabase = NULL; m_pDatabase = NULL; unsetLinkedToDatabase(); - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } } @@ -2905,28 +2486,15 @@ private: F_Row ** ppHashBucket = gv_SFlmSysData.pRowCacheMgr->rowHash( m_ui64RowId); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - flmAssert( m_pNewerVersion == NULL); m_pPrevInBucket = NULL; if ((m_pNextInBucket = *ppHashBucket) != NULL) { -#ifdef FLM_CACHE_PROTECT - m_pNextInBucket->unprotectCachedItem(); -#endif m_pNextInBucket->m_pPrevInBucket = this; -#ifdef FLM_CACHE_PROTECT - m_pNextInBucket->protectCachedItem(); -#endif } -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif *ppHashBucket = this; } @@ -2934,32 +2502,16 @@ private: // Assumes that the row cache mutex has already been locked. FINLINE void unlinkFromHashBucket( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - flmAssert( m_pNewerVersion == NULL); if (m_pNextInBucket) { -#ifdef FLM_CACHE_PROTECT - m_pNextInBucket->unprotectCachedItem(); -#endif m_pNextInBucket->m_pPrevInBucket = m_pPrevInBucket; -#ifdef FLM_CACHE_PROTECT - m_pNextInBucket->protectCachedItem(); -#endif } if (m_pPrevInBucket) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInBucket->unprotectCachedItem(); -#endif m_pPrevInBucket->m_pNextInBucket = m_pNextInBucket; -#ifdef FLM_CACHE_PROTECT - m_pPrevInBucket->protectCachedItem(); -#endif } else { @@ -2972,10 +2524,6 @@ private: m_pPrevInBucket = NULL; m_pNextInBucket = NULL; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Unlink a row from its version list. @@ -2984,73 +2532,33 @@ private: F_Row * pNewerVer, F_Row * pOlderVer) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if( (m_pNewerVersion = pNewerVer) != NULL) { -#ifdef FLM_CACHE_PROTECT - pNewerVer->unprotectCachedItem(); -#endif pNewerVer->m_pOlderVersion = this; -#ifdef FLM_CACHE_PROTECT - pNewerVer->protectCachedItem(); -#endif } if ((m_pOlderVersion = pOlderVer) != NULL) { -#ifdef FLM_CACHE_PROTECT - pOlderVer->unprotectCachedItem(); -#endif pOlderVer->m_pNewerVersion = this; -#ifdef FLM_CACHE_PROTECT - pOlderVer->protectCachedItem(); -#endif } - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Unlink a row from its version list. This routine // Assumes that the row cache mutex has already been locked. FINLINE void unlinkFromVerList( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (m_pNewerVersion) { -#ifdef FLM_CACHE_PROTECT - m_pNewerVersion->unprotectCachedItem(); -#endif m_pNewerVersion->m_pOlderVersion = m_pOlderVersion; -#ifdef FLM_CACHE_PROTECT - m_pNewerVersion->protectCachedItem(); -#endif } if (m_pOlderVersion) { -#ifdef FLM_CACHE_PROTECT - m_pOlderVersion->unprotectCachedItem(); -#endif m_pOlderVersion->m_pNewerVersion = m_pNewerVersion; -#ifdef FLM_CACHE_PROTECT - m_pOlderVersion->protectCachedItem(); -#endif } m_pNewerVersion = NULL; m_pOlderVersion = NULL; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Link a row into the heap list @@ -3060,28 +2568,14 @@ private: flmAssert( !m_pPrevInHeapList); flmAssert( (m_uiFlags & FROW_HEAP_ALLOC) == 0); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if( (m_pNextInHeapList = gv_SFlmSysData.pRowCacheMgr->m_pHeapList) != NULL) { -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pHeapList->unprotectCachedItem(); -#endif gv_SFlmSysData.pRowCacheMgr->m_pHeapList->m_pPrevInHeapList = this; -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pHeapList->protectCachedItem(); -#endif } gv_SFlmSysData.pRowCacheMgr->m_pHeapList = this; m_uiFlags |= FROW_HEAP_ALLOC; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Unlink a row from the heap list @@ -3090,30 +2584,14 @@ private: { flmAssert( m_uiFlags & FROW_HEAP_ALLOC); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (m_pNextInHeapList) { -#ifdef FLM_CACHE_PROTECT - m_pNextInHeapList->unprotectCachedItem(); -#endif m_pNextInHeapList->m_pPrevInHeapList = m_pPrevInHeapList; -#ifdef FLM_CACHE_PROTECT - m_pNextInHeapList->protectCachedItem(); -#endif } if (m_pPrevInHeapList) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInHeapList->unprotectCachedItem(); -#endif m_pPrevInHeapList->m_pNextInHeapList = m_pNextInHeapList; -#ifdef FLM_CACHE_PROTECT - m_pPrevInHeapList->protectCachedItem(); -#endif } else { @@ -3123,10 +2601,6 @@ private: m_pPrevInHeapList = NULL; m_pNextInHeapList = NULL; m_uiFlags &= ~FROW_HEAP_ALLOC; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. @@ -3134,56 +2608,26 @@ private: { flmAssert( !m_pPrevInOldList); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if( (m_pNextInOldList = gv_SFlmSysData.pRowCacheMgr->m_pOldList) != NULL) { -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pOldList->unprotectCachedItem(); -#endif gv_SFlmSysData.pRowCacheMgr->m_pOldList->m_pPrevInOldList = this; -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pOldList->protectCachedItem(); -#endif } gv_SFlmSysData.pRowCacheMgr->m_pOldList = this; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } // Assumes that the row cache mutex has already been locked. FINLINE void unlinkFromOldList( void) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (m_pNextInOldList) { -#ifdef FLM_CACHE_PROTECT - m_pNextInOldList->unprotectCachedItem(); -#endif m_pNextInOldList->m_pPrevInOldList = m_pPrevInOldList; -#ifdef FLM_CACHE_PROTECT - m_pNextInOldList->protectCachedItem(); -#endif } if (m_pPrevInOldList) { -#ifdef FLM_CACHE_PROTECT - m_pPrevInOldList->unprotectCachedItem(); -#endif m_pPrevInOldList->m_pNextInOldList = m_pNextInOldList; -#ifdef FLM_CACHE_PROTECT - m_pPrevInOldList->protectCachedItem(); -#endif } else { @@ -3192,10 +2636,6 @@ private: m_pPrevInOldList = NULL; m_pNextInOldList = NULL; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } FINLINE FLMUINT memSize( void) @@ -3227,10 +2667,6 @@ private: { FLMUINT uiSize; -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (m_ui64HighTransId == FLM_MAX_UINT64 && ui64NewTransID != FLM_MAX_UINT64) { @@ -3251,9 +2687,6 @@ private: } m_ui64HighTransId = ui64NewTransID; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } void freePurged( void); diff --git a/sql/src/fdbcopy.cpp b/sql/src/fdbcopy.cpp index d927c80..edb8cee 100644 --- a/sql/src/fdbcopy.cpp +++ b/sql/src/fdbcopy.cpp @@ -228,7 +228,9 @@ RCODE F_DbSystem::copyDb( goto Exit; } - if (RC_BAD( rc = pSrcSFileHdl->setup( pSrcSFileClient))) + if (RC_BAD( rc = pSrcSFileHdl->setup( pSrcSFileClient, + gv_SFlmSysData.pFileHdlCache, gv_SFlmSysData.uiFileOpenFlags, + gv_SFlmSysData.uiFileCreateFlags))) { goto Exit; } @@ -352,7 +354,9 @@ retry: goto Exit; } - if (RC_BAD( rc = pDestSFileHdl->setup( pDestSFileClient))) + if (RC_BAD( rc = pDestSFileHdl->setup( pDestSFileClient, + gv_SFlmSysData.pFileHdlCache, gv_SFlmSysData.uiFileOpenFlags, + gv_SFlmSysData.uiFileCreateFlags))) { goto Exit; } @@ -469,8 +473,8 @@ retry: // Close all file handles in the source and destination - pSrcSFileHdl->releaseFiles( TRUE); - pDestSFileHdl->releaseFiles( TRUE); + pSrcSFileHdl->releaseFiles(); + pDestSFileHdl->releaseFiles(); // Copy the database files. @@ -822,7 +826,7 @@ FSTATIC RCODE flmCopyFile( // Read data from source file. - if (RC_BAD( rc = pSrcFileHdl->sectorRead( uiOffset, uiBytesToRead, + if (RC_BAD( rc = pSrcFileHdl->read( uiOffset, uiBytesToRead, pucBuffer, &uiBytesRead))) { if (rc == NE_FLM_IO_END_OF_FILE) diff --git a/sql/src/fdict.cpp b/sql/src/fdict.cpp index 4ad98e1..8aa3ba8 100644 --- a/sql/src/fdict.cpp +++ b/sql/src/fdict.cpp @@ -740,7 +740,7 @@ RCODE F_Dict::addEncDef( eEncAlgorithm eEncAlg, FLMUINT uiEncKeySize, FLMBYTE * pucEncKey, - FLMUINT uiEncKeyLen) + FLMUINT) // uiEncKeyLen) { RCODE rc = NE_SFLM_OK; F_ENCDEF * pEncDef; diff --git a/sql/src/fdict.h b/sql/src/fdict.h index 0dcbc66..0c61a47 100644 --- a/sql/src/fdict.h +++ b/sql/src/fdict.h @@ -166,7 +166,7 @@ typedef struct NAME_INFO { const char * pszName; FLMUINT uiItemNum; -}; +} NAME_INFO; /************************************************************************** Desc: This class is the name table class. diff --git a/sql/src/fdllmain.cpp b/sql/src/fdllmain.cpp index cf9f601..5fbce5f 100644 --- a/sql/src/fdllmain.cpp +++ b/sql/src/fdllmain.cpp @@ -86,8 +86,8 @@ FLMEXTC RCODE DllCanUnloadNow( void) if (gv_SFlmSysData.pDatabaseHashTbl) { - FBUCKET * pDatabaseHashTbl; - FLMUINT uiCnt; + F_BUCKET * pDatabaseHashTbl; + FLMUINT uiCnt; for (uiCnt = 0, pDatabaseHashTbl = gv_SFlmSysData.pDatabaseHashTbl; uiCnt < FILE_HASH_ENTRIES; diff --git a/sql/src/ffilehdr.cpp b/sql/src/ffilehdr.cpp index a167c56..8c02e5e 100644 --- a/sql/src/ffilehdr.cpp +++ b/sql/src/ffilehdr.cpp @@ -352,7 +352,13 @@ FSTATIC RCODE verifyDbHdr( switch (pDbHdr->ui32DbVersion) { + case SFLM_CURRENT_VERSION_NUM: + { + break; + } + default: + { if (pDbHdr->ui32DbVersion > SFLM_CURRENT_VERSION_NUM) { rc = RC_SET( NE_SFLM_NEWER_FLAIM); @@ -361,7 +367,9 @@ FSTATIC RCODE verifyDbHdr( { rc = RC_SET( NE_SFLM_UNSUPPORTED_VERSION); } + goto Exit; + } } // Validate the checksum diff --git a/sql/src/filesys.h b/sql/src/filesys.h index 749cfa1..873e13e 100644 --- a/sql/src/filesys.h +++ b/sql/src/filesys.h @@ -151,10 +151,6 @@ RCODE flmCreateLckFile( const char * pszFilePath, IF_FileHdl ** ppLockFileHdl); -RCODE flmAllocHashTbl( - FLMUINT uiHashTblSize, - FBUCKET ** ppHashTblRV); - RCODE flmWaitNotifyReq( F_MUTEX hMutex, F_SEM hSem, diff --git a/sql/src/flaimsys.h b/sql/src/flaimsys.h index 6b5398b..f60ac47 100644 --- a/sql/src/flaimsys.h +++ b/sql/src/flaimsys.h @@ -1181,17 +1181,17 @@ public: const void * pvBuffer, FLMUINT uiBytesToWrite); - virtual FLMINT getRefCount( void) + virtual FLMINT FLMAPI getRefCount( void) { return( IF_BackupClient::getRefCount()); } - virtual FLMINT AddRef( void) + virtual FLMINT FLMAPI AddRef( void) { return( IF_BackupClient::AddRef()); } - virtual FLMINT Release( void) + virtual FLMINT FLMAPI Release( void) { return( IF_BackupClient::Release()); } @@ -1237,17 +1237,17 @@ public: RCODE abortFile( void); - virtual FLMINT getRefCount( void) + virtual FLMINT FLMAPI getRefCount( void) { return( IF_RestoreClient::getRefCount()); } - virtual FLMINT AddRef( void) + virtual FLMINT FLMAPI AddRef( void) { return( IF_RestoreClient::AddRef()); } - virtual FLMINT Release( void) + virtual FLMINT FLMAPI Release( void) { return( IF_RestoreClient::Release()); } @@ -1456,17 +1456,17 @@ public: return( NE_SFLM_OK); } - virtual FLMINT getRefCount( void) + virtual FLMINT FLMAPI getRefCount( void) { return( IF_RestoreStatus::getRefCount()); } - virtual FLMINT AddRef( void) + virtual FLMINT FLMAPI AddRef( void) { return( IF_RestoreStatus::AddRef()); } - virtual FLMINT Release( void) + virtual FLMINT FLMAPI Release( void) { return( IF_RestoreStatus::Release()); } @@ -2707,7 +2707,7 @@ public: { } - FINLINE RCODE compare( + FINLINE RCODE FLMAPI compare( const void * pvKey1, FLMUINT uiKeyLen1, const void * pvKey2, @@ -2745,17 +2745,17 @@ public: m_pOldRow = pOldRow; } - virtual FLMINT getRefCount( void) + virtual FLMINT FLMAPI getRefCount( void) { return( IF_ResultSetCompare::getRefCount()); } - virtual FLMINT AddRef( void) + virtual FLMINT FLMAPI AddRef( void) { return( IF_ResultSetCompare::AddRef()); } - virtual FLMINT Release( void) + virtual FLMINT FLMAPI Release( void) { return( IF_ResultSetCompare::Release()); } @@ -2927,9 +2927,9 @@ public: { } - virtual FLMINT AddRef( void); + virtual FLMINT FLMAPI AddRef( void); - virtual FLMINT Release( void); + virtual FLMINT FLMAPI Release( void); RCODE init( void); @@ -3321,10 +3321,10 @@ private: const char * pszDestRflDir, IF_DbCopyStatus * ifpStatus); - static RCODE monitorThrd( + static RCODE FLMAPI monitorThrd( IF_Thread * pThread); - static RCODE cacheCleanupThrd( + static RCODE FLMAPI cacheCleanupThrd( IF_Thread * pThread); static void checkNotUsedObjects( void); @@ -3459,36 +3459,36 @@ public: FLMUINT32 ui32BlkAddr = 0, FLMUINT uiOffsetIndex = 0); - FINLINE FLMUINT64 totalSize( void) + FINLINE FLMUINT64 FLMAPI totalSize( void) { return( m_uiStreamSize); } - FINLINE FLMUINT64 remainingSize( void) + FINLINE FLMUINT64 FLMAPI remainingSize( void) { return( m_uiStreamSize - (m_uiBufferStartOffset + m_uiBufferOffset)); } - FINLINE RCODE close( void) + FINLINE RCODE FLMAPI close( void) { reset(); return( NE_SFLM_OK); } - RCODE positionTo( + RCODE FLMAPI positionTo( FLMUINT64 ui64Position); - FINLINE FLMUINT64 getCurrPosition( void) + FINLINE FLMUINT64 FLMAPI getCurrPosition( void) { return( m_uiBufferStartOffset + m_uiBufferOffset); } - RCODE read( + RCODE FLMAPI read( void * pvBuffer, FLMUINT uiBytesToRead, FLMUINT * puiBytesRead); - FLMINT Release( void); + FLMINT FLMAPI Release( void); FINLINE FLMUINT32 getBlkAddr( void) { @@ -4393,6 +4393,10 @@ public: FLMUINT FLMAPI getFileOffset( FLMUINT uiBlockAddr); + FLMUINT FLMAPI getBlockAddress( + FLMUINT uiFileNumber, + FLMUINT uiFileOffset); + RCODE FLMAPI getFilePath( FLMUINT uiFileNumber, char * pszPath); diff --git a/sql/src/flbackup.cpp b/sql/src/flbackup.cpp index 2eafa2e..d1e7a09 100644 --- a/sql/src/flbackup.cpp +++ b/sql/src/flbackup.cpp @@ -86,10 +86,10 @@ private: RCODE _setup( void); - static RCODE readThread( + static RCODE FLMAPI readThread( IF_Thread * pThread); - static RCODE writeThread( + static RCODE FLMAPI writeThread( IF_Thread * pThread); // Data @@ -1094,7 +1094,8 @@ RCODE F_DbSystem::dbRestore( goto Exit; } - if( RC_BAD( rc = pSFile->setup( &SFileClient))) + if( RC_BAD( rc = pSFile->setup( &SFileClient, gv_SFlmSysData.pFileHdlCache, + gv_SFlmSysData.uiFileOpenFlags, gv_SFlmSysData.uiFileCreateFlags))) { goto Exit; } @@ -1618,7 +1619,7 @@ FSTATIC RCODE flmRestoreFile( // Compare the incremental backup sequence number to the value in the // database's DB header. - if( RC_BAD( rc = pSFile->readHeader( 0, sizeof( SFLM_DB_HDR), + if( RC_BAD( rc = pSFile->readBlock( 0, sizeof( SFLM_DB_HDR), &dbHdr, &uiTmp))) { goto Exit; @@ -1680,7 +1681,7 @@ FSTATIC RCODE flmRestoreFile( // Write the database header - if( RC_BAD( rc = pSFile->writeHeader( 0, + if( RC_BAD( rc = pSFile->writeBlock( 0, uiBlockSize, pucBlkBuf, &uiBytesWritten))) { goto Exit; @@ -1754,22 +1755,8 @@ FSTATIC RCODE flmRestoreFile( // Write the block to the database -#ifdef FLM_UNIX - - // Unix systems can have sector sizes that are larger than our - // typical 4K database blocks. The Unix implementation of SectorWrite - // (called by WriteBlock) will write the passed-in block and clobber any - // additional data beyond the end of the block to the end of the sector if - // it has enough room in the block buffer to write a full sector. If the - // block buffer is less than a full sector, the Unix SectorWrite will only - // write out the amount requested, not a full sector. - if( RC_BAD( rc = pSFile->writeBlock( uiBlkAddr, - uiBlockSize, pucBlkBuf, NULL, &uiBytesWritten))) -#else - if( RC_BAD( rc = pSFile->writeBlock( uiBlkAddr, - uiBlockSize, pucBlkBuf, NULL, &uiBytesWritten))) -#endif + uiBlockSize, pucBlkBuf, &uiBytesWritten))) { if( rc == NE_FLM_IO_PATH_NOT_FOUND || rc == NE_FLM_IO_INVALID_FILENAME) @@ -1787,13 +1774,8 @@ FSTATIC RCODE flmRestoreFile( goto Exit; } -#ifdef FLM_UNIX if( RC_BAD( rc = pSFile->writeBlock( uiBlkAddr, - uiBlockSize, pucBlkBuf, NULL, &uiBytesWritten))) -#else - if( RC_BAD( rc = pSFile->writeBlock( uiBlkAddr, - uiBlockSize, pucBlkBuf, NULL, &uiBytesWritten))) -#endif + uiBlockSize, pucBlkBuf, &uiBytesWritten))) { goto Exit; } @@ -2512,7 +2494,7 @@ Exit: /**************************************************************************** Desc: This thread writes data in the background ****************************************************************************/ -RCODE F_BackerStream::writeThread( +RCODE FLMAPI F_BackerStream::writeThread( IF_Thread * pThread) { F_BackerStream * pBackerStream = (F_BackerStream *)pThread->getParm1(); diff --git a/sql/src/flclose.cpp b/sql/src/flclose.cpp index 7d0c877..20e2a04 100644 --- a/sql/src/flclose.cpp +++ b/sql/src/flclose.cpp @@ -131,7 +131,7 @@ RCODE F_DbSystem::waitToClose( const char * pszDbPath) { RCODE rc = NE_SFLM_OK; - FBUCKET * pBucket; + F_BUCKET * pBucket; FLMUINT uiBucket; F_Database * pDatabase = NULL; char szDbPathStr1[ F_PATH_MAX_SIZE]; diff --git a/sql/src/flconvrt.cpp b/sql/src/flconvrt.cpp index 5d5ef9a..a9a6afe 100644 --- a/sql/src/flconvrt.cpp +++ b/sql/src/flconvrt.cpp @@ -633,7 +633,9 @@ RCODE F_Db::rollOverDbKey( void) if (rc == NE_SFLM_EOF_HIT) { rc = NE_SFLM_OK; + break; } + goto Exit; } @@ -644,6 +646,7 @@ RCODE F_Db::rollOverDbKey( void) { goto Exit; } + if (bIsNull) { rc = RC_SET_AND_ASSERT( NE_SFLM_NULL_ENCDEF_NUM); diff --git a/sql/src/flerror.cpp b/sql/src/flerror.cpp index 927943d..ffb89c4 100644 --- a/sql/src/flerror.cpp +++ b/sql/src/flerror.cpp @@ -118,6 +118,9 @@ RCODE flmMakeErr( int iLine, FLMBOOL bAssert) { + F_UNREFERENCED_PARM( pszFile); + F_UNREFERENCED_PARM( iLine); + if( bAssert) { flmAssert( 0); diff --git a/sql/src/flindex.cpp b/sql/src/flindex.cpp index a71c97e..913f8b1 100644 --- a/sql/src/flindex.cpp +++ b/sql/src/flindex.cpp @@ -25,7 +25,7 @@ #include "flaimsys.h" -FSTATIC RCODE flmBackgroundIndexBuildThrd( +FSTATIC RCODE FLMAPI flmBackgroundIndexBuildThrd( IF_Thread * pThread); /**************************************************************************** @@ -816,7 +816,6 @@ RCODE F_Db::backgroundIndexBuild( m_uiFlags |= FDB_BACKGROUND_INDEXING; uiIndexNum = pBackgroundIx->indexStatus.uiIndexNum; - m_pSFileHdl->enableFlushMinimize(); for (;;) { @@ -909,8 +908,6 @@ RCODE F_Db::backgroundIndexBuild( goto Exit; } - pThread->setThreadStatus( FLM_THREAD_STATUS_COMMITTING_TRANS); - // Commit the transaction (even if we didn't do any indexing work). bStartedTrans = FALSE; @@ -943,7 +940,7 @@ Desc: Thread that will build an index in the background. Caller will create a pDb to use. This pDb must be freed at the conclusion of the routine. ****************************************************************************/ -FSTATIC RCODE flmBackgroundIndexBuildThrd( +FSTATIC RCODE FLMAPI flmBackgroundIndexBuildThrd( IF_Thread * pThread) { RCODE rc = NE_SFLM_OK; diff --git a/sql/src/flreduce.cpp b/sql/src/flreduce.cpp index 809171a..36843c3 100644 --- a/sql/src/flreduce.cpp +++ b/sql/src/flreduce.cpp @@ -414,8 +414,7 @@ RCODE F_Db::readBlkHdr( { if (rc != NE_FLM_IO_END_OF_FILE && rc != NE_SFLM_MEM) { - m_pSFileHdl->releaseFile( FSGetFileNumber( uiBlkAddress), - TRUE); + m_pSFileHdl->releaseFiles(); } goto Exit; } diff --git a/sql/src/frow.cpp b/sql/src/frow.cpp index 13be9f6..5a9e882 100644 --- a/sql/src/frow.cpp +++ b/sql/src/frow.cpp @@ -93,10 +93,6 @@ F_Row::F_Row() m_uiTableNum = 0; m_ui64RowId = 0; - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } /**************************************************************************** @@ -180,10 +176,6 @@ void F_Row::freePurged( void) unsetPurged(); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - delete this; } @@ -235,25 +227,13 @@ void F_Row::freeCache( if (!bPutInPurgeList) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif delete this; } else { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif if ((m_pNextInGlobal = gv_SFlmSysData.pRowCacheMgr->m_pPurgeList) != NULL) { -#ifdef FLM_CACHE_PROTECT - m_pNextInGlobal->unprotectCachedItem(); -#endif m_pNextInGlobal->m_pPrevInGlobal = this; -#ifdef FLM_CACHE_PROTECT - m_pNextInGlobal->protectCachedItem(); -#endif } gv_SFlmSysData.pRowCacheMgr->m_pPurgeList = this; @@ -262,9 +242,6 @@ void F_Row::freeCache( m_uiFlags &= ~(FROW_DIRTY | FROW_NEW); setPurged(); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif flmAssert( !m_pPrevInGlobal); } } @@ -297,7 +274,7 @@ RCODE F_RowCacheMgr::initCache( void) // Set up the F_Row object allocator if (RC_BAD( rc = m_pRowAllocator->setup( - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, + TRUE, gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, &m_rowRelocator, sizeof( F_Row), &m_Usage.slabUsage, NULL))) { goto Exit; @@ -311,7 +288,7 @@ RCODE F_RowCacheMgr::initCache( void) // Set up the buffer allocator for F_Row objects if (RC_BAD( rc = m_pBufAllocator->setup( - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, NULL, + TRUE, gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, NULL, &m_Usage.slabUsage, NULL))) { goto Exit; @@ -377,134 +354,62 @@ void F_RowRelocator::relocate( if (pNewRow->m_pPrevInDatabase) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInDatabase->unprotectCachedItem(); -#endif pNewRow->m_pPrevInDatabase->m_pNextInDatabase = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInDatabase->protectCachedItem(); -#endif } if (pNewRow->m_pNextInDatabase) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInDatabase->unprotectCachedItem(); -#endif pNewRow->m_pNextInDatabase->m_pPrevInDatabase = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInDatabase->protectCachedItem(); -#endif } if (pNewRow->m_pPrevInGlobal) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInGlobal->unprotectCachedItem(); -#endif pNewRow->m_pPrevInGlobal->m_pNextInGlobal = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInGlobal->protectCachedItem(); -#endif } if (pNewRow->m_pNextInGlobal) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInGlobal->unprotectCachedItem(); -#endif pNewRow->m_pNextInGlobal->m_pPrevInGlobal = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInGlobal->protectCachedItem(); -#endif } if (pNewRow->m_pPrevInBucket) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInBucket->unprotectCachedItem(); -#endif pNewRow->m_pPrevInBucket->m_pNextInBucket = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInBucket->protectCachedItem(); -#endif } if (pNewRow->m_pNextInBucket) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInBucket->unprotectCachedItem(); -#endif pNewRow->m_pNextInBucket->m_pPrevInBucket = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInBucket->protectCachedItem(); -#endif } if (pNewRow->m_pOlderVersion) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pOlderVersion->unprotectCachedItem(); -#endif pNewRow->m_pOlderVersion->m_pNewerVersion = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pOlderVersion->protectCachedItem(); -#endif } if (pNewRow->m_pNewerVersion) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNewerVersion->unprotectCachedItem(); -#endif pNewRow->m_pNewerVersion->m_pOlderVersion = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNewerVersion->protectCachedItem(); -#endif } if (pNewRow->m_pPrevInHeapList) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInHeapList->unprotectCachedItem(); -#endif pNewRow->m_pPrevInHeapList->m_pNextInHeapList = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInHeapList->protectCachedItem(); -#endif } if (pNewRow->m_pNextInHeapList) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInHeapList->unprotectCachedItem(); -#endif pNewRow->m_pNextInHeapList->m_pPrevInHeapList = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInHeapList->protectCachedItem(); -#endif } if (pNewRow->m_pPrevInOldList) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInOldList->unprotectCachedItem(); -#endif pNewRow->m_pPrevInOldList->m_pNextInOldList = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pPrevInOldList->protectCachedItem(); -#endif } if (pNewRow->m_pNextInOldList) { -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInOldList->unprotectCachedItem(); -#endif pNewRow->m_pNextInOldList->m_pPrevInOldList = pNewRow; -#ifdef FLM_CACHE_PROTECT - pNewRow->m_pNextInOldList->protectCachedItem(); -#endif } if( pDatabase) @@ -1499,14 +1404,7 @@ RCODE F_Row::resizeDataBuffer( flmAssert( *((F_Row **)pucActualAlloc) == this); setRowAndDataPtr( pucActualAlloc); -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif m_uiColumnDataBufSize = uiSize; -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif - uiNewSize = memSize(); if (m_ui64HighTransId != FLM_MAX_UINT64) @@ -1552,20 +1450,12 @@ RCODE F_Row::resizeColumnList( FLMBYTE * pucActualAlloc; FLMBOOL bHeapAlloc = FALSE; void * pvThis = this; -#ifdef FLM_CACHE_PROTECT - FLMBOOL bProtectRow = FALSE; -#endif if( uiColumnCount == m_uiNumColumns) { goto Exit; } -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); - bProtectRow = TRUE; -#endif - if( !bMutexAlreadyLocked) { flmAssert( rowInUse()); @@ -1657,13 +1547,6 @@ RCODE F_Row::resizeColumnList( Exit: -#ifdef FLM_CACHE_PROTECT - if( bProtectRow) - { - protectCachedItem(); - } -#endif - return( rc); } @@ -2248,10 +2131,6 @@ RCODE F_Row::flushRow( f_mutexLock( gv_SFlmSysData.hRowCacheMutex); bMutexLocked = TRUE; -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - incrRowUseCount(); f_mutexUnlock( gv_SFlmSysData.hRowCacheMutex); bMutexLocked = FALSE; @@ -2262,9 +2141,6 @@ RCODE F_Row::flushRow( bMutexLocked = TRUE; decrRowUseCount(); -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif if( RC_BAD( rc)) { @@ -2368,7 +2244,7 @@ Desc: RCODE F_Row::readRow( F_Db * pDb, FLMUINT uiTableNum, - FLMUINT64 ui64RowId, + FLMUINT64, // ui64RowId, IF_IStream * pIStream, FLMUINT uiRowDataLength) { @@ -2693,10 +2569,6 @@ Start_Find: goto Exit; } -#ifdef FLM_CACHE_PROTECT - pRow->unprotectCachedItem(); -#endif - pRow->m_ui64RowId = ui64RowId; pRow->m_uiTableNum = uiTableNum; @@ -2754,9 +2626,6 @@ Start_Find: : pRow), rc); } pRow->decrRowUseCount(); -#ifdef FLM_CACHE_PROTECT - pRow->protectCachedItem(); -#endif // If we did not succeed, free the F_Row structure. @@ -2839,10 +2708,6 @@ RCODE F_RowCacheMgr::createRow( goto Exit; } -#ifdef FLM_CACHE_PROTECT - pRow->unprotectCachedItem(); -#endif - pRow->m_ui64RowId = pTable->lfInfo.ui64NextRowId; pTable->lfInfo.ui64NextRowId++; pTable->lfInfo.bNeedToWriteOut = TRUE; @@ -2874,10 +2739,6 @@ RCODE F_RowCacheMgr::createRow( *ppRow = pRow; pRow->incrRowUseCount(); -#ifdef FLM_CACHE_PROTECT - pRow->protectCachedItem(); -#endif - Exit: if (bMutexLocked) @@ -2900,9 +2761,6 @@ RCODE F_RowCacheMgr::_makeWriteCopy( F_Row * pNewerRow = NULL; F_Row * pOlderRow = *ppRow; FLMBOOL bMutexLocked = FALSE; -#ifdef FLM_CACHE_PROTECT - FLMBOOL bProtectNewerRow = FALSE; -#endif flmAssert( pOlderRow->m_ui64HighTransId == FLM_MAX_UINT64); flmAssert( !pOlderRow->m_pNewerVersion); @@ -2935,11 +2793,6 @@ RCODE F_RowCacheMgr::_makeWriteCopy( pOlderRow->unlinkFromDatabase(); pOlderRow->linkToDatabaseAtHead( pDatabase); -#ifdef FLM_CACHE_PROTECT - pNewerRow->unprotectCachedItem(); - bProtectNewerRow = TRUE; -#endif - pNewerRow->m_pDatabase = pDatabase; pNewerRow->m_uiFlags = pOlderRow->m_uiFlags; pNewerRow->m_uiOffsetIndex = pOlderRow->m_uiOffsetIndex; @@ -2989,11 +2842,6 @@ RCODE F_RowCacheMgr::_makeWriteCopy( *ppRow = pNewerRow; pNewerRow->incrRowUseCount(); -#ifdef FLM_CACHE_PROTECT - pNewerRow->protectCachedItem(); - bProtectNewerRow = FALSE; -#endif - // Set pNewerRow to NULL so it won't get freed at Exit pNewerRow = NULL; @@ -3491,7 +3339,7 @@ Exit: Desc: ******************************************************************************/ RCODE F_Row::getBinary( - F_Db * pDb, + F_Db *, // pDb, FLMUINT uiColumnNum, void * pvBuffer, FLMUINT uiBufferLen, @@ -3567,7 +3415,7 @@ void F_Row::setToNull( Desc: ******************************************************************************/ void F_Row::getDataLen( - F_Db * pDb, + F_Db *, // pDb, FLMUINT uiColumnNum, FLMUINT * puiDataLen, FLMBOOL * pbIsNull) @@ -4260,10 +4108,6 @@ void F_Row::setRowDirty( F_Db * pDb, FLMBOOL bNew) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - if (!rowIsDirty()) { f_mutexLock( gv_SFlmSysData.hRowCacheMutex); @@ -4303,10 +4147,6 @@ void F_Row::setRowDirty( { m_uiFlags |= FROW_NEW; } - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } /**************************************************************************** @@ -4316,10 +4156,6 @@ void F_Row::unsetRowDirtyAndNew( F_Db * pDb, FLMBOOL bMutexAlreadyLocked) { -#ifdef FLM_CACHE_PROTECT - unprotectCachedItem(); -#endif - // When outputting a binary or text stream, it is possible that the // dirty flag was unset when the last buffer was output @@ -4348,10 +4184,6 @@ void F_Row::unsetRowDirtyAndNew( f_mutexUnlock( gv_SFlmSysData.hRowCacheMutex); } } - -#ifdef FLM_CACHE_PROTECT - protectCachedItem(); -#endif } /***************************************************************************** @@ -4486,14 +4318,8 @@ void * F_Row::operator new( flmAssert( uiSize == sizeof( F_Row)); f_assertMutexLocked( gv_SFlmSysData.hRowCacheMutex); - if( (pvCell = - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->allocCell( - &gv_SFlmSysData.pRowCacheMgr->m_rowRelocator)) != NULL) - { -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->unprotectCell( pvCell); -#endif - } + pvCell = gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->allocCell( + &gv_SFlmSysData.pRowCacheMgr->m_rowRelocator, NULL); return( pvCell); } @@ -4556,10 +4382,7 @@ void F_Row::operator delete( return; } -#ifdef FLM_CACHE_PROTECT - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->protectCell( ptr); -#endif - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->freeCell( (FLMBYTE *)ptr, FALSE); + gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->freeCell( (FLMBYTE *)ptr); } /**************************************************************************** @@ -4587,7 +4410,7 @@ void F_Row::operator delete( return; } - gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->freeCell( (FLMBYTE *)ptr, FALSE); + gv_SFlmSysData.pRowCacheMgr->m_pRowAllocator->freeCell( (FLMBYTE *)ptr); } #endif diff --git a/sql/src/fslfileu.cpp b/sql/src/fslfileu.cpp index da778e0..a0191e3 100644 --- a/sql/src/fslfileu.cpp +++ b/sql/src/fslfileu.cpp @@ -796,7 +796,7 @@ Exit: Desc: Thread that will delete block chains from deleted indexes and tables in the background. ****************************************************************************/ -RCODE F_Database::maintenanceThread( +RCODE FLMAPI F_Database::maintenanceThread( IF_Thread * pThread) { RCODE rc = NE_SFLM_OK; @@ -855,62 +855,59 @@ Retry: { pThread->setThreadStatus( FLM_THREAD_STATUS_RUNNING); - for( ;;) + if( RC_BAD( rc = pDb->beginBackgroundTrans( pThread))) { - if( RC_BAD( rc = pDb->beginBackgroundTrans( pThread))) - { - goto Exit; - } - bStartedTrans = TRUE; - - pTableCursor->resetCursor(); - if (RC_BAD( rc = pTableCursor->setupRange( pDb, SFLM_TBLNUM_BLOCK_CHAINS, - 1, FLM_MAX_UINT64, NULL, NULL, NULL))) - { - goto Exit; - } + goto Exit; + } + bStartedTrans = TRUE; - // Free up to 25 blocks per transaction. - - uiBlocksToFree = 25; - while (uiBlocksToFree) - { - - if (RC_BAD( rc = pTableCursor->nextRow( pDb, &pRow, &ui64MaintRowId))) - { - if (rc != NE_SFLM_EOF_HIT) - { - RC_UNEXPECTED_ASSERT( rc); - goto Exit; - } - rc = NE_SFLM_OK; - break; - } - if (RC_BAD( rc = pRow->getUINT( pDb, - SFLM_COLNUM_BLOCK_CHAINS_BLOCK_ADDRESS, &uiBlkAddress, - &bIsNull))) - { - goto Exit; - } - if (bIsNull) - { - rc = RC_SET_AND_ASSERT( NE_SFLM_DATA_ERROR); - goto Exit; - } - - if( RC_BAD( rc = pDb->maintBlockChainFree( - ui64MaintRowId, uiBlkAddress, uiBlocksToFree, 0, &uiBlocksFreed))) - { - goto Exit; - } - uiBlocksToFree -= uiBlocksFreed; - } + pTableCursor->resetCursor(); + if (RC_BAD( rc = pTableCursor->setupRange( pDb, SFLM_TBLNUM_BLOCK_CHAINS, + 1, FLM_MAX_UINT64, NULL, NULL, NULL))) + { + goto Exit; + } + + // Free up to 25 blocks per transaction. + + uiBlocksToFree = 25; + while (uiBlocksToFree) + { - bStartedTrans = FALSE; - if( RC_BAD( rc = pDb->commitTrans( 0, FALSE))) + if (RC_BAD( rc = pTableCursor->nextRow( pDb, &pRow, &ui64MaintRowId))) + { + if (rc != NE_SFLM_EOF_HIT) + { + RC_UNEXPECTED_ASSERT( rc); + goto Exit; + } + rc = NE_SFLM_OK; + break; + } + if (RC_BAD( rc = pRow->getUINT( pDb, + SFLM_COLNUM_BLOCK_CHAINS_BLOCK_ADDRESS, &uiBlkAddress, + &bIsNull))) { goto Exit; } + if (bIsNull) + { + rc = RC_SET_AND_ASSERT( NE_SFLM_DATA_ERROR); + goto Exit; + } + + if( RC_BAD( rc = pDb->maintBlockChainFree( + ui64MaintRowId, uiBlkAddress, uiBlocksToFree, 0, &uiBlocksFreed))) + { + goto Exit; + } + uiBlocksToFree -= uiBlocksFreed; + } + + bStartedTrans = FALSE; + if( RC_BAD( rc = pDb->commitTrans( 0, FALSE))) + { + goto Exit; } pThread->setThreadStatus( FLM_THREAD_STATUS_SLEEPING); diff --git a/sql/src/fstructs.h b/sql/src/fstructs.h index 947a4be..4ce2197 100644 --- a/sql/src/fstructs.h +++ b/sql/src/fstructs.h @@ -857,13 +857,6 @@ private: F_SuperFileHdl * pSFileHdl, FLMUINT * puiBlocksFlushed); - RCODE writeContiguousBlocks( - SFLM_DB_STATS * pDbStats, - F_SuperFileHdl * pSFileHdl, - IF_IOBuffer * pIOBuffer, - FLMUINT uiBlkAddress, - FLMBOOL bDoAsync); - RCODE writeSortedBlocks( SFLM_DB_STATS * pDbStats, F_SuperFileHdl * pSFileHdl, @@ -871,7 +864,6 @@ private: FLMUINT * puiDirtyCacheLeft, FLMBOOL * pbForceCheckpoint, FLMBOOL bIsCPThread, - FLMBOOL bDoAsync, FLMUINT uiNumSortedBlocks, FLMBOOL * pbWroteAll); @@ -909,15 +901,13 @@ private: RCODE lgFlushLogBuffer( SFLM_DB_STATS * pDbStats, - F_SuperFileHdl * pSFileHdl, - FLMBOOL bDoAsync); + F_SuperFileHdl * pSFileHdl); RCODE lgOutputBlock( SFLM_DB_STATS * pDbStats, F_SuperFileHdl * pSFileHdl, F_CachedBlock * pLogBlock, F_BLK_HDR * pBlkHdr, - FLMBOOL bDoAsync, FLMUINT * puiLogEofRV); FLMUINT lFileFindEmpty( @@ -947,7 +937,7 @@ private: FLMBOOL bCounts, FLMBOOL bHaveData); - static RCODE maintenanceThread( + static RCODE FLMAPI maintenanceThread( IF_Thread * pThread); F_Database * m_pNext; // Next F_Database structure in in name hash @@ -1192,7 +1182,7 @@ Desc: This is the FLAIM Shared System Data Structure. It is the anchor ***************************************************************************/ typedef struct FLMSYSDATA { - FBUCKET * pDatabaseHashTbl; // Database name hash table (array of FBUCKET). + F_BUCKET * pDatabaseHashTbl; // Database name hash table #define FILE_HASH_ENTRIES 256 F_MUTEX hShareMutex; // Mutex for controlling access to @@ -1266,37 +1256,6 @@ typedef struct FLMSYSDATA FLMUINT uiLinuxRevision; #endif -#ifdef FLM_DEBUG - // Variables for memory allocation tracking. - - FLMBOOL bTrackLeaks; - FLMBOOL bLogLeaks; - FLMBOOL bStackWalk; - FLMBOOL bMemTrackingInitialized; - FLMUINT uiInitThreadId; - F_MUTEX hMemTrackingMutex; - void ** ppvMemTrackingPtrs; - FLMUINT uiMemTrackingPtrArraySize; - FLMUINT uiMemNumPtrs; - FLMUINT uiMemNextPtrSlotToUse; - FLMUINT uiAllocCnt; - #if defined( FLM_WIN) - HANDLE hMemProcess; - #endif - - #ifdef DEBUG_SIM_OUT_OF_MEM - FLMUINT uiOutOfMemSimEnabledFlag; - // We pick a random number for the flag so that it is hard to accidentally - // turn this flag on by writing memory out-of-bounds. - - #define OUT_OF_MEM_SIM_ENABLED_FLAG 2149614134UL - - F_RandomGenerator memSimRandomGen; - FLMUINT uiSimOutOfMemFailTotal; - FLMUINT uiSimOutOfMemFailSequence; - #endif -#endif - IF_FileSystem * pFileSystem; F_MUTEX hIniMutex; IF_ThreadMgr * pThreadMgr; @@ -1304,9 +1263,9 @@ typedef struct FLMSYSDATA FLMUINT uiCheckpointThreadGroup; F_MUTEX hHttpSessionMutex; F_BtPool * pBtPool; -#ifdef FLM_NLM - FLMBOOL bUseNSSFileHdls; -#endif + IF_FileHdlCache * pFileHdlCache; + FLMUINT uiFileOpenFlags; + FLMUINT uiFileCreateFlags; } FLMSYSDATA; #ifndef ALLOCATE_SYS_DATA diff --git a/sql/src/fsysdata.cpp b/sql/src/fsysdata.cpp index 6ba7bb6..27892e7 100644 --- a/sql/src/fsysdata.cpp +++ b/sql/src/fsysdata.cpp @@ -95,69 +95,6 @@ FSTATIC RCODE flmGetIniFileName( FLMBYTE * pszIniFileName, FLMUINT uiBufferSz); -/**************************************************************************** -Desc: This routine allocates and initializes a hash table. -****************************************************************************/ -RCODE flmAllocHashTbl( - FLMUINT uiHashTblSize, - FBUCKET ** ppHashTblRV) -{ - RCODE rc = NE_SFLM_OK; - FBUCKET * pHashTbl = NULL; - IF_RandomGenerator * pRandGen = NULL; - FLMUINT uiCnt; - FLMUINT uiRandVal; - FLMUINT uiTempVal; - - // Allocate memory for the hash table - - if (RC_BAD( rc = f_calloc( - (FLMUINT)(sizeof( FBUCKET)) * uiHashTblSize, &pHashTbl))) - { - goto Exit; - } - - // Set up the random number generator - - if( RC_BAD( rc = FlmAllocRandomGenerator( &pRandGen))) - { - goto Exit; - } - - pRandGen->setSeed( 1); - - for (uiCnt = 0; uiCnt < uiHashTblSize; uiCnt++) - { - pHashTbl [uiCnt].uiHashValue = (FLMBYTE)uiCnt; - pHashTbl [uiCnt].pFirstInBucket = NULL; - } - - if( uiHashTblSize <= 256) - { - for( uiCnt = 0; uiCnt < uiHashTblSize - 1; uiCnt++) - { - uiRandVal = (FLMBYTE) pRandGen->getUINT32( (FLMUINT32)uiCnt, - (FLMUINT32)(uiHashTblSize - 1)); - if( uiRandVal != uiCnt) - { - uiTempVal = (FLMBYTE)pHashTbl [uiCnt].uiHashValue; - pHashTbl [uiCnt].uiHashValue = pHashTbl [uiRandVal].uiHashValue; - pHashTbl [uiRandVal].uiHashValue = uiTempVal; - } - } - } - -Exit: - - if( pRandGen) - { - pRandGen->Release(); - } - - *ppHashTblRV = pHashTbl; - return( rc); -} - /**************************************************************************** Desc: This routine determines the number of cache bytes to use for caching based on a percentage of available physical memory or a percentage @@ -669,7 +606,7 @@ RCODE F_Database::linkToBucket( void) { RCODE rc = NE_SFLM_OK; F_Database * pTmpDatabase; - FBUCKET * pBucket; + F_BUCKET * pBucket; FLMUINT uiBucket; pBucket = gv_SFlmSysData.pDatabaseHashTbl; @@ -751,7 +688,9 @@ RCODE F_Db::linkToDatabase( goto Exit; } - if( RC_BAD( rc = m_pSFileHdl->setup( pSFileClient))) + if( RC_BAD( rc = m_pSFileHdl->setup( pSFileClient, + gv_SFlmSysData.pFileHdlCache, gv_SFlmSysData.uiFileOpenFlags, + gv_SFlmSysData.uiFileCreateFlags))) { goto Exit; } @@ -874,7 +813,7 @@ Desc: This routine functions as a thread. It monitors open files and frees up files which have been closed longer than the maximum close time. ****************************************************************************/ -RCODE F_DbSystem::monitorThrd( +RCODE FLMAPI F_DbSystem::monitorThrd( IF_Thread * pThread) { FLMUINT uiLastUnusedCleanupTime = 0; @@ -1168,59 +1107,52 @@ RCODE F_GlobalCacheMgr::setCacheLimit( FLMUINT uiNewTotalCacheSize, FLMBOOL bPreallocateCache) { - RCODE rc = NE_SFLM_OK; + RCODE rc = NE_FLM_OK; + FLMUINT uiOldCacheSize = m_uiMaxBytes; if( uiNewTotalCacheSize > FLM_MAX_CACHE_SIZE) { uiNewTotalCacheSize = FLM_MAX_CACHE_SIZE; } - if( m_bDynamicCacheAdjust || !bPreallocateCache) + if( bPreallocateCache) { -DONT_PREALLOCATE: - - if( uiNewTotalCacheSize < m_uiMaxBytes) + if( m_bDynamicCacheAdjust) { - m_uiMaxBytes = uiNewTotalCacheSize; - m_uiMaxSlabs = m_uiMaxBytes / m_pSlabManager->getSlabSize(); - f_mutexLock( gv_SFlmSysData.hRowCacheMutex); - gv_SFlmSysData.pRowCacheMgr->reduceCache(); - f_mutexUnlock( gv_SFlmSysData.hRowCacheMutex); - - f_mutexLock( gv_SFlmSysData.hBlockCacheMutex); - rc = gv_SFlmSysData.pBlockCacheMgr->reduceCache( NULL); - f_mutexUnlock( gv_SFlmSysData.hBlockCacheMutex); - if( RC_BAD( rc)) - { - goto Exit; - } + // Can't pre-allocate and dynamically adjust. + + bPreallocateCache = FALSE; } else { - if( RC_BAD( rc = m_pSlabManager->resize( 0))) + if( RC_BAD( rc = m_pSlabManager->resize( + uiNewTotalCacheSize, TRUE, &uiNewTotalCacheSize))) { - goto Exit; + bPreallocateCache = FALSE; } } - - m_bCachePreallocated = FALSE; } - else - { - if( RC_BAD( m_pSlabManager->resize( - uiNewTotalCacheSize, &uiNewTotalCacheSize))) - { - goto DONT_PREALLOCATE; - } - - m_bCachePreallocated = TRUE; - } - + m_uiMaxBytes = uiNewTotalCacheSize; m_uiMaxSlabs = m_uiMaxBytes / m_pSlabManager->getSlabSize(); + m_bCachePreallocated = bPreallocateCache; + + if( uiNewTotalCacheSize < uiOldCacheSize) + { + f_mutexLock( gv_SFlmSysData.hRowCacheMutex); + gv_SFlmSysData.pRowCacheMgr->reduceCache(); + f_mutexUnlock( gv_SFlmSysData.hRowCacheMutex); + + f_mutexLock( gv_SFlmSysData.hBlockCacheMutex); + gv_SFlmSysData.pBlockCacheMgr->reduceCache( NULL); + f_mutexUnlock( gv_SFlmSysData.hBlockCacheMutex); + } + + if( !bPreallocateCache) + { + m_pSlabManager->resize( uiNewTotalCacheSize, FALSE); + } -Exit: - return( rc); } @@ -1313,6 +1245,14 @@ RCODE F_DbSystem::init( void) goto Exit; } + // Set up a file handle cache + + if( RC_BAD( rc = gv_SFlmSysData.pFileSystem->allocFileHandleCache( 32, 120, + &gv_SFlmSysData.pFileHdlCache))) + { + goto Exit; + } + gv_SFlmSysData.uiIndexingThreadGroup = gv_SFlmSysData.pThreadMgr->allocGroupId(); @@ -1325,14 +1265,6 @@ RCODE F_DbSystem::init( void) flmAssert( FB2UD( (FLMBYTE *)"\x0A\x0B\x0C\x0D") == 0x0D0C0B0A); flmAssert( FB2UW( (FLMBYTE *)"\x0A\x0B") == 0x0B0A); -#ifdef FLM_DEBUG - - // Variables for memory allocation tracking. - - gv_SFlmSysData.bTrackLeaks = TRUE; - gv_SFlmSysData.hMemTrackingMutex = F_MUTEX_NULL; -#endif - gv_SFlmSysData.hRowCacheMutex = F_MUTEX_NULL; gv_SFlmSysData.hBlockCacheMutex = F_MUTEX_NULL; gv_SFlmSysData.hShareMutex = F_MUTEX_NULL; @@ -1356,6 +1288,12 @@ RCODE F_DbSystem::init( void) goto Exit; } + gv_SFlmSysData.uiFileOpenFlags = + FLM_IO_RDWR | FLM_IO_SH_DENYNONE | FLM_IO_DIRECT | FLM_IO_MISALIGNED_OK; + + gv_SFlmSysData.uiFileCreateFlags = + gv_SFlmSysData.uiFileOpenFlags | FLM_IO_EXCL | FLM_IO_CREATE_DIR; + // Initialize all of the fields gv_SFlmSysData.uiMaxUnusedTime = FLM_SECS_TO_TIMER_UNITS( @@ -1440,7 +1378,7 @@ RCODE F_DbSystem::init( void) // Allocate memory for the file name hash table. - if (RC_BAD(rc = flmAllocHashTbl( FILE_HASH_ENTRIES, + if (RC_BAD(rc = f_allocHashTable( FILE_HASH_ENTRIES, &gv_SFlmSysData.pDatabaseHashTbl))) { goto Exit; @@ -1614,6 +1552,14 @@ void F_DbSystem::cleanup( void) gv_SFlmSysData.pCacheCleanupThrd = NULL; } + // Release the file handle cache + + if( gv_SFlmSysData.pFileHdlCache) + { + gv_SFlmSysData.pFileHdlCache->Release(); + gv_SFlmSysData.pFileHdlCache = NULL; + } + // Release the thread manager if( gv_SFlmSysData.pThreadMgr) @@ -1626,7 +1572,7 @@ void F_DbSystem::cleanup( void) if (gv_SFlmSysData.pDatabaseHashTbl) { - FBUCKET * pDatabaseHashTbl; + F_BUCKET * pDatabaseHashTbl; // F_Database destructor expects the global mutex to be locked // IMPORTANT NOTE: pDatabaseHashTbl is ALWAYS allocated diff --git a/sql/src/kybuild.cpp b/sql/src/kybuild.cpp index abcbde2..6fd45ab 100644 --- a/sql/src/kybuild.cpp +++ b/sql/src/kybuild.cpp @@ -448,7 +448,7 @@ Exit: Desc: Generate the keys for a text component. ****************************************************************************/ RCODE F_Db::genTextKeyComponents( - F_COLUMN * pColumn, + F_COLUMN *, // pColumn, ICD * pIcd, FLMUINT uiKeyComponent, FLMUINT uiKeyLen, @@ -752,10 +752,10 @@ Exit: Desc: Generate the keys for other data types besides text. ****************************************************************************/ RCODE F_Db::genOtherKeyComponent( - F_COLUMN * pColumn, - ICD * pIcd, - FLMUINT uiKeyComponent, - FLMUINT uiKeyLen) + F_COLUMN *, // pColumn, + ICD * pIcd, + FLMUINT uiKeyComponent, + FLMUINT uiKeyLen) { RCODE rc = NE_SFLM_OK; FLMUINT uiElmLen; diff --git a/sql/src/opendatabase.cpp b/sql/src/opendatabase.cpp index b296107..cda6cfd 100644 --- a/sql/src/opendatabase.cpp +++ b/sql/src/opendatabase.cpp @@ -30,7 +30,7 @@ FSTATIC void flmFreeCPInfo( CP_INFO ** ppCPInfoRV); -FSTATIC RCODE flmCPThread( +FSTATIC RCODE FLMAPI flmCPThread( IF_Thread * pThread); /*************************************************************************** @@ -753,7 +753,7 @@ Exit: if (RC_BAD( rc)) { - (void)pDb->m_pSFileHdl->releaseFiles( TRUE); + (void)pDb->m_pSFileHdl->releaseFiles(); } return( rc); @@ -799,7 +799,7 @@ RCODE F_DbSystem::findDatabase( F_Database ** ppDatabase) { RCODE rc = NE_SFLM_OK; - FBUCKET * pBucket; + F_BUCKET * pBucket; FLMUINT uiBucket; FLMBOOL bMutexLocked = TRUE; F_Database * pDatabase; @@ -1391,14 +1391,12 @@ RCODE F_Database::setupDatabase( // Setup the write buffer managers. - if( RC_BAD( rc = FlmAllocIOBufferMgr( &m_pBufferMgr))) + if( RC_BAD( rc = FlmAllocIOBufferMgr( MAX_PENDING_WRITES, + MAX_WRITE_BUFFER_BYTES, FALSE, &m_pBufferMgr))) { goto Exit; } - m_pBufferMgr->setMaxBuffers( MAX_PENDING_WRITES); - m_pBufferMgr->setMaxBytes( MAX_WRITE_BUFFER_BYTES); - // Initialize members of F_Database object. m_uiBucket = 0xFFFF; @@ -1570,7 +1568,7 @@ Exit: if (pCFileHdl) { - (void)pSFileHdl->releaseFile( (FLMUINT)0, TRUE); + (void)pSFileHdl->releaseFiles(); pSFileHdl->setBlockSize( m_uiBlockSize); } @@ -1656,7 +1654,9 @@ RCODE F_Database::startCPThread( void) // Set up the super file - if (RC_BAD( rc = pCPInfo->pSFileHdl->setup( pSFileClient))) + if (RC_BAD( rc = pCPInfo->pSFileHdl->setup( pSFileClient, + gv_SFlmSysData.pFileHdlCache, gv_SFlmSysData.uiFileOpenFlags, + gv_SFlmSysData.uiFileCreateFlags))) { goto Exit; } @@ -1854,7 +1854,7 @@ Desc: This routine functions as a thread. It monitors open files and frees up files which have been closed longer than the maximum close time. ****************************************************************************/ -FSTATIC RCODE flmCPThread( +FSTATIC RCODE FLMAPI flmCPThread( IF_Thread * pThread) { CP_INFO * pCPInfo = (CP_INFO *)pThread->getParm1(); diff --git a/sql/src/recover.cpp b/sql/src/recover.cpp index 0619d2f..a3e6d06 100644 --- a/sql/src/recover.cpp +++ b/sql/src/recover.cpp @@ -249,7 +249,7 @@ RCODE F_Db::processBeforeImage( m_pSFileHdl->setMaxAutoExtendSize( m_pDatabase->m_uiMaxFileSize); m_pSFileHdl->setExtendSize( m_pDatabase->m_uiFileExtendSize); rc = m_pSFileHdl->writeBlock( uiBlkAddress, uiBlkLength, pBlkHdr, - NULL, &uiBytesWritten); + &uiBytesWritten); #ifdef FLM_DBG_LOG flmDbgLogWrite( m_pDatabase, uiBlkAddress, 0, ui64TransID, "ROLLBACK"); @@ -359,8 +359,8 @@ RCODE F_Database::writeDbHdr( goto Exit; } - if( RC_BAD( rc = pCFileHdl->sectorWrite( 0, - uiBytesWritten, pTmpDbHdr, NULL, &uiBytesWritten))) + if( RC_BAD( rc = pCFileHdl->write( 0, + uiBytesWritten, pTmpDbHdr, &uiBytesWritten))) { if (pDbStats) { @@ -435,7 +435,6 @@ RCODE F_Db::physRollback( // blocks along the way. uiCurrAddr = uiFirstLogBlkAddr; - m_pSFileHdl->enableFlushMinimize(); while (FSAddrIsBelow( uiCurrAddr, uiLogEOF)) { if (RC_BAD( rc = processBeforeImage( uiLogEOF, &uiCurrAddr, @@ -454,7 +453,6 @@ RCODE F_Db::physRollback( } Exit: - m_pSFileHdl->disableFlushMinimize(); // Free the memory handle, if one was allocated. diff --git a/sql/src/rfl.cpp b/sql/src/rfl.cpp index 9259fc9..8a6f6e6 100644 --- a/sql/src/rfl.cpp +++ b/sql/src/rfl.cpp @@ -107,16 +107,14 @@ F_Rfl::~F_Rfl() if( m_Buf1.pBufferMgr) { - flmAssert( !m_Buf1.pBufferMgr->havePendingIO() && - !m_Buf1.pBufferMgr->haveUsed()); + flmAssert( !m_Buf1.pBufferMgr->isIOPending()); m_Buf1.pBufferMgr->Release(); m_Buf1.pBufferMgr = NULL; } if( m_Buf2.pBufferMgr) { - flmAssert( !m_Buf2.pBufferMgr->havePendingIO() && - !m_Buf2.pBufferMgr->haveUsed()); + flmAssert( !m_Buf2.pBufferMgr->isIOPending()); m_Buf2.pBufferMgr->Release(); m_Buf2.pBufferMgr = NULL; } @@ -351,9 +349,9 @@ RCODE F_Rfl::positionTo( m_pCurrentBuf->uiRflBufBytes = MOD_512( uiFileOffset); if (m_pCurrentBuf->uiRflBufBytes) { - if (RC_BAD( rc = m_pFileHdl->sectorRead( + if (RC_BAD( rc = m_pFileHdl->read( m_pCurrentBuf->uiRflFileOffset, m_pCurrentBuf->uiRflBufBytes, - m_pCurrentBuf->pIOBuffer->getBuffer(), &uiBytesRead))) + m_pCurrentBuf->pIOBuffer->getBufferPtr(), &uiBytesRead))) { if (rc == NE_FLM_IO_END_OF_FILE) { @@ -595,32 +593,26 @@ RCODE F_Rfl::setup( goto Exit; } - if( RC_BAD( rc = FlmAllocIOBufferMgr( &m_Buf1.pBufferMgr))) + if( RC_BAD( rc = FlmAllocIOBufferMgr( m_uiRflWriteBufs, + m_uiRflWriteBufs * m_uiBufferSize, TRUE, &m_Buf1.pBufferMgr))) { goto Exit; } - if( RC_BAD( rc = FlmAllocIOBufferMgr( &m_Buf2.pBufferMgr))) + if( RC_BAD( rc = FlmAllocIOBufferMgr( m_uiRflWriteBufs, + m_uiRflWriteBufs * m_uiBufferSize, TRUE, &m_Buf2.pBufferMgr))) { goto Exit; } - m_Buf1.pBufferMgr->enableKeepBuffer(); - m_Buf1.pBufferMgr->setMaxBuffers( m_uiRflWriteBufs); - m_Buf1.pBufferMgr->setMaxBytes( m_uiRflWriteBufs * m_uiBufferSize); - - if( RC_BAD( rc = m_Buf1.pBufferMgr->getBuffer( &m_Buf1.pIOBuffer, - m_uiBufferSize, m_uiBufferSize))) + if( RC_BAD( rc = m_Buf1.pBufferMgr->getBuffer( m_uiBufferSize, + &m_Buf1.pIOBuffer))) { goto Exit; } - m_Buf2.pBufferMgr->enableKeepBuffer(); - m_Buf2.pBufferMgr->setMaxBuffers( m_uiRflWriteBufs); - m_Buf2.pBufferMgr->setMaxBytes( m_uiRflWriteBufs * m_uiBufferSize); - - if( RC_BAD( rc = m_Buf2.pBufferMgr->getBuffer( &m_Buf2.pIOBuffer, - m_uiBufferSize, m_uiBufferSize))) + if( RC_BAD( rc = m_Buf2.pBufferMgr->getBuffer( m_uiBufferSize, + &m_Buf2.pIOBuffer))) { goto Exit; } @@ -791,8 +783,7 @@ RCODE F_Rfl::writeHeader( // Write out the header - if (RC_BAD( rc = m_pFileHdl->sectorWrite( 0L, 512, - ucBuf, NULL, &uiBytesWritten))) + if (RC_BAD( rc = m_pFileHdl->write( 0L, 512, ucBuf, &uiBytesWritten))) { // Remap disk full error @@ -959,8 +950,7 @@ RCODE F_Rfl::openFile( // Read the header. - if (RC_BAD( rc = m_pFileHdl->sectorRead( 0, 512, ucBuf, - &uiBytesRead))) + if (RC_BAD( rc = m_pFileHdl->read( 0, 512, ucBuf, &uiBytesRead))) { if (rc == NE_FLM_IO_END_OF_FILE) { @@ -1229,14 +1219,13 @@ RCODE F_Rfl::flush( goto Exit; } - pucOldBuffer = pBuffer->pIOBuffer->getBuffer(); + pucOldBuffer = pBuffer->pIOBuffer->getBufferPtr(); uiFileOffset = pBuffer->uiRflFileOffset; uiBufBytes = pBuffer->uiRflBufBytes; if (m_uiRflWriteBufs > 1) { - if( RC_BAD( rc = pBuffer->pBufferMgr->getBuffer( - &pNewBuffer, - m_uiBufferSize, m_uiBufferSize))) + if( RC_BAD( rc = pBuffer->pBufferMgr->getBuffer( m_uiBufferSize, + &pNewBuffer))) { goto Exit; } @@ -1248,14 +1237,22 @@ RCODE F_Rfl::flush( if (!bFinalWrite) { - copyLastSector( pBuffer, pucOldBuffer, pNewBuffer->getBuffer(), + copyLastSector( pBuffer, pucOldBuffer, pNewBuffer->getBufferPtr(), uiCurrPacketLen, bStartingNewFile); } } - - rc = m_pFileHdl->sectorWrite( uiFileOffset, uiBufBytes, - pucOldBuffer, pAsyncBuf, - &uiBytesWritten); + + if( pAsyncBuf) + { + rc = m_pFileHdl->write( uiFileOffset, uiBufBytes, pAsyncBuf, + &uiBytesWritten); + } + else + { + rc = m_pFileHdl->write( uiFileOffset, uiBufBytes, pucOldBuffer, + &uiBytesWritten); + } + if( m_uiRflWriteBufs == 1) { @@ -1332,8 +1329,8 @@ void F_Rfl::switchBuffers( void) if (pOldBuffer->uiRflBufBytes) { - copyLastSector( m_pCurrentBuf, pOldBuffer->pIOBuffer->getBuffer(), - m_pCurrentBuf->pIOBuffer->getBuffer(), 0, FALSE); + copyLastSector( m_pCurrentBuf, pOldBuffer->pIOBuffer->getBufferPtr(), + m_pCurrentBuf->pIOBuffer->getBufferPtr(), 0, FALSE); } } @@ -2227,7 +2224,7 @@ RCODE F_Rfl::finishPacket( // Get a pointer to packet header. - pucPacket = &(m_pCurrentBuf->pIOBuffer->getBuffer()[ + pucPacket = &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[ m_pCurrentBuf->uiRflBufBytes]); // Set the packet address in the packet header. @@ -3677,7 +3674,7 @@ Exit: Desc: *********************************************************************/ RCODE F_Rfl::recovEncDefKey( - F_Db * pDb, + F_Db *, // pDb, const FLMBYTE * pucPacketBody, FLMUINT uiPacketBodyLen, eRestoreAction *) // peAction @@ -6018,8 +6015,8 @@ RCODE F_Rfl::readPacket( // Move the bytes left in the buffer down to the beginning // of the buffer. - f_memmove( m_pCurrentBuf->pIOBuffer->getBuffer(), - &(m_pCurrentBuf->pIOBuffer->getBuffer()[ m_uiRflReadOffset]), + f_memmove( m_pCurrentBuf->pIOBuffer->getBufferPtr(), + &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[ m_uiRflReadOffset]), m_pCurrentBuf->uiRflBufBytes - m_uiRflReadOffset); m_pCurrentBuf->uiRflBufBytes -= m_uiRflReadOffset; m_pCurrentBuf->uiRflFileOffset += m_uiRflReadOffset; @@ -6057,7 +6054,7 @@ RCODE F_Rfl::readPacket( // Read enough to get the entire packet. if( RC_BAD( rc = m_pRestore->read( uiReadLen, - &(m_pCurrentBuf->pIOBuffer->getBuffer()[ + &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[ m_pCurrentBuf->uiRflBufBytes]), &uiBytesRead))) { if( rc == NE_FLM_IO_END_OF_FILE) @@ -6145,8 +6142,8 @@ RCODE F_Rfl::readPacket( // Read to get the entire packet. - if( RC_BAD( rc = m_pFileHdl->sectorRead( m_pCurrentBuf->uiRflFileOffset, - uiReadLen, m_pCurrentBuf->pIOBuffer->getBuffer(), + if( RC_BAD( rc = m_pFileHdl->read( m_pCurrentBuf->uiRflFileOffset, + uiReadLen, m_pCurrentBuf->pIOBuffer->getBufferPtr(), &uiBytesRead))) { if( rc == NE_FLM_IO_END_OF_FILE) @@ -6399,7 +6396,7 @@ Get_Next_File: // Verify the packet address. m_uiPacketAddress = m_pCurrentBuf->uiRflFileOffset + m_uiRflReadOffset; - pucPacket = &(m_pCurrentBuf->pIOBuffer->getBuffer()[m_uiRflReadOffset]); + pucPacket = &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[m_uiRflReadOffset]); if ((FLMUINT)FB2UD( &pucPacket [RFL_PACKET_ADDRESS_OFFSET]) != m_uiPacketAddress) { @@ -6421,7 +6418,7 @@ Get_Next_File: { goto Exit; } - pucPacket = &(m_pCurrentBuf->pIOBuffer->getBuffer()[m_uiRflReadOffset]); + pucPacket = &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[m_uiRflReadOffset]); // At this point, we are guaranteed to have the entire packet // in the buffer. @@ -6796,7 +6793,7 @@ Retry_Open: } if( RC_BAD( rc = m_pRestore->read( uiReadLen, - m_pCurrentBuf->pIOBuffer->getBuffer(), &uiBytesRead))) + m_pCurrentBuf->pIOBuffer->getBufferPtr(), &uiBytesRead))) { goto Exit; } diff --git a/sql/src/rfl.h b/sql/src/rfl.h index 655e675..d1fcdbe 100644 --- a/sql/src/rfl.h +++ b/sql/src/rfl.h @@ -424,7 +424,7 @@ public: FINLINE FLMBYTE * getPacketPtr( void) { - return( &(m_pCurrentBuf->pIOBuffer->getBuffer()[ + return( &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[ m_pCurrentBuf->uiRflBufBytes])); } @@ -434,7 +434,7 @@ public: { if( m_pCurrentBuf->pBufferMgr) { - flmAssert( !m_pCurrentBuf->pBufferMgr->havePendingIO()); + flmAssert( !m_pCurrentBuf->pBufferMgr->isIOPending()); } if (m_pFileHdl) { @@ -535,7 +535,7 @@ private: FINLINE FLMBYTE * getPacketBodyPtr( void) { - return( &(m_pCurrentBuf->pIOBuffer->getBuffer()[ + return( &(m_pCurrentBuf->pIOBuffer->getBufferPtr()[ m_pCurrentBuf->uiRflBufBytes + RFL_PACKET_OVERHEAD])); } diff --git a/sql/src/scache.cpp b/sql/src/scache.cpp index 877262b..9d82472 100644 --- a/sql/src/scache.cpp +++ b/sql/src/scache.cpp @@ -26,6 +26,7 @@ #include "flaimsys.h" #define MAX_BLOCKS_TO_SORT 500 +#define FLM_MAX_IO_BUFFER_BLOCKS 16 FSTATIC void ScaNotify( FNOTIFY * pNotify, @@ -64,7 +65,7 @@ FINLINE FLMINT scaCompare( Desc: Compare two cache blocks during a sort to determine which one has lower address. *****************************************************************************/ -FINLINE FLMINT scaSortCompare( +FINLINE FLMINT FLMAPI scaSortCompare( void * pvBuffer, FLMUINT uiPos1, FLMUINT uiPos2) @@ -76,7 +77,7 @@ FINLINE FLMINT scaSortCompare( /*************************************************************************** Desc: Swap two entries in cache table during sort. *****************************************************************************/ -FINLINE void scaSortSwap( +FINLINE void FLMAPI scaSortSwap( void * pvBuffer, FLMUINT uiPos1, FLMUINT uiPos2) @@ -1205,15 +1206,11 @@ RCODE F_Database::flushLogBlocks( : (F_CachedBlock **)NULL); FLMUINT uiTotalLoggedBlocks = 0; FLMBOOL bForceCheckpoint = *pbForceCheckpoint; - FLMBOOL bDoAsync; #ifdef FLM_DBG_LOG FLMUINT16 ui16OldFlags; #endif m_uiCurrLogWriteOffset = 0; - bDoAsync = (gv_SFlmSysData.bOkToDoAsyncWrites && pSFileHdl->canDoAsync()) - ? TRUE - : FALSE; // Get the correct log header. If we are in an update transaction, // need to use the uncommitted log header. Otherwise, use the last @@ -1453,7 +1450,7 @@ RCODE F_Database::flushLogBlocks( if (RC_BAD( rc = lgOutputBlock( pDbStats, pSFileHdl, pLastBlockToLog, pLastBlockToLog->m_pPrevInVersionList->m_pBlkHdr, - bDoAsync, &uiLogEof))) + &uiLogEof))) { goto Exit; } @@ -1523,8 +1520,7 @@ Write_Log_Blocks: if (m_uiCurrLogWriteOffset) { - if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl, - bDoAsync))) + if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl))) { goto Exit; } @@ -1533,12 +1529,9 @@ Write_Log_Blocks: // If doing async, wait for pending writes to complete before writing // the log header. - if (bDoAsync) + if (RC_BAD( rc = m_pBufferMgr->waitForAllPendingIO())) { - if (RC_BAD( rc = m_pBufferMgr->waitForAllPendingIO())) - { - goto Exit; - } + goto Exit; } // Must wait for all RFL writes before writing out log header. @@ -1737,24 +1730,21 @@ Exit: // Don't care what rc is at this point. Just calling // lgFlushLogBuffer to clear the buffer. - (void)lgFlushLogBuffer( pDbStats, pSFileHdl, bDoAsync); + (void)lgFlushLogBuffer( pDbStats, pSFileHdl); } // Need to wait for any async writes to complete. - if (bDoAsync) + if (bMutexLocked) { - if (bMutexLocked) - { - f_mutexUnlock( gv_SFlmSysData.hBlockCacheMutex); - bMutexLocked = FALSE; - } - - // Don't care about rc here, but we don't want to leave - // this routine until all pending IO is taken care of. - - (void)m_pBufferMgr->waitForAllPendingIO(); + f_mutexUnlock( gv_SFlmSysData.hBlockCacheMutex); + bMutexLocked = FALSE; } + + // Don't care about rc here, but we don't want to leave + // this routine until all pending IO is taken care of. + + (void)m_pBufferMgr->waitForAllPendingIO(); if (!bMutexLocked) { @@ -1832,7 +1822,7 @@ Exit: // Better not be any incomplete writes at this point. - flmAssert( !m_pBufferMgr->havePendingIO()); + flmAssert( !m_pBufferMgr->isIOPending()); flmAssert( m_pCurrLogBuffer == NULL); *pbForceCheckpoint = bForceCheckpoint; @@ -1842,35 +1832,42 @@ Exit: /**************************************************************************** Desc: This routine is called whenever a write of a dirty block completes. ****************************************************************************/ -FSTATIC void scaWriteComplete( - IF_IOBuffer * pIOBuffer) +/**************************************************************************** +Desc: This routine is called whenever a write of a dirty block completes. +****************************************************************************/ +FSTATIC void FLMAPI scaWriteComplete( + IF_IOBuffer * pIOBuffer, + void * pvData) { - RCODE rc = pIOBuffer->getCompletionCode(); - FLMUINT uiNumBlocks = pIOBuffer->getBufferSize() / - pIOBuffer->getBlockSize(); - F_CachedBlock * pSCache; + RCODE rc; + FLMUINT uiNumBlocks = 0; + F_CachedBlock * pSCache = NULL; F_Database * pDatabase; - SFLM_DB_STATS * pDbStats = (SFLM_DB_STATS *)pIOBuffer->getStats(); + SFLM_DB_STATS * pDbStats = (SFLM_DB_STATS *)pvData; FLMUINT uiMilliPerBlock = 0; FLMUINT uiExtraMilli = 0; - #ifdef FLM_DBG_LOG - FLMUINT16 ui16OldFlags; + FLMUINT16 ui16OldFlags; #endif - if (pDbStats) + f_assert( pIOBuffer->isComplete()); + + rc = pIOBuffer->getCompletionCode(); + uiNumBlocks = pIOBuffer->getCallbackDataCount(); + + if( pDbStats) { - FLMUINT64 ui64ElapMilli = pIOBuffer->getElapTime(); + FLMUINT64 ui64ElapMilli = pIOBuffer->getElapsedTime(); uiMilliPerBlock = (FLMUINT)(ui64ElapMilli / (FLMUINT64)uiNumBlocks); uiExtraMilli = (FLMUINT)(ui64ElapMilli % (FLMUINT64)uiNumBlocks); } f_mutexLock( gv_SFlmSysData.hBlockCacheMutex); - while (uiNumBlocks) + while( uiNumBlocks) { uiNumBlocks--; - pSCache = (F_CachedBlock *)pIOBuffer->getCompletionCallbackData( uiNumBlocks); + pSCache = (F_CachedBlock *)pIOBuffer->getCallbackData( uiNumBlocks); pDatabase = pSCache->getDatabase(); if (pDbStats) @@ -3762,77 +3759,6 @@ Do_Free_Pass: f_mutexUnlock( gv_SFlmSysData.hBlockCacheMutex); } -/**************************************************************************** -Desc: Write an IO buffer to disk. -****************************************************************************/ -RCODE F_Database::writeContiguousBlocks( - SFLM_DB_STATS * pDbStats, - F_SuperFileHdl * pSFileHdl, - IF_IOBuffer * pIOBuffer, - FLMUINT uiBlkAddress, - FLMBOOL bDoAsync) -{ - RCODE rc = NE_SFLM_OK; - FLMBYTE * pucWriteBuffer; - IF_IOBuffer * pAsyncBuffer; - FLMUINT uiBytesWritten; - FLMUINT uiWriteLen; - - pucWriteBuffer = pIOBuffer->getBuffer(); - - if (!bDoAsync) - { - pAsyncBuffer = NULL; - } - else - { - pAsyncBuffer = pIOBuffer; - } - - // Determine how many bytes to write - - uiWriteLen = pIOBuffer->getBufferSize(); - pSFileHdl->setMaxAutoExtendSize( m_uiMaxFileSize); - pSFileHdl->setExtendSize( m_uiFileExtendSize); - - pIOBuffer->startTimer( pDbStats); - - // NOTE: No guarantee that pIOBuffer will still be around - // after the call to writeBlock, unless we are doing - // non-asynchronous write. - - rc = pSFileHdl->writeBlock( uiBlkAddress, uiWriteLen, - pucWriteBuffer, pAsyncBuffer, &uiBytesWritten); - if (!pAsyncBuffer) - { - pIOBuffer->notifyComplete( rc); - } - pIOBuffer = NULL; - - if (RC_BAD( rc)) - { - if (pDbStats) - { - pDbStats->bHaveStats = TRUE; - pDbStats->uiWriteErrors++; - } - - goto Exit; - } - -Exit: - - // If we allocated a write buffer, but did not do a write with it - // still need to do the notify to clean up cache blocks. - - if (pIOBuffer) - { - flmAssert( RC_BAD( rc)); - pIOBuffer->notifyComplete( rc); - } - return( rc); -} - /**************************************************************************** Desc: Prepares a block to be written out. Calculates the checksum and converts the block to native format if not currently in native @@ -3881,7 +3807,6 @@ RCODE F_Database::writeSortedBlocks( FLMUINT * puiDirtyCacheLeft, FLMBOOL * pbForceCheckpoint, FLMBOOL bIsCPThread, - FLMBOOL bDoAsync, FLMUINT uiNumSortedBlocks, FLMBOOL * pbWroteAll) { @@ -4076,13 +4001,12 @@ Add_Contiguous_Block: // Ask for a buffer of the size needed. flmAssert( pIOBuffer == NULL); - if (RC_BAD( rc = m_pBufferMgr->getBuffer( - &pIOBuffer, uiContiguousBlocks * m_uiBlockSize, - m_uiBlockSize))) + if (RC_BAD( rc = m_pBufferMgr->getBuffer( + uiContiguousBlocks * m_uiBlockSize, &pIOBuffer))) { goto Exit; } - pIOBuffer->setCompletionCallback( scaWriteComplete); + pIOBuffer->setCompletionCallback( scaWriteComplete, pDbStats); // Callback will now take care of everything between // uiStartOffset and uiStartOffset + uiNumSortedBlocksProcessed - 1 @@ -4130,7 +4054,7 @@ Add_Contiguous_Block: // Set callback data so we will release these and clear // the pending flag if we don't do the I/O. - pIOBuffer->setCompletionCallbackData( uiLoop, pSCache); + pIOBuffer->addCallbackData( pSCache); } if (bMutexLocked) @@ -4141,7 +4065,7 @@ Add_Contiguous_Block: // Copy blocks into the IO buffer. - pucBuffer = pIOBuffer->getBuffer(); + pucBuffer = pIOBuffer->getBufferPtr(); for (uiLoop = 0; uiLoop < uiBlockCount; uiLoop++, pucBuffer += m_uiBlockSize) @@ -4169,10 +4093,26 @@ Add_Contiguous_Block: goto Exit; } } - - rc = writeContiguousBlocks( pDbStats, pSFileHdl, - pIOBuffer, uiStartBlkAddr, bDoAsync); + + pSFileHdl->setMaxAutoExtendSize( m_uiMaxFileSize); + pSFileHdl->setExtendSize( m_uiFileExtendSize); + + rc = pSFileHdl->writeBlock( uiStartBlkAddr, + pIOBuffer->getBufferSize(), pIOBuffer); + + pIOBuffer->Release(); pIOBuffer = NULL; + + if( RC_BAD( rc)) + { + if (pDbStats) + { + pDbStats->bHaveStats = TRUE; + pDbStats->uiWriteErrors++; + } + + goto Exit; + } // See if we should give up our write lock. Will do so if we // are not forcing a checkpoint and we have not exceeded the @@ -4272,7 +4212,6 @@ RCODE F_Database::flushDirtyBlocks( RCODE rc = NE_SFLM_OK; RCODE rc2; F_CachedBlock * pSCache; - FLMBOOL bDoAsync; FLMBOOL bMutexLocked = FALSE; FLMUINT uiSortedBlocks = 0; FLMUINT uiBlockCount = 0; @@ -4290,12 +4229,6 @@ RCODE F_Database::flushDirtyBlocks( unlockMutex(); } - // See if we can do async IO. - - bDoAsync = (gv_SFlmSysData.bOkToDoAsyncWrites && pSFileHdl->canDoAsync()) - ? TRUE - : FALSE; - flmAssert( !m_pPendingWriteList); uiDirtyCacheLeft = m_uiDirtyCacheCount * m_uiBlockSize; @@ -4449,7 +4382,7 @@ Force_Checkpoint: rc = writeSortedBlocks( pDbStats, pSFileHdl, uiMaxDirtyCache, &uiDirtyCacheLeft, &bForceCheckpoint, bIsCPThread, - bDoAsync, uiSortedBlocks, pbWroteAll); + uiSortedBlocks, pbWroteAll); } else { @@ -4514,17 +4447,13 @@ Exit: bMutexLocked = FALSE; } - if (bDoAsync) + // Wait for writes to complete. + + if (RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) { - - // Wait for writes to complete. - - if (RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) + if (RC_OK( rc)) { - if (RC_OK( rc)) - { - rc = rc2; - } + rc = rc2; } } @@ -4532,7 +4461,7 @@ Exit: // Better not be any incomplete writes at this point. - flmAssert( !m_pBufferMgr->havePendingIO()); + flmAssert( !m_pBufferMgr->isIOPending()); // Don't keep around a large block array if we happened to // allocate one that is bigger than our normal size. It may @@ -4556,7 +4485,6 @@ RCODE F_Database::reduceDirtyCache( RCODE rc = NE_SFLM_OK; RCODE rc2; F_CachedBlock * pSCache; - FLMBOOL bDoAsync; FLMBOOL bMutexLocked = FALSE; FLMUINT uiDirtyCacheLeft; FLMUINT uiSortedBlocks = 0; @@ -4566,13 +4494,6 @@ RCODE F_Database::reduceDirtyCache( flmAssert( !m_uiLogCacheCount); - // See if we can do async IO. - - bDoAsync = (gv_SFlmSysData.bOkToDoAsyncWrites && - pSFileHdl->canDoAsync()) - ? TRUE - : FALSE; - flmAssert( !m_pPendingWriteList); if( m_uiDirtyCacheCount > m_uiBlocksDoneArraySize * 2) @@ -4629,7 +4550,7 @@ RCODE F_Database::reduceDirtyCache( bWroteAll = TRUE; rc = writeSortedBlocks( pDbStats, pSFileHdl, 0, &uiDirtyCacheLeft, - &bForceCheckpoint, FALSE, bDoAsync, uiSortedBlocks, &bWroteAll); + &bForceCheckpoint, FALSE, uiSortedBlocks, &bWroteAll); uiSortedBlocks = 0; @@ -4664,16 +4585,13 @@ Exit: bMutexLocked = FALSE; } - if( bDoAsync) - { - // Wait for writes to complete. + // Wait for writes to complete. - if( RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) + if( RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) + { + if( RC_OK( rc)) { - if( RC_OK( rc)) - { - rc = rc2; - } + rc = rc2; } } @@ -4681,7 +4599,7 @@ Exit: // Better not be any incomplete writes at this point. - flmAssert( !m_pBufferMgr->havePendingIO()); + flmAssert( !m_pBufferMgr->isIOPending()); // Don't keep around a large block array if we happened to // allocate one that is bigger than our normal size. It may @@ -4720,7 +4638,6 @@ RCODE F_Database::reduceNewBlocks( RCODE rc = NE_SFLM_OK; RCODE rc2; F_CachedBlock * pSCache; - FLMBOOL bDoAsync = FALSE; FLMBOOL bMutexLocked = FALSE; FLMUINT uiSortedBlocks = 0; FLMUINT uiDirtyCacheLeft; @@ -4734,12 +4651,6 @@ RCODE F_Database::reduceNewBlocks( unlockMutex(); } - // See if we can do async IO. - - bDoAsync = (gv_SFlmSysData.bOkToDoAsyncWrites && pSFileHdl->canDoAsync()) - ? TRUE - : FALSE; - flmAssert( !m_pPendingWriteList); uiDirtyCacheLeft = m_uiDirtyCacheCount * m_uiBlockSize; @@ -4811,7 +4722,7 @@ RCODE F_Database::reduceNewBlocks( rc = writeSortedBlocks( pDbStats, pSFileHdl, ~((FLMUINT)0), &uiDirtyCacheLeft, &bForceCheckpoint, FALSE, - bDoAsync, uiSortedBlocks, &bDummy); + uiSortedBlocks, &bDummy); if( RC_OK( rc)) { @@ -4862,17 +4773,13 @@ Exit: bMutexLocked = FALSE; } - if (bDoAsync) + // Wait for writes to complete. + + if (RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) { - - // Wait for writes to complete. - - if (RC_BAD( rc2 = m_pBufferMgr->waitForAllPendingIO())) + if (RC_OK( rc)) { - if (RC_OK( rc)) - { - rc = rc2; - } + rc = rc2; } } @@ -4880,7 +4787,7 @@ Exit: // Better not be any incomplete writes at this point. - flmAssert( !m_pBufferMgr->havePendingIO()); + flmAssert( !m_pBufferMgr->isIOPending()); // Don't keep around a large block array if we happened to // allocate one that is bigger than our normal size. It may @@ -5318,7 +5225,7 @@ RCODE F_Database::createBlock( F_Db * pDb, F_CachedBlock ** ppSCacheRV) { - RCODE rc = NE_SFLM_OK; + RCODE rc = NE_FLM_OK; FLMUINT uiBlkAddress; F_BLK_HDR * pBlkHdr; F_CachedBlock * pSCache = NULL; @@ -5380,16 +5287,12 @@ RCODE F_Database::createBlock( if( !gv_SFlmSysData.pGlobalCacheMgr->cacheOverLimit()) { - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->lockMutex(); - - if( (pSCache = new( uiBlockSize, TRUE) F_CachedBlock( uiBlockSize)) == NULL) + if( (pSCache = new( uiBlockSize) F_CachedBlock( uiBlockSize)) == NULL) { rc = RC_SET( NE_SFLM_MEM); goto Exit; } - pSCache->m_uiUseCount++; - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->unlockMutex(); bLocalCacheAllocation = TRUE; } @@ -5447,7 +5350,7 @@ RCODE F_Database::createBlock( // Set use count to one so the block cannot be replaced. - pSCache->m_uiUseCount--; + pSCache->m_bCanRelocate = TRUE; pSCache->useForThread( 0); } else @@ -5745,16 +5648,13 @@ RCODE F_Database::logPhysBlk( if( !gv_SFlmSysData.pGlobalCacheMgr->cacheOverLimit()) { - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->lockMutex(); - - if( (pNewSCache = new( uiBlockSize, TRUE) F_CachedBlock( uiBlockSize)) == NULL) + if( (pNewSCache = new( uiBlockSize) F_CachedBlock( + uiBlockSize)) == NULL) { rc = RC_SET( NE_SFLM_MEM); goto Exit; } - pNewSCache->m_uiUseCount++; - gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->unlockMutex(); bLocalCacheAllocation = TRUE; // Copy the old block's data into this one. @@ -5781,7 +5681,7 @@ RCODE F_Database::logPhysBlk( // Set use count to one so the block cannot be replaced. - pNewSCache->m_uiUseCount--; + pNewSCache->m_bCanRelocate = TRUE; pNewSCache->useForThread( 0); } else @@ -6073,7 +5973,7 @@ RCODE F_BlockCacheMgr::initCache( void) } if (RC_BAD( rc = m_pBlockAllocator->setup( - gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, NULL, uiBlockSizes, + TRUE, gv_SFlmSysData.pGlobalCacheMgr->m_pSlabManager, NULL, uiBlockSizes, &m_Usage.slabUsage, NULL))) { goto Exit; @@ -7152,8 +7052,6 @@ RCODE F_Database::doCheckpoint( F_CachedBlock * pSCache; FLMUINT uiTimestamp; - pSFileHdl->enableFlushMinimize(); - if (m_pCPInfo) { lockMutex(); @@ -7281,8 +7179,6 @@ Exit: unlockMutex(); } - pSFileHdl->disableFlushMinimize(); - return( rc); } @@ -7784,27 +7680,46 @@ Exit: #undef new #undef delete +/**************************************************************************** +Desc: +****************************************************************************/ +void FLMAPI F_CachedBlock::objectAllocInit( + void * pvAlloc, + FLMUINT uiSize) +{ + F_UNREFERENCED_PARM( uiSize); + + // Need to make sure that m_bCanRelocate is initialized to zero + // prior to unlocking the mutex. This is so the allocator + // doesn't see garbage values that may cause it to relocate the object + // before the constructor has been called. + + ((F_CachedBlock *)pvAlloc)->m_bCanRelocate = FALSE; +} + /**************************************************************************** Desc: ****************************************************************************/ void * F_CachedBlock::operator new( FLMSIZET uiSize, - FLMUINT uiBlockSize, - FLMBOOL bAllocMutexLocked) + FLMUINT uiBlockSize) #ifndef FLM_NLM throw() #endif { - void * pvPtr; + void * pvPtr; flmAssert( uiSize == sizeof( F_CachedBlock)); + if( RC_BAD( gv_SFlmSysData.pBlockCacheMgr->m_pBlockAllocator->allocBuf( &gv_SFlmSysData.pBlockCacheMgr->m_blockRelocator, - uiSize + uiBlockSize, (FLMBYTE **)&pvPtr, bAllocMutexLocked))) + uiSize + uiBlockSize, F_CachedBlock::objectAllocInit, + (FLMBYTE **)&pvPtr))) { pvPtr = NULL; } - + + flmAssert( !((F_CachedBlock *)pvPtr)->m_bCanRelocate); return( pvPtr); } diff --git a/sql/src/sqleval.cpp b/sql/src/sqleval.cpp index f002f7f..2f0f99c 100644 --- a/sql/src/sqleval.cpp +++ b/sql/src/sqleval.cpp @@ -1555,7 +1555,7 @@ FSTATIC RCODE sqlCompareOperands( SQL_VALUE * pRValue, eSQLQueryOperators eOperator, FLMUINT uiCompareRules, - FLMBOOL bNotted, + FLMBOOL, // bNotted, SQLBoolType * peBool) { RCODE rc = NE_SFLM_OK; diff --git a/sql/src/sqloptimize.cpp b/sql/src/sqloptimize.cpp index 5066988..278c360 100644 --- a/sql/src/sqloptimize.cpp +++ b/sql/src/sqloptimize.cpp @@ -1592,15 +1592,15 @@ Exit: // new sub-tree as the last child of pParentNode. //------------------------------------------------------------------------- FSTATIC RCODE copyAndLinkSubTree( - F_Pool * pPool, - SQL_DNF_NODE * pSrcSubTree, - SQL_DNF_NODE * pParentNode) + F_Pool * pPool, + SQL_DNF_NODE * pSrcSubTree, + SQL_DNF_NODE *) // pParentNode) { - RCODE rc = NE_SFLM_OK; - SQL_DNF_NODE * pNewSubTree = NULL; - SQL_DNF_NODE * pCurrDestParentNode = NULL; - SQL_DNF_NODE * pCurrSrcNode = pSrcSubTree; - SQL_DNF_NODE * pNewDestNode = NULL; + RCODE rc = NE_SFLM_OK; + SQL_DNF_NODE * pNewSubTree = NULL; + SQL_DNF_NODE * pCurrDestParentNode = NULL; + SQL_DNF_NODE * pCurrSrcNode = pSrcSubTree; + SQL_DNF_NODE * pNewDestNode = NULL; for (;;) { diff --git a/sql/src/sqlstatement.cpp b/sql/src/sqlstatement.cpp index 31beb16..52beef0 100644 --- a/sql/src/sqlstatement.cpp +++ b/sql/src/sqlstatement.cpp @@ -1078,9 +1078,11 @@ RCODE SQLStatement::getNumber( // Ignore white space + if( f_isWhitespace( ucChar)) { continue; } + if (ucChar >= '0' && ucChar <= '9') { uiDigitValue = (FLMUINT)(ucChar - '0'); @@ -2049,8 +2051,15 @@ RCODE SQLStatement::executeSQL( if (RC_BAD( rc = getToken( szToken, sizeof( szToken), TRUE, &uiTokenLineOffset, NULL))) { - goto Exit; + if( rc != NE_SFLM_EOF_HIT) + { + goto Exit; + } + + rc = NE_SFLM_OK; + break; } + if (f_stricmp( szToken, "select") == 0) { if (RC_BAD( rc = processSelect())) @@ -2081,10 +2090,12 @@ RCODE SQLStatement::executeSQL( } else if (f_stricmp( szToken, "open") == 0) { - if (RC_BAD( rc = haveToken( "database", FALSE, SQL_ERR_INVALID_OPEN_OPTION))) + if (RC_BAD( rc = haveToken( "database", FALSE, + SQL_ERR_INVALID_OPEN_OPTION))) { goto Exit; } + if (RC_BAD( rc = processOpenDatabase())) { goto Exit; diff --git a/sql/src/translog.cpp b/sql/src/translog.cpp index 0220b67..88be2ec 100644 --- a/sql/src/translog.cpp +++ b/sql/src/translog.cpp @@ -69,17 +69,18 @@ void scaLogWrite( Desc: This is the callback routine that is called when a disk write is completed. ****************************************************************************/ -FSTATIC void lgWriteComplete( - IF_IOBuffer * pIOBuffer) +FSTATIC void FLMAPI lgWriteComplete( + IF_IOBuffer * pIOBuffer, + void * pvData) { F_Database * pDatabase = - (F_Database *)pIOBuffer->getCompletionCallbackData( 0); + (F_Database *)pIOBuffer->getCallbackData( 0); #ifdef FLM_DBG_LOG FLMUINT uiBlockSize = pDatabase->getBlockSize(); FLMUINT uiLength = pIOBuffer->getBufferSize(); char * pszEvent; #endif - SFLM_DB_STATS * pDbStats = (SFLM_DB_STATS *)pIOBuffer->getStats(); + SFLM_DB_STATS * pDbStats = (SFLM_DB_STATS *)pvData; #ifdef FLM_DBG_LOG pszEvent = (char *)(RC_OK( pIOBuffer->getCompletionCode()) @@ -96,7 +97,7 @@ FSTATIC void lgWriteComplete( // completion at any time. pDatabase->lockMutex(); - pDbStats->LogBlockWrites.ui64ElapMilli += pIOBuffer->getElapTime(); + pDbStats->LogBlockWrites.ui64ElapMilli += pIOBuffer->getElapsedTime(); pDatabase->unlockMutex(); } } @@ -106,21 +107,9 @@ Desc: This routine flushes a log buffer to the log file. ****************************************************************************/ RCODE F_Database::lgFlushLogBuffer( SFLM_DB_STATS * pDbStats, - F_SuperFileHdl * pSFileHdl, - FLMBOOL bDoAsync) + F_SuperFileHdl * pSFileHdl) { RCODE rc = NE_SFLM_OK; - FLMUINT uiBytesWritten; - IF_IOBuffer * pAsyncBuffer; - - if (!bDoAsync) - { - pAsyncBuffer = NULL; - } - else - { - pAsyncBuffer = m_pCurrLogBuffer; - } if (pDbStats) { @@ -129,39 +118,32 @@ RCODE F_Database::lgFlushLogBuffer( pDbStats->LogBlockWrites.ui64TotalBytes += m_uiCurrLogWriteOffset; } - m_pCurrLogBuffer->setCompletionCallback( lgWriteComplete); - m_pCurrLogBuffer->setCompletionCallbackData( 0, (void *)this); + m_pCurrLogBuffer->setCompletionCallback( lgWriteComplete, pDbStats); + m_pCurrLogBuffer->addCallbackData( (void *)this); pSFileHdl->setMaxAutoExtendSize( m_uiMaxFileSize); pSFileHdl->setExtendSize( m_uiFileExtendSize); - m_pCurrLogBuffer->startTimer( pDbStats); // NOTE: No guarantee that m_pCurrLogBuffer will still be around - // after the call to WriteBlock, unless we are doing + // after the call to writeBlock, unless we are doing // non-asynchronous write. - rc = pSFileHdl->writeBlock( m_uiCurrLogBlkAddr, - m_uiCurrLogWriteOffset, - m_pCurrLogBuffer->getBuffer(), - pAsyncBuffer, &uiBytesWritten); - if (!pAsyncBuffer) - { - m_pCurrLogBuffer->notifyComplete( rc); - } - m_pCurrLogBuffer = NULL; - - if (RC_BAD( rc)) + if( RC_BAD( rc = pSFileHdl->writeBlock( m_uiCurrLogBlkAddr, + m_uiCurrLogWriteOffset, m_pCurrLogBuffer))) { if (pDbStats) { pDbStats->uiWriteErrors++; } + goto Exit; } Exit: m_uiCurrLogWriteOffset = 0; + m_pCurrLogBuffer->Release(); m_pCurrLogBuffer = NULL; + return( rc); } @@ -176,7 +158,6 @@ RCODE F_Database::lgOutputBlock( // block in cache. This block will be // modified to the logged version of // the block - FLMBOOL bDoAsync, // Do asynchronous writes? FLMUINT * puiLogEofRV) // Returns log EOF { RCODE rc = NE_SFLM_OK; @@ -196,8 +177,7 @@ RCODE F_Database::lgOutputBlock( if (m_uiCurrLogWriteOffset) { - if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl, - bDoAsync))) + if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl))) { goto Exit; } @@ -242,7 +222,7 @@ RCODE F_Database::lgOutputBlock( for( ;;) { if (RC_BAD( rc = m_pBufferMgr->getBuffer( - &m_pCurrLogBuffer, uiLogBufferSize, uiLogBufferSize))) + uiLogBufferSize, &m_pCurrLogBuffer))) { // If we failed to get a buffer of the requested size, // reduce the buffer size by half and try again. @@ -265,7 +245,7 @@ RCODE F_Database::lgOutputBlock( // Copy data from log block to the log buffer - pucLogBlk = m_pCurrLogBuffer->getBuffer() + m_uiCurrLogWriteOffset; + pucLogBlk = m_pCurrLogBuffer->getBufferPtr() + m_uiCurrLogWriteOffset; pLogBlkHdr = (F_BLK_HDR *)pucLogBlk; f_memcpy( pLogBlkHdr, pLogBlock->m_pBlkHdr, m_uiBlockSize); @@ -302,8 +282,7 @@ RCODE F_Database::lgOutputBlock( if (m_uiCurrLogWriteOffset == m_pCurrLogBuffer->getBufferSize()) { - if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl, - bDoAsync))) + if (RC_BAD( rc = lgFlushLogBuffer( pDbStats, pSFileHdl))) { goto Exit; } diff --git a/sql/src/updaterow.cpp b/sql/src/updaterow.cpp index 4b28014..36a1f3a 100644 --- a/sql/src/updaterow.cpp +++ b/sql/src/updaterow.cpp @@ -827,7 +827,7 @@ RCODE F_Db::updateSelectedRows( FLMUINT uiTableNum, SQLQuery * pSqlQuery, COLUMN_SET * pFirstColumnSet, - FLMUINT uiNumColumnsToSet) + FLMUINT) // uiNumColumnsToSet) { RCODE rc = NE_SFLM_OK; FLMBOOL bStartedTrans = FALSE; diff --git a/sql/src/whereclause.cpp b/sql/src/whereclause.cpp index 1d7c680..4132f95 100644 --- a/sql/src/whereclause.cpp +++ b/sql/src/whereclause.cpp @@ -1082,9 +1082,9 @@ Exit: // Desc: Add an ORDER BY component //------------------------------------------------------------------------- RCODE SQLQuery::orderBy( - FLMUINT uiTableNum, - FLMUINT uiColumnNum, - FLMBOOL bDescending) + FLMUINT uiTableNum, + FLMUINT uiColumnNum, + FLMBOOL) // bDescending) { RCODE rc = NE_SFLM_OK; SQL_TABLE * pTable;