diff --git a/xflaim/src/fdynbtre.cpp b/xflaim/src/fdynbtre.cpp deleted file mode 100644 index 0bd22a0..0000000 --- a/xflaim/src/fdynbtre.cpp +++ /dev/null @@ -1,1198 +0,0 @@ -//------------------------------------------------------------------------------ -// Desc: Contains the methods for the FFixedBlk, FBtreeRoot, FBtreeLeaf, -// FBtreeNonLeaf, and FBtreeBlk classes. -// -// Tabs: 3 -// -// Copyright (c) 1998-2006 Novell, Inc. All Rights Reserved. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of version 2 of the GNU General Public -// License as published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, contact Novell, Inc. -// -// To contact Novell about this file by physical or electronic mail, -// you may find current contact information at www.novell.com -// -// $Id: fdynbtre.cpp 3112 2006-01-19 13:12:40 -0700 (Thu, 19 Jan 2006) dsanders $ -//------------------------------------------------------------------------------ - -#include "flaimsys.h" -#include "fdynsset.h" - -// Make sure that the extension is in lower case characters. - -#define FRSET_FILENAME_EXTENSION "frs" - -/**************************************************************************** - -Organization: - - These modules are orgianized by function and NOT by class. - For example, all of the searchEntry modules are together. - All of the split and getFirst/next/last... modules are together. - -****************************************************************************/ - - -/**************************************************************************** - Constructors and Setup Methods -****************************************************************************/ - -/**************************************************************************** -Desc: Set common variables -****************************************************************************/ -FFixedBlk::FFixedBlk() -{ - m_fnCompare = NULL; - m_pvUserData = NULL; - m_uiPosition = DYNSSET_POSITION_NOT_SET; - m_bDirty = FALSE; - m_pucBlkBuf = NULL; -} - -/**************************************************************************** -Desc: -****************************************************************************/ -FBtreeRoot::FBtreeRoot() -{ - int i; - - m_pFileHdl = NULL; - m_pszFileName = NULL; - m_eBlkType = ACCESS_BTREE_ROOT; - m_uiEntryOvhd = 4; - m_uiLRUCount = 1; - m_uiLevels = 1; - m_uiNewBlkAddr = 0; - m_uiHighestWrittenBlkAddr = 0; - m_uiTotalEntries = 0; - - // Initialize the cache blocks. - for( i = 0; i < FBTREE_CACHE_BLKS; i++) - { - m_CacheBlks[i].uiBlkAddr = 0xFFFFFFFF; - m_CacheBlks[i].uiLRUValue = 0; - m_CacheBlks[i].pBlk = NULL; - } -} - -/**************************************************************************** -Desc: -****************************************************************************/ -FBtreeRoot::~FBtreeRoot() -{ - int i; - - closeFile(); - - for( i = 0; i < FBTREE_CACHE_BLKS; i++) - { - if( m_CacheBlks[i].pBlk) - { - m_CacheBlks[i].pBlk->Release(); - } - } -} - -/**************************************************************************** -Desc: Allocate structures and set entry size. -****************************************************************************/ -RCODE FBtreeLeaf::setup( - FLMUINT uiEntrySize) -{ - RCODE rc = NE_XFLM_OK; - - if (RC_BAD( rc = f_calloc( DYNSSET_BLOCK_SIZE, &m_pucBlkBuf))) - { - goto Exit; - } - - m_uiEntrySize = uiEntrySize; - m_pvUserData = (void *) uiEntrySize; - reset( ACCESS_BTREE_LEAF); - nextBlk( FBTREE_END); - prevBlk( FBTREE_END); - lemBlk( FBTREE_END); - reset( ACCESS_BTREE_LEAF); - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Allocate structures and set entry size. -****************************************************************************/ -RCODE FBtreeNonLeaf::setup( - FLMUINT uiEntrySize) -{ - RCODE rc = NE_XFLM_OK; - - if (RC_BAD( rc = f_calloc( DYNSSET_BLOCK_SIZE, &m_pucBlkBuf))) - { - goto Exit; - } - - m_uiEntrySize = uiEntrySize; - m_pvUserData = (void *) uiEntrySize; - reset( ACCESS_BTREE_NON_LEAF); - nextBlk( FBTREE_END); - prevBlk( FBTREE_END); - lemBlk( FBTREE_END); - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Allocate structures and set entry size. -****************************************************************************/ -RCODE FBtreeRoot::setup( - FLMUINT uiEntrySize, - char * pszFileName) -{ - RCODE rc; - - if (RC_BAD( rc = f_calloc( DYNSSET_BLOCK_SIZE, &m_pucBlkBuf))) - { - goto Exit; - } - - m_uiEntrySize = uiEntrySize; - m_pvUserData = (void *) uiEntrySize; - reset( ACCESS_BTREE_ROOT); - m_pszFileName = pszFileName; - nextBlk( FBTREE_END); - prevBlk( FBTREE_END); - lemBlk( FBTREE_END); - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Setup the block as a new block -****************************************************************************/ -void FBtreeBlk::reset( - FBlkTypes eBlkType) -{ - m_eBlkType = eBlkType; - - if (eBlkType == ACCESS_BTREE_ROOT || eBlkType == ACCESS_BTREE_NON_LEAF) - { - m_uiEntryOvhd = 4; - } - else - { - m_uiEntryOvhd = 0; - } - m_uiNumSlots = (DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)) / - ( m_uiEntrySize + m_uiEntryOvhd); - entryCount( 0); - m_uiPosition = DYNSSET_POSITION_NOT_SET; - m_bDirty = FALSE; -} - -/**************************************************************************** -Desc: Return the next entry in the result set. If the result set - is not positioned then the first entry will be returned. -****************************************************************************/ -RCODE FBtreeBlk::getNext( - void * pvEntryBuffer) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiPos = m_uiPosition; - - // Position to the next/first entry. - - if (uiPos == DYNSSET_POSITION_NOT_SET) - { - uiPos = 0; - } - else - { - if (++uiPos > entryCount()) - { - rc = RC_SET( NE_XFLM_EOF_HIT); - goto Exit; - } - } - f_memcpy( pvEntryBuffer, ENTRY_POS(uiPos), m_uiEntrySize); - m_uiPosition = uiPos; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Return the last entry in the result set. -****************************************************************************/ -RCODE FBtreeBlk::getLast( - void * pvEntryBuffer) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiPos = entryCount(); - - // Position to the next/first entry. - - if (uiPos == 0) - { - rc = RC_SET( NE_XFLM_EOF_HIT); - goto Exit; - } - - uiPos--; - f_memcpy( pvEntryBuffer, ENTRY_POS(uiPos), m_uiEntrySize); - m_uiPosition = uiPos; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Search a btree. Position for get* or for insert. -****************************************************************************/ -RCODE FBtreeRoot::search( - void * pvEntry, - void * pvFoundEntry) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiCurLevel = m_uiLevels - 1; // Min 2 levels - FLMUINT uiBlkAddr; - - // Reset the stack - only needed for debugging. - //f_memset( m_BTStack, 0, sizeof(FBtreeBlk *) * FBTREE_MAX_LEVELS); - - // Search this root block. - - m_BTStack[ uiCurLevel] = this; - (void) searchEntry( pvEntry, &uiBlkAddr); - - while( uiCurLevel--) - { - // Read the next block and place at uiCurLevel (backwards from FS). - - if( RC_BAD( rc = readBlk( uiBlkAddr, - uiCurLevel ? ACCESS_BTREE_NON_LEAF : ACCESS_BTREE_LEAF, - &m_BTStack[ uiCurLevel] ))) - { - goto Exit; - } - - // Set the rc - only for the leaf block, otherwise rc should be ignored. - - rc = m_BTStack[ uiCurLevel]->searchEntry( pvEntry, &uiBlkAddr, - uiCurLevel ? NULL : pvFoundEntry); - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Search a single block tree. Position for get* or for insert. - Do a binary search on all of the entries to find a match. - If no match then position to the entry where an insert - will take place. -****************************************************************************/ -RCODE FBtreeBlk::searchEntry( - void * pvEntry, - FLMUINT * puiChildAddr, - void * pvFoundEntry) -{ - RCODE rc = RC_SET( NE_XFLM_NOT_FOUND); - FLMUINT uiLow; - FLMUINT uiMid; - FLMUINT uiHigh; - FLMUINT uiTblSize; - FLMINT iCompare; - - // check for zero entries. - - if (!entryCount()) - { - uiMid = 0; - goto Exit; - } - uiHigh = uiTblSize = entryCount() - 1; - uiLow = 0; - for(;;) - { - uiMid = (uiLow + uiHigh) >> 1; // (uiLow + uiHigh) / 2 - - // Use compare routine - - if (m_fnCompare) - { - iCompare = m_fnCompare( pvEntry, ENTRY_POS( uiMid), m_pvUserData); - } - else - { - iCompare = f_memcmp( pvEntry, ENTRY_POS( uiMid), m_uiEntrySize); - } - - if (iCompare == 0) - { - if (pvFoundEntry) - { - f_memcpy( pvFoundEntry, ENTRY_POS( uiMid), m_uiEntrySize); - } - rc = NE_XFLM_OK; - goto Exit; - } - - // Check if we are done - where wLow equals uiHigh or mid is at end. - - if (iCompare < 0) - { - if (uiMid == uiLow || uiLow == uiHigh) - { - break; - } - uiHigh = uiMid - 1; // Too high - } - else - { - if (uiMid == uiHigh || uiLow == uiHigh) - { - - // Go up one for the correct position? - - uiMid++; - break; - } - uiLow = uiMid + 1; // Too low - } - } - -Exit: - - m_uiPosition = uiMid; - if (puiChildAddr && blkType() != ACCESS_BTREE_LEAF) - { - if (uiMid == entryCount()) - { - *puiChildAddr = lemBlk(); - } - else - { - FLMBYTE * pucChildAddr = ENTRY_POS(uiMid) + m_uiEntrySize; - *puiChildAddr = (FLMUINT)FB2UD( pucChildAddr); - } - } - return( rc); -} - -/**************************************************************************** -Desc: Insert the entry into the btree - should be positioned -****************************************************************************/ -RCODE FBtreeRoot::insert( - void * pvEntry) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiCurLevel; - FLMBYTE ucEntryBuf[FBTREE_MAX_LEVELS][DYNSSET_MAX_FIXED_ENTRY_SIZE]; - FLMUINT uiNewBlkAddr; - - if (RC_OK( rc = m_BTStack[0]->insert( pvEntry))) - { - goto Exit; - } - - // Failed to input at the left level. Do block split(s). - // This is an iterative and NOT a recursive split algorithm. - // The debugging, and cases to test should be lots easier this way. - - f_memcpy( ucEntryBuf[0], pvEntry, m_uiEntrySize); - uiCurLevel = 0; - uiNewBlkAddr = FBTREE_END; - for(;;) - { - - // Split while adding the element. - - if (RC_BAD( rc = (m_BTStack[uiCurLevel])->split( - this, - ucEntryBuf[ uiCurLevel], - uiNewBlkAddr, - ucEntryBuf[ uiCurLevel+1], - &uiNewBlkAddr))) - { - goto Exit; - } - - uiCurLevel++; - flmAssert( uiCurLevel < m_uiLevels); - - if (RC_OK( rc = m_BTStack[uiCurLevel]->insertEntry( - ucEntryBuf[uiCurLevel], uiNewBlkAddr))) - { - goto Exit; - } - - // Only returns NE_XFLM_OK or FAILURE. - - // Root split? - - if (uiCurLevel + 1 == m_uiLevels) - { - flmAssert( m_uiLevels + 1 <= FBTREE_MAX_LEVELS); - if (m_uiLevels + 1 > FBTREE_MAX_LEVELS) - { - rc = RC_SET( NE_XFLM_BTREE_FULL); - goto Exit; - } - - // Need to split the root block. - rc = ((FBtreeRoot *)m_BTStack[uiCurLevel])->split( - ucEntryBuf[uiCurLevel], uiNewBlkAddr ); - break; - } - } - -Exit: - - if (RC_OK(rc)) - { - m_uiTotalEntries++; - } - return( rc); -} - -/**************************************************************************** -Desc: Insert the entry into the buffer. -****************************************************************************/ -RCODE FBtreeBlk::insertEntry( - void * pvEntry, - FLMUINT uiChildAddr) -{ - RCODE rc = NE_XFLM_OK; - FLMBYTE * pucCurEntry; - FLMUINT uiShiftBytes; // Always shift down - - if( entryCount() >= m_uiNumSlots) - { - rc = RC_SET( NE_XFLM_FAILURE); - goto Exit; - } - flmAssert( m_uiPosition != DYNSSET_POSITION_NOT_SET); - pucCurEntry = ENTRY_POS( m_uiPosition); - if ((uiShiftBytes = (entryCount() - m_uiPosition) * - (m_uiEntrySize + m_uiEntryOvhd)) != 0) - { - - // Big hairy assert. Finds coding bugs and corruptions. - - flmAssert( m_uiPosition * (m_uiEntrySize + m_uiEntryOvhd) + - uiShiftBytes < DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)); - - f_memmove( pucCurEntry + m_uiEntrySize + m_uiEntryOvhd, - pucCurEntry, uiShiftBytes); - } - f_memcpy( pucCurEntry, pvEntry, m_uiEntrySize); - if( m_uiEntryOvhd) - { - UD2FBA( (FLMUINT32)uiChildAddr, &pucCurEntry[m_uiEntrySize]); - } - entryCount( entryCount() + 1); - m_uiPosition++; - m_bDirty = TRUE; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Move first half of entries into new block. Reset previous block - to point to new block. Add new last entry in new block to parent. - Fixup prev/next linkages. -****************************************************************************/ -RCODE FBtreeBlk::split( - FBtreeRoot * pRoot, - FLMBYTE * pucCurEntry, // (in) Contains entry to insert - FLMUINT uiCurBlkAddr, // (in) Blk addr if non-leaf - FLMBYTE * pucParentEntry, // (out) Entry to insert into parent. - FLMUINT * puiNewBlkAddr) // (out) New blk addr to insert into parent. -{ - RCODE rc = NE_XFLM_OK; - FBtreeBlk * pPrevBlk; - FBtreeBlk * pNewBlk = NULL; - FLMBYTE * pucEntry = NULL; - FLMBYTE * pucMidEntry; - FLMBYTE * pucChildAddr; - FLMUINT uiChildAddr; - FLMUINT uiPrevBlkAddr; - FLMUINT uiMid; - FLMUINT uiPos; - FLMUINT uiMoveBytes; - FLMBOOL bInserted = FALSE; - - // Allocate a new block for the split. - - if (RC_BAD( rc = pRoot->newBlk( &pNewBlk, blkType() ))) - { - goto Exit; - } - pNewBlk->AddRef(); // Pin the block - may get flushed out. - - - // the last half into the new block, but that would force the parent - // entry to be changed. This may take a little longer, but it is much - // more easier to code. - - // Call search entry once just to setup for insert. - - (void) pNewBlk->searchEntry( ENTRY_POS( 0)); - - // get the count and move more then half into the new block. - - uiMid = (entryCount() + 5) >> 1; - uiChildAddr = FBTREE_END; - - for (uiPos = 0; uiPos < uiMid; uiPos++) - { - pucEntry = ENTRY_POS( uiPos); - if (blkType() != ACCESS_BTREE_LEAF) - { - pucChildAddr = pucEntry + m_uiEntrySize; - uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); - } - - // m_uiPosition automatically gets incremented. - - if (RC_BAD( rc = pNewBlk->insertEntry( pucEntry, uiChildAddr))) - { - RC_UNEXPECTED_ASSERT( rc); - goto Exit; - } - } - - if (m_uiPosition < uiMid) - { - - // Insert this entry now - - bInserted = TRUE; - (void) pNewBlk->searchEntry( pucCurEntry); - if (RC_BAD( rc = pNewBlk->insertEntry( pucCurEntry, uiCurBlkAddr))) - { - goto Exit; - } - } - - // Let caller insert into parent entry. This rids us of recursion. - - f_memcpy( pucParentEntry, pucEntry, m_uiEntrySize); - - // Move the rest down - - pucEntry = ENTRY_POS( 0); - pucMidEntry = ENTRY_POS( uiMid); - - entryCount( entryCount() - uiMid); - uiMoveBytes = entryCount() * (m_uiEntrySize + m_uiEntryOvhd); - flmAssert( uiMoveBytes < DYNSSET_BLOCK_SIZE - sizeof( FixedBlkHdr)); - f_memmove( pucEntry, pucMidEntry, uiMoveBytes); - - if( !bInserted) - { - - // m_uiPosition -= uiMid; - - (void) searchEntry( pucCurEntry); - if (RC_BAD( rc = insertEntry( pucCurEntry, uiCurBlkAddr))) - { - goto Exit; - } - } - - // VISIT: Could position stack to point to current element to insert. - - // Fixup the prev/next block linkages. - - if (prevBlk() != FBTREE_END) - { - if (RC_BAD( rc = pRoot->readBlk( prevBlk(), blkType(), &pPrevBlk ))) - { - goto Exit; - } - - pPrevBlk->nextBlk( pNewBlk->blkAddr()); - uiPrevBlkAddr = pPrevBlk->blkAddr(); - } - else - { - uiPrevBlkAddr = FBTREE_END; - } - pNewBlk->prevBlk( uiPrevBlkAddr); - pNewBlk->nextBlk( blkAddr()); - prevBlk( pNewBlk->blkAddr()); - - *puiNewBlkAddr = pNewBlk->blkAddr(); - -Exit: - - if (pNewBlk) - { - pNewBlk->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: Reinsert all entries given a new root block. - Caller will release 'this'. Used ONLY for building the first - ROOT and two leaves of the tree. -****************************************************************************/ -RCODE FBtreeLeaf::split( - FBtreeRoot * pNewRoot) // New Non-leaf root -{ - RCODE rc = NE_XFLM_OK; - FLMBYTE * pucEntry; - FLMUINT uiPos; - FLMUINT uiEntryCount = entryCount(); - FLMUINT uiMid = (uiEntryCount + 1) >> 1; - - if (RC_BAD( rc = pNewRoot->setupTree( ENTRY_POS(uiMid), - ACCESS_BTREE_LEAF, NULL, NULL))) - { - goto Exit; - } - - for (uiPos = 0; uiPos < uiEntryCount; uiPos++) - { - pucEntry = ENTRY_POS( uiPos); - if ((rc = pNewRoot->search( pucEntry)) != NE_XFLM_NOT_FOUND) - { - rc = RC_SET_AND_ASSERT( NE_XFLM_FAILURE); - goto Exit; - } - - if (RC_BAD( rc = pNewRoot->insert( pucEntry))) - { - goto Exit; - } - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Split the root block and make two new non-leaf blocks. - The secret here is that the root block never moves (cheers!). - This takes a little longer but is worth the work because the - root block never goes out to disk and is not in the cache. -****************************************************************************/ -RCODE FBtreeRoot::split( - void * pvCurEntry, - FLMUINT uiCurChildAddr) -{ - RCODE rc = NE_XFLM_OK; - FLMBYTE * pucEntry; - FLMBYTE * pucChildAddr; - FBtreeBlk * pLeftBlk; - FBtreeBlk * pRightBlk; - FBtreeBlk * pBlk; - FLMUINT uiChildAddr; - FLMUINT uiPos; - FLMUINT uiEntryCount = entryCount(); - FLMUINT uiMid = (uiEntryCount + 1) >> 1; - - if (RC_BAD( rc = setupTree( NULL, ACCESS_BTREE_NON_LEAF, - &pLeftBlk, &pRightBlk))) - { - goto Exit; - } - - // Call search entry once just to setup for insert. - - (void) pLeftBlk->searchEntry( ENTRY_POS( 0)); - - // Take the entries from the root block and move into leafs. - - for (uiPos = 0; uiPos <= uiMid; uiPos++) - { - pucEntry = ENTRY_POS( uiPos); - pucChildAddr = pucEntry + m_uiEntrySize; - uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); - - if (RC_BAD( rc = pLeftBlk->insertEntry( pucEntry, uiChildAddr))) - { - goto Exit; - } - } - - // Call search entry once just to setup for insert. - - (void) pRightBlk->searchEntry( ENTRY_POS( 0)); - - for (uiPos = uiMid + 1; uiPos < uiEntryCount; uiPos++) - { - pucEntry = ENTRY_POS( uiPos); - pucChildAddr = pucEntry + m_uiEntrySize; - uiChildAddr = (FLMUINT)FB2UD(pucChildAddr); - - if ((rc = pRightBlk->searchEntry( pucEntry )) != NE_XFLM_NOT_FOUND) - { - rc = RC_SET_AND_ASSERT( NE_XFLM_FAILURE); - goto Exit; - } - - if (RC_BAD( rc = pRightBlk->insertEntry( pucEntry, uiChildAddr))) - { - goto Exit; - } - } - - // Reset the root block and insert new midpoint. - - entryCount( 0); - lemBlk( pRightBlk->blkAddr()); // Duplicated just in case. - pucEntry = ENTRY_POS( uiMid); - - if ((rc = searchEntry( pucEntry )) != NE_XFLM_NOT_FOUND) - { - rc = RC_SET_AND_ASSERT( NE_XFLM_FAILURE); - goto Exit; - } - - if (RC_BAD( rc = insertEntry( pucEntry, pLeftBlk->blkAddr() ))) - { - goto Exit; - } - - // Insert the current entry (parameters) into the left or right blk. - // This could be done a number of different ways. - (void) searchEntry( pvCurEntry, &uiChildAddr); - if (RC_BAD( rc = readBlk( uiChildAddr, ACCESS_BTREE_NON_LEAF, &pBlk))) - { - goto Exit; - } - (void) pBlk->searchEntry( pvCurEntry); - if (RC_BAD( rc = pBlk->insertEntry( pvCurEntry, uiCurChildAddr))) - { - goto Exit; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Setup two child blocks for a root block. -****************************************************************************/ -RCODE FBtreeRoot::setupTree( - FLMBYTE * pucMidEntry, // If !NULL entry to insert into root. - FBlkTypes eBlkType, // Leaf or non-leaf - FBtreeBlk ** ppLeftBlk, // (out) - FBtreeBlk ** ppRightBlk) // (out) -{ - RCODE rc = NE_XFLM_OK; - FBtreeBlk * pLeftBlk = NULL; - FBtreeBlk * pRightBlk = NULL; - - if (RC_BAD( rc = newBlk( &pLeftBlk, eBlkType))) - { - goto Exit; - } - - if (RC_BAD( rc = newBlk( &pRightBlk, eBlkType))) - { - goto Exit; - } - - if (eBlkType == ACCESS_BTREE_NON_LEAF) - { - ((FBtreeNonLeaf *)pRightBlk)->lemBlk( lemBlk()); - } - - // Fix up the linkages - - pLeftBlk->nextBlk( pRightBlk->blkAddr()); - pRightBlk->prevBlk( pLeftBlk->blkAddr()); - lemBlk( pRightBlk->blkAddr()); - - if (pucMidEntry) - { - - // Add the midentry to the root block. Search to position and insert. - - searchEntry( pucMidEntry); - insertEntry( pucMidEntry, pLeftBlk->blkAddr()); - } - m_uiLevels++; - - if (ppLeftBlk) - { - *ppLeftBlk = pLeftBlk; - } - if (ppRightBlk) - { - *ppRightBlk = pRightBlk; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Read in the block or get it from the cache. -****************************************************************************/ -RCODE FBtreeRoot::readBlk( - FLMUINT uiBlkAddr, // Blk address to read - FBlkTypes eBlkType, // Expected access type to read - FBtreeBlk ** ppBlk) // (out) Return block -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiPos; - FLMUINT uiLRUValue = (FLMUINT)~0; - FLMUINT uiLRUPos = 0; - FBtreeBlk * pNewBlk; - - for (uiPos = 0; uiPos < FBTREE_CACHE_BLKS; uiPos++) - { - if (m_CacheBlks[uiPos].uiBlkAddr == uiBlkAddr) - { - goto Exit; - } - - // The ref count is used for pinning the block. - - if (m_CacheBlks[uiPos].pBlk && - m_CacheBlks[uiPos].pBlk->getRefCount() == 1 && - uiLRUValue > m_CacheBlks[uiPos].uiLRUValue) - { - uiLRUValue = m_CacheBlks[uiPos].uiLRUValue; - uiLRUPos = uiPos; - } - - // There better not be a hole by this point. - - flmAssert( m_CacheBlks[uiPos].pBlk != NULL); - } - uiPos = uiLRUPos; - - // Read from disk? - - flmAssert( m_pFileHdl != NULL); - - if (RC_BAD( rc = newCacheBlk( uiPos, &pNewBlk, eBlkType))) - { - goto Exit; - } - - // Pick the LRU block and make that object do the reading - // so it can reset all internals and get used to being a different blk. - - pNewBlk->blkAddr( uiBlkAddr); - m_CacheBlks[uiPos].uiBlkAddr = uiBlkAddr; - m_CacheBlks[uiPos].uiLRUValue = m_uiLRUCount++; - - if (RC_BAD( rc = pNewBlk->readBlk( m_pFileHdl, uiBlkAddr))) - { - - // Release the block because the reset() changed the object type. - // May hit the assert above. - - m_CacheBlks[uiPos].pBlk->Release(); - m_CacheBlks[uiPos].pBlk = NULL; - goto Exit; - } - -Exit: - - if (RC_OK(rc)) - { - *ppBlk = m_CacheBlks[uiPos].pBlk; - m_CacheBlks[uiPos].uiLRUValue = m_uiLRUCount++; - } - return( rc); -} - -/**************************************************************************** -Desc: Get a new block using an exising or newly allocated block from - the cache. Initializes the block. May be leaf or non-leaf - but NOT the root block. -****************************************************************************/ -RCODE FBtreeRoot::newBlk( - FBtreeBlk ** ppBlk, - FBlkTypes eBlkType) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiLRUValue = (FLMUINT)~0; - FLMUINT uiPos; - FLMUINT uiLRUPos = 0; - FBtreeBlk * pNewBlk; - - for (uiPos = 0; uiPos < FBTREE_CACHE_BLKS; uiPos++) - { - - // The ref count is used for pinning the block. - - if (getRefCount() == 1 && - uiLRUValue > m_CacheBlks[uiPos].uiLRUValue) - { - uiLRUValue = m_CacheBlks[uiPos].uiLRUValue; - uiLRUPos = uiPos; - } - - // use the first hole. - - if (m_CacheBlks[uiPos].pBlk == NULL) - { - uiLRUPos = uiPos; - break; - } - } - uiPos = uiLRUPos; - if (RC_BAD( rc = newCacheBlk( uiPos, &pNewBlk, eBlkType))) - { - goto Exit; - } - - pNewBlk->blkAddr( newBlkAddr()); - m_CacheBlks[uiPos].uiBlkAddr = pNewBlk->blkAddr(); - m_CacheBlks[uiPos].uiLRUValue = m_uiLRUCount++; - - pNewBlk->entryCount(0); - pNewBlk->lemBlk( FBTREE_END); - pNewBlk->nextBlk( FBTREE_END); - pNewBlk->prevBlk( FBTREE_END); - *ppBlk = pNewBlk; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Release the existing cache block and setup and alloc new blk. -****************************************************************************/ -RCODE FBtreeRoot::newCacheBlk( - FLMUINT uiCachePos, - FBtreeBlk ** ppBlk, - FBlkTypes eBlkType) -{ - RCODE rc = NE_XFLM_OK; - FBtreeBlk * pNewBlk = NULL; - - if (m_CacheBlks[uiCachePos].pBlk) - { - if (m_CacheBlks[uiCachePos].pBlk->isDirty()) - { - if (RC_BAD( rc = writeBlk( uiCachePos))) - { - goto Exit; - } - } - } - - if (m_CacheBlks[uiCachePos].pBlk != NULL && - m_CacheBlks[uiCachePos].pBlk->blkType() == eBlkType) - { - - // If block is of the same type then reset it and use it. - - pNewBlk = m_CacheBlks[uiCachePos].pBlk; - pNewBlk->reset( eBlkType); - *ppBlk = pNewBlk; - goto Exit; - } - - if (m_CacheBlks[uiCachePos].pBlk) - { - m_CacheBlks[uiCachePos].pBlk->Release(); - } - if (eBlkType == ACCESS_BTREE_LEAF) - { - FBtreeLeaf * pLeafBlk; - if ((pLeafBlk = f_new FBtreeLeaf) == NULL) - { - rc = RC_SET( NE_XFLM_MEM); - goto Exit; - } - if (RC_BAD( rc = pLeafBlk->setup( m_uiEntrySize))) - { - pLeafBlk->Release(); - goto Exit; - } - pLeafBlk->setCompareFunc( m_fnCompare, m_pvUserData); - pNewBlk = (FBtreeBlk *) pLeafBlk; - } - else - { - FBtreeNonLeaf * pNonLeafBlk; - if ((pNonLeafBlk = f_new FBtreeNonLeaf) == NULL) - { - rc = RC_SET( NE_XFLM_MEM); - goto Exit; - } - if (RC_BAD( rc = pNonLeafBlk->setup( m_uiEntrySize))) - { - pNonLeafBlk->Release(); - goto Exit; - } - pNonLeafBlk->setCompareFunc( m_fnCompare, m_pvUserData); - pNewBlk = (FBtreeBlk *) pNonLeafBlk; - } - m_CacheBlks[uiCachePos].pBlk = pNewBlk; - *ppBlk = pNewBlk; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Read the block from disk. -****************************************************************************/ -RCODE FBtreeBlk::readBlk( - IF_FileHdl * pFileHdl, - FLMUINT uiBlkAddr) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiBytesRead; - - if (RC_BAD( rc = pFileHdl->read( - uiBlkAddr * DYNSSET_BLOCK_SIZE, DYNSSET_BLOCK_SIZE, - m_pucBlkBuf, &uiBytesRead))) - { - RC_UNEXPECTED_ASSERT( rc); - goto Exit; - } - - if (blkAddr() != uiBlkAddr) - { - - // Most likely a coding error rather than an I/O error. - - goto Exit; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Write the block to disk. -****************************************************************************/ -RCODE FBtreeBlk::writeBlk( - IF_FileHdl * pFileHdl) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiBytesWritten; - FLMUINT uiBlkAddr = blkAddr(); - - if (RC_BAD( rc = pFileHdl->write( - uiBlkAddr * DYNSSET_BLOCK_SIZE, - DYNSSET_BLOCK_SIZE, - m_pucBlkBuf, - &uiBytesWritten))) - { - goto Exit; - } - - m_bDirty = FALSE; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Write all blocks that are dirty and have an addrees lower - than the input block address and then write this block. - Write in order so that - we don't have to write zeros for any block. -****************************************************************************/ -RCODE FBtreeRoot::writeBlk( - FLMUINT uiWritePos) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiPos; - FLMUINT uiHighBlkAddr = m_CacheBlks[uiWritePos].uiBlkAddr; - - if (!m_pFileHdl) - { - if (RC_BAD( rc = openFile())) - { - goto Exit; - } - } - for (uiPos = 0; uiPos < FBTREE_CACHE_BLKS; uiPos++) - { - if( (uiWritePos != uiPos) && - (m_CacheBlks[uiPos].pBlk) && - (m_CacheBlks[uiPos].uiBlkAddr >= m_uiHighestWrittenBlkAddr) && - (m_CacheBlks[uiPos].uiBlkAddr < uiHighBlkAddr) && - (m_CacheBlks[uiPos].pBlk->isDirty()) ) - { - - // Recursive call to write out lower blocks if needed. - - if (RC_BAD( rc = writeBlk( uiPos))) - { - goto Exit; - } - } - } - m_CacheBlks[ uiWritePos].pBlk->writeBlk( m_pFileHdl); - if (m_CacheBlks[uiWritePos].uiBlkAddr > m_uiHighestWrittenBlkAddr) - { - m_uiHighestWrittenBlkAddr = m_CacheBlks[uiWritePos].uiBlkAddr; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Close the file if previously opened and creates the file. -****************************************************************************/ -RCODE FBtreeRoot::openFile( void) -{ - RCODE rc = NE_XFLM_OK; - - if (!m_pFileHdl) - { - rc = gv_XFlmSysData.pFileSystem->createUniqueFile( m_pszFileName, - FRSET_FILENAME_EXTENSION, - FLM_IO_RDWR | FLM_IO_CREATE_DIR, &m_pFileHdl); - } - return( rc); -} - -/**************************************************************************** -Desc: Closes and deletes the temporary file. -****************************************************************************/ -void FBtreeRoot::closeFile( void) -{ - if (m_pFileHdl) - { - m_pFileHdl->close(); - gv_XFlmSysData.pFileSystem->deleteFile( m_pszFileName); - m_pFileHdl->Release(); - m_pFileHdl = NULL; - } -} diff --git a/xflaim/src/fdynsset.cpp b/xflaim/src/fdynsset.cpp deleted file mode 100644 index 1135f42..0000000 --- a/xflaim/src/fdynsset.cpp +++ /dev/null @@ -1,328 +0,0 @@ -//------------------------------------------------------------------------------ -// Desc: Contains the methods for FDynSearchSet class. -// -// Tabs: 3 -// -// Copyright (c) 1998-2006 Novell, Inc. All Rights Reserved. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of version 2 of the GNU General Public -// License as published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, contact Novell, Inc. -// -// To contact Novell about this file by physical or electronic mail, -// you may find current contact information at www.novell.com -// -// $Id: fdynsset.cpp 3112 2006-01-19 13:12:40 -0700 (Thu, 19 Jan 2006) dsanders $ -//------------------------------------------------------------------------------ - -#include "flaimsys.h" -#include "fdynsset.h" - -#define HASH_POS(vp) \ - (((FLMUINT)(FB2UD((FLMBYTE*)vp)) % m_uiNumSlots) * m_uiEntrySize) - -static const FLMBYTE ucZeros [ DYNSSET_MAX_FIXED_ENTRY_SIZE ] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/**************************************************************************** -Desc: Setup the result set with input values. This method must be - called and only called once. -****************************************************************************/ -RCODE FDynSearchSet::setup( - char * pszTmpDir, - FLMUINT uiEntrySize) -{ - RCODE rc = NE_XFLM_OK; - FHashBlk * pHashBlk; - - // Set the input variables. - - if( pszTmpDir ) - { - f_strcpy( m_szFileName, pszTmpDir); // Dest <- src - } - else - { - f_memset( m_szFileName, 0, F_PATH_MAX_SIZE); - } - m_uiEntrySize = uiEntrySize; - - if ((pHashBlk = f_new FHashBlk) == NULL) - { - rc = RC_SET( NE_XFLM_MEM); - goto Exit; - } - pHashBlk->setup( uiEntrySize); - m_pAccess = (FFixedBlk *) pHashBlk; - m_pvUserData = (void *) uiEntrySize; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Add a fixed length entry to the dynamic search result set. -****************************************************************************/ -RCODE FDynSearchSet::addEntry( - void * pvEntry) -{ - RCODE rc = NE_XFLM_OK; - -Add_Again: - - if (RC_OK( rc = m_pAccess->search( pvEntry))) - { - rc = RC_SET( NE_XFLM_EXISTS); - } - else if (rc == NE_XFLM_NOT_FOUND) - { - - // Insert the entry. - - if ((rc = m_pAccess->insert( pvEntry)) == NE_XFLM_FAILURE) - { - // Find the type of access method implemented - - if (m_pAccess->blkType() == ACCESS_HASH) - { - FBtreeLeaf * pBtreeBlk; - FLMBYTE ucEntryBuffer[ DYNSSET_MAX_FIXED_ENTRY_SIZE]; - - // Go from a hash to a b-tree object. Alloc and move stuff over. - - if ((pBtreeBlk = f_new FBtreeLeaf) == NULL) - { - rc = RC_SET( NE_XFLM_MEM); - goto Exit; - } - pBtreeBlk->setup( m_uiEntrySize); - pBtreeBlk->setCompareFunc( m_fnCompare, m_pvUserData); - for( rc = m_pAccess->getFirst( ucEntryBuffer ); - RC_OK(rc); - rc = m_pAccess->getNext( ucEntryBuffer) ) - { - // Call search to setup for insert. - (void) pBtreeBlk->search( ucEntryBuffer); - if (RC_BAD( rc = pBtreeBlk->insert( ucEntryBuffer))) - { - pBtreeBlk->Release(); - goto Exit; - } - } - rc = NE_XFLM_OK; - m_pAccess->Release(); - m_pAccess = pBtreeBlk; - goto Add_Again; - } - else if( m_pAccess->blkType() == ACCESS_BTREE_LEAF) - { - FBtreeRoot * pFullBtree; - - // Go from 1 block to 3 changing root blocks and free m_pAccess - // All new splits will be taken care of automatically. - - if ((pFullBtree = f_new FBtreeRoot) == NULL) - { - rc = RC_SET( NE_XFLM_MEM); - goto Exit; - } - if( RC_BAD( rc = pFullBtree->setup( m_uiEntrySize, m_szFileName))) - { - pFullBtree->Release(); - goto Exit; - } - pFullBtree->setCompareFunc( m_fnCompare, m_pvUserData); - if (RC_BAD( rc = ((FBtreeLeaf *)m_pAccess)->split( pFullBtree))) - { - goto Exit; - } - m_pAccess->Release(); - m_pAccess = pFullBtree; - goto Add_Again; - } - else - { - rc = RC_SET_AND_ASSERT( NE_XFLM_FAILURE); - goto Exit; - } - } - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Find matching entry. Position for Get* or for insert. -****************************************************************************/ -RCODE FHashBlk::search( - void * pvEntry, - void * pvFoundEntry) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiHashPos = HASH_POS( pvEntry); - FLMINT iCompare; - - for (;;) - { - - // If all zeros then setup to insert at this position. - - if (!f_memcmp( &m_pucBlkBuf[ uiHashPos], ucZeros, m_uiEntrySize)) - { - rc = RC_SET( NE_XFLM_NOT_FOUND); - goto Exit; - } - - if (m_fnCompare) - { - iCompare = m_fnCompare( pvEntry, &m_pucBlkBuf[ uiHashPos], - m_pvUserData); - } - else - { - iCompare = f_memcmp( pvEntry, &m_pucBlkBuf[ uiHashPos], - m_uiEntrySize); - } - - if (iCompare == 0) - { - - // Found match. - - if (pvFoundEntry) - { - f_memcpy( pvFoundEntry, &m_pucBlkBuf[ uiHashPos], m_uiEntrySize); - } - break; - } - - // Go to the next entry - - uiHashPos += m_uiEntrySize; - if (uiHashPos >= DYNSSET_HASH_BUFFER_SIZE) - { - uiHashPos = 0; - } - } - -Exit: - - m_uiPosition = uiHashPos; - return( rc); -} - -/**************************************************************************** -Desc: Insert the entry into the buffer. -****************************************************************************/ -RCODE FHashBlk::insert( - void * pvEntry) -{ - RCODE rc = NE_XFLM_OK; - - if( getTotalEntries() > ((m_uiNumSlots * 7) / 10)) - { - rc = RC_SET( NE_XFLM_FAILURE); - goto Exit; - } - - f_memcpy( &m_pucBlkBuf[ m_uiPosition], pvEntry, m_uiEntrySize); - m_uiTotalEntries++; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Return the next entry in the result set. If the result set - is not positioned then the first entry will be returned. -****************************************************************************/ -RCODE FHashBlk::getNext( - void * pvEntryBuffer) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiHashPos; - - // Position to the next/first entry. - - if (m_uiPosition == DYNSSET_POSITION_NOT_SET) - { - uiHashPos = 0; - } - else - { - uiHashPos = m_uiPosition + m_uiEntrySize; - } - - for ( ; ; uiHashPos += m_uiEntrySize) - { - if (uiHashPos >= DYNSSET_HASH_BUFFER_SIZE) - { - rc = RC_SET( NE_XFLM_EOF_HIT); - goto Exit; - } - - // If all zeros then setup to insert at this position. - - if (f_memcmp( &m_pucBlkBuf[ uiHashPos], ucZeros, m_uiEntrySize)) - { - f_memcpy( pvEntryBuffer, &m_pucBlkBuf[ uiHashPos], m_uiEntrySize); - m_uiPosition = uiHashPos; - goto Exit; - } - } - -Exit: - - return rc; -} - -/**************************************************************************** -Desc: Returns the last entry in the result set. -****************************************************************************/ -RCODE FHashBlk::getLast( - void * pvEntryBuffer) -{ - RCODE rc = NE_XFLM_OK; - FLMUINT uiHashPos; - - // Position to the next/first entry. - - uiHashPos = DYNSSET_HASH_BUFFER_SIZE; - - for( ; ; ) - { - uiHashPos -= m_uiEntrySize; - - // If all zeros then setup to insert at this position. - - if (f_memcmp( &m_pucBlkBuf[ uiHashPos], ucZeros, m_uiEntrySize)) - { - f_memcpy( pvEntryBuffer, &m_pucBlkBuf[ uiHashPos], m_uiEntrySize); - m_uiPosition = uiHashPos; - goto Exit; - } - if (uiHashPos == 0) - { - rc = RC_SET( NE_XFLM_EOF_HIT); - goto Exit; - } - } - -Exit: - - return( rc); -} diff --git a/xflaim/src/fdynsset.h b/xflaim/src/fdynsset.h deleted file mode 100644 index be14986..0000000 --- a/xflaim/src/fdynsset.h +++ /dev/null @@ -1,672 +0,0 @@ -//------------------------------------------------------------------------------ -// Desc: FLAIM Dynamic search result set class. -// -// Tabs: 3 -// -// Copyright (c) 1998-2000, 2002-2006 Novell, Inc. All Rights Reserved. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of version 2 of the GNU General Public -// License as published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, contact Novell, Inc. -// -// To contact Novell about this file by physical or electronic mail, -// you may find current contact information at www.novell.com -// -// $Id: fdynsset.h 3108 2006-01-19 13:05:19 -0700 (Thu, 19 Jan 2006) dsanders $ -//------------------------------------------------------------------------------ - -#ifndef FDYNSSET_H -#define FDYNSSET_H - -/***************************************************************************** -***** -** Definitions -***** -*****************************************************************************/ - -/* -A block size of 8K will perform well in minimizing the number of reads -to obtain a block. A 6K may perform better if the file is located -across the network. -*/ - -#define DYNSSET_BLOCK_SIZE 0x4000 -#define DYNSSET_HASH_BUFFER_SIZE 0x2000 -#define DYNSSET_MIN_FIXED_ENTRY_SIZE 4 -// Change ucZeros in fdynsset.cpp if this changes. -#define DYNSSET_MAX_FIXED_ENTRY_SIZE 32 -#define DYNSSET_POSITION_NOT_SET 0xFFFFFFFF - -#define FBTREE_CACHE_BLKS 32 -#define FBTREE_END 0xFFFFFFFF -#define FBTREE_MAX_LEVELS 4 - -typedef int (* FDYNSET_COMPARE_FUNC)( - void * pvData1, - void * pvData2, - void * pvUserData); - - -/***************************************************************************** -***** -** Forward References -***** -*****************************************************************************/ - -class FDynSearchSet; -class FHashBlk; -class FBtreeBlk; -class FBtreeRoot; -class FBtreeNonLeaf; -class FBtreeLeaf; - -enum eBlkTypes -{ - ACCESS_HASH, - ACCESS_BTREE_LEAF, - ACCESS_BTREE_ROOT, - ACCESS_BTREE_NON_LEAF -}; -typedef enum eBlkTypes FBlkTypes; - - -/*=========================================================================== - Virtual FFixedBlk -===========================================================================*/ -class FFixedBlk : public F_Object -{ -public: - - FFixedBlk(); - ~FFixedBlk() - { - } - - /* virtual methods that must be implemented */ - - FBlkTypes blkType() - { - return m_eBlkType; - } - - virtual RCODE getCurrent( - void * pvEntryBuffer) = 0; - - virtual RCODE getFirst( - void * pvEntryBuffer) = 0; - - virtual RCODE getLast( - void * pvEntryBuffer) = 0; - - virtual RCODE getNext( - void * pvEntryBuffer) = 0; - - virtual FLMUINT getTotalEntries() = 0; - - virtual RCODE insert( - void * pvEntry) = 0; - - FINLINE FLMBOOL isDirty( void) - { - return( m_bDirty); - } - - virtual RCODE search( - void * pvEntry, - void * pvFoundEntry = NULL) = 0; - - void setCompareFunc( - FDYNSET_COMPARE_FUNC fnCompare, - void * pvUserData) - { - m_fnCompare = fnCompare; - m_pvUserData = pvUserData; - } - -protected: - - // Variables - - FDYNSET_COMPARE_FUNC m_fnCompare; - void * m_pvUserData; - FBlkTypes m_eBlkType; - FLMUINT m_uiEntrySize; - FLMUINT m_uiNumSlots; - FLMUINT m_uiPosition; - FLMBOOL m_bDirty; - FLMBYTE * m_pucBlkBuf; -}; - - -/***************************************************************************** -***** -** Result Set Class Definitions -** Source: fdynsset.cpp -***** -*****************************************************************************/ -class FDynSearchSet : public F_Object -{ - -public: - - FDynSearchSet() - { - m_fnCompare = NULL; - m_pvUserData = NULL; - m_uiEntrySize = 0; - m_pAccess = NULL; - } - - ~FDynSearchSet() - { - if (m_pAccess) - { - m_pAccess->Release(); - } - } - - RCODE setup( - char * pszTmpDir, - FLMUINT uiEntrySize); - - FINLINE void setCompareFunc( - FDYNSET_COMPARE_FUNC fnCompare, - void * pvUserData - ) - { - m_fnCompare = fnCompare; - m_pvUserData = pvUserData; - m_pAccess->setCompareFunc( fnCompare, pvUserData); - } - - RCODE addEntry( - void * pvEntry); - - FINLINE RCODE findMatch( - void * pvMatchEntry, - void * pvFoundEntry - ) - { - return m_pAccess->search( pvMatchEntry, pvFoundEntry); - } - - FINLINE FLMUINT getEntrySize( void) - { - return m_uiEntrySize; - } - - FINLINE FLMUINT getTotalEntries( void) - { - return m_pAccess->getTotalEntries(); - } - -private: - - // Variables - - FDYNSET_COMPARE_FUNC m_fnCompare; - void * m_pvUserData; - FLMUINT m_uiEntrySize; - FFixedBlk * m_pAccess; - char m_szFileName [F_PATH_MAX_SIZE]; -}; - -/*=========================================================================== - Block Header Definition - -Desc: Actually stored as the first section of each block. - We can write this structure because the same process will - read the block header i.e. portability is not a problem. -===========================================================================*/ - -typedef struct -{ - FLMUINT uiBlkAddr; - FLMUINT uiPrevBlkAddr; - FLMUINT uiNextBlkAddr; - FLMUINT uiLEMAddr; - FLMUINT uiNumEntries; -} FixedBlkHdr; - -/*=========================================================================== - Fixed Length HASH Access Method -===========================================================================*/ -class FHashBlk : public FFixedBlk -{ -public: - - FHashBlk() - { - // Base class constructors are called before this constructor is. - - m_eBlkType = ACCESS_HASH; - m_pucBlkBuf = m_ucHashBlk; - f_memset( m_ucHashBlk, 0, sizeof( m_ucHashBlk)); - m_uiTotalEntries = 0; - } - - ~FHashBlk() - { - // Set to NULL so we don't free the block - m_pucBlkBuf = NULL; - } - - FINLINE RCODE setup( - FLMUINT uiEntrySize - ) - { - m_uiEntrySize = uiEntrySize; - m_uiNumSlots = DYNSSET_HASH_BUFFER_SIZE / uiEntrySize; - return( NE_XFLM_OK); - } - - FINLINE RCODE getCurrent( - void * pvEntryBuffer - ) - { - - // Position to the next/first entry. - - if (m_uiPosition == DYNSSET_POSITION_NOT_SET) - { - return RC_SET( NE_XFLM_NOT_FOUND); - } - - f_memcpy( pvEntryBuffer, &m_pucBlkBuf[ m_uiPosition], m_uiEntrySize); - return( NE_XFLM_OK); - } - - FINLINE RCODE getFirst( - void * pvEntryBuffer - ) - { - m_uiPosition = DYNSSET_POSITION_NOT_SET; - return( getNext( pvEntryBuffer)); - } - - RCODE getLast( - void * pvEntryBuffer); - - RCODE getNext( - void * pvEntryBuffer); - - FINLINE FLMUINT getTotalEntries( void) - { - return m_uiTotalEntries; - } - - RCODE insert( - void * pvEntry); - - RCODE search( - void * pvEntry, - void * pvFoundEntry = NULL); - -private: - - FLMUINT m_uiTotalEntries; - // Allocate the hash block to save 1 allocation. - // We need to make the hash as fast as possible. - FLMBYTE m_ucHashBlk[ DYNSSET_HASH_BUFFER_SIZE]; -}; - - -/*=========================================================================== - Virtual FBtreeBlk -===========================================================================*/ - -// Leaf and non-leaf entry position. Don't do any ++ or -- ! ! ! ! - -#define ENTRY_POS(uiPos) (m_pucBlkBuf + sizeof( FixedBlkHdr) + \ - (uiPos * (m_uiEntrySize+m_uiEntryOvhd))) - -class FBtreeBlk : public FFixedBlk -{ -public: - - FBtreeBlk() - { - } - - ~FBtreeBlk() - { - if (m_pucBlkBuf) - { - f_free( &m_pucBlkBuf); - } - } - - // virtual methods that must be implemented - - FINLINE RCODE getCurrent( - void * pvEntryBuffer - ) - { - // Position to the next/first entry. - - if (m_uiPosition == DYNSSET_POSITION_NOT_SET) - { - return RC_SET( NE_XFLM_NOT_FOUND); - } - - f_memcpy( pvEntryBuffer, ENTRY_POS( m_uiPosition), m_uiEntrySize); - return( NE_XFLM_OK); - } - - FINLINE RCODE getFirst( - void * pvEntryBuffer - ) - { - m_uiPosition = DYNSSET_POSITION_NOT_SET; - return( getNext( pvEntryBuffer)); - } - - RCODE getLast( - void * pvEntryBuffer); - - RCODE getNext( - void * pvEntryBuffer); - - RCODE readBlk( - IF_FileHdl * pFileHdl, - FLMUINT uiBlkAddr); - - void reset( - FBlkTypes eBlkType); - - RCODE split( - FBtreeRoot * pParent, - FLMBYTE * pucCurEntry, - FLMUINT uiCurBlkAddr, - FLMBYTE * pucParentEntry, - FLMUINT * puiNewBlkAddr); - - RCODE writeBlk( - IF_FileHdl * pFileHdl); - - // Virtual methods - - virtual FLMUINT getTotalEntries( void) = 0; - - virtual RCODE insert( - void * pvEntry) = 0; - - virtual RCODE search( - void * pvEntry, - void * pvFoundEntry = NULL) = 0; - - virtual RCODE searchEntry( - void * pvEntry, - FLMUINT * puiChildAddr = NULL, - void * pvFoundEntry = NULL); - - // Implemented as inline functions. - // Even though these are b-tree specific - keep them here to - // avoid having a b-tree block class. Most are not used for hash. - - FINLINE FLMUINT blkAddr( void) - { - return( ((FixedBlkHdr *)m_pucBlkBuf)->uiBlkAddr); - } - - FINLINE void blkAddr( - FLMUINT uiBlkAddr) - { - ((FixedBlkHdr *)m_pucBlkBuf)->uiBlkAddr = uiBlkAddr; - m_bDirty = TRUE; - } - - // Get and set the number of entries in the block - - FINLINE FLMUINT entryCount( void) - { - return( ((FixedBlkHdr *)m_pucBlkBuf)->uiNumEntries); - } - - FINLINE void entryCount( - FLMUINT uiNumEntries) - { - ((FixedBlkHdr *)m_pucBlkBuf)->uiNumEntries = uiNumEntries; - m_bDirty = TRUE; - } - - RCODE insertEntry( - void * pvEntry, - FLMUINT uiChildAddr = FBTREE_END); - - - // Get and set the last element marker in the block. - - FINLINE FLMUINT lemBlk( void) - { - return( ((FixedBlkHdr *)m_pucBlkBuf)->uiLEMAddr); - } - - FINLINE void lemBlk( - FLMUINT uiLEMAddr) - { - ((FixedBlkHdr *)m_pucBlkBuf)->uiLEMAddr = uiLEMAddr; - m_bDirty = TRUE; - } - - // Get and set the next block address element - - FINLINE FLMUINT nextBlk( void) - { - return( ((FixedBlkHdr *)m_pucBlkBuf)->uiNextBlkAddr); - } - - FINLINE void nextBlk( - FLMUINT uiBlkAddr) - { - ((FixedBlkHdr *)m_pucBlkBuf)->uiNextBlkAddr = uiBlkAddr; - m_bDirty = TRUE; - } - - // Get and set the previous block address element - - FINLINE FLMUINT prevBlk( void) - { - return( ((FixedBlkHdr *)m_pucBlkBuf)->uiPrevBlkAddr); - } - - FINLINE void prevBlk( - FLMUINT uiBlkAddr) - { - ((FixedBlkHdr *)m_pucBlkBuf)->uiPrevBlkAddr = uiBlkAddr; - m_bDirty = TRUE; - } - -protected: - - // Variables - - FLMUINT m_uiEntryOvhd; // Overhead in the entry. -}; - - -/*=========================================================================== - Fixed Length B-tree Leaf - may be a root -===========================================================================*/ - -class FBtreeLeaf : public FBtreeBlk -{ -public: - - FBtreeLeaf() - { - m_eBlkType = ACCESS_BTREE_LEAF; - m_uiEntryOvhd = 0; - } - - ~FBtreeLeaf() - { - } - - RCODE setup( - FLMUINT uiEntrySize); - - FINLINE FLMUINT getTotalEntries( void) - { - return( (FLMUINT)entryCount()); - } - - FINLINE RCODE insert( - void * pvEntry) - { - return( insertEntry( pvEntry, FBTREE_END)); - } - - FINLINE RCODE search( - void * pvEntry, - void * pvFoundEntry = NULL) - { - return( searchEntry( pvEntry, NULL, pvFoundEntry)); - } - - RCODE split( - FBtreeRoot * pNewRoot); - -}; - -typedef struct -{ - FLMUINT uiBlkAddr; - FLMUINT uiLRUValue; - FBtreeBlk * pBlk; // Points to leaf or non-leaf block -} FBTREE_CACHE; - -/*=========================================================================== - Fixed Length B-tree non-leaf block -===========================================================================*/ - -class FBtreeNonLeaf : public FBtreeBlk -{ -public: - - FBtreeNonLeaf() - { - m_eBlkType = ACCESS_BTREE_NON_LEAF; - m_uiEntryOvhd = sizeof( FLMUINT32); - } - - ~FBtreeNonLeaf() - { - } - - RCODE setup( - FLMUINT uiEntrySize); - - FINLINE FLMUINT getTotalEntries( void) - { - return( (FLMUINT) entryCount()); - } - - FINLINE RCODE insert( - void * // pvEntry - ) - { - return( NE_XFLM_OK); - } - - FINLINE RCODE search( - void *, // pvEntry, - void * pvFoundEntry = NULL - ) - { - F_UNREFERENCED_PARM( pvFoundEntry); - flmAssert( 0); - return( NE_XFLM_OK); - } -}; - -/*=========================================================================== - Fixed Length B-tree Non-Leaf Root -===========================================================================*/ -class FBtreeRoot : public FBtreeNonLeaf -{ -public: - FBtreeRoot(); - ~FBtreeRoot(); - - RCODE setup( - FLMUINT uiEntrySize, - char * pszFileName); - - - void closeFile( void); - - FINLINE FLMUINT getTotalEntries( void) - { - return( m_uiTotalEntries); - } - - RCODE insert( - void * pvEntry); - - RCODE newBlk( - FBtreeBlk ** ppBlk, - FBlkTypes eBlkType); - - FINLINE FLMUINT newBlkAddr( void) - { - return( m_uiNewBlkAddr++); - } - - RCODE newCacheBlk( - FLMUINT uiCachePos, - FBtreeBlk ** ppBlk, - FBlkTypes eBlkType); - - RCODE openFile( void); - - RCODE readBlk( - FLMUINT uiBlkAddr, - FBlkTypes eBlkType, - FBtreeBlk ** ppBlk); - - RCODE search( - void * pvEntry, - void * pvFoundEntry = NULL); - - RCODE setupTree( - FLMBYTE * pucMidEntry, // If !NULL entry to insert into root. - FBlkTypes eBlkType, // Leaf or non-leaf - FBtreeBlk ** ppLeftBlk, // (out) - FBtreeBlk ** ppRightBlk); // (out) - - RCODE split( - void * pvCurEntry, - FLMUINT uiCurChildAddr); - - RCODE writeBlk( - FLMUINT uiWritePos); - -private: - - FLMUINT m_uiLevels; // Number of levels in the b-tree - FLMUINT m_uiTotalEntries; // Count of total entries - FLMUINT m_uiNewBlkAddr; // Next new blk addr. - FLMUINT m_uiHighestWrittenBlkAddr; - - IF_FileHdl * m_pFileHdl; // File handle or NULL if not open. - char * m_pszFileName; // File created for result set or default. - - // Cache of 'n' blocks to apply LRU algorithm. - - FLMUINT m_uiLRUCount; // Count to find least rec. used. - FBTREE_CACHE m_CacheBlks[ FBTREE_CACHE_BLKS]; - - // B-tree stack. - FBtreeBlk * m_BTStack[ FBTREE_MAX_LEVELS]; -}; - -#endif // ifndef FRSET_H diff --git a/xflaim/src/flaimsys.h b/xflaim/src/flaimsys.h index b558262..53c870a 100644 --- a/xflaim/src/flaimsys.h +++ b/xflaim/src/flaimsys.h @@ -72,9 +72,6 @@ class F_DbInfo; class F_KeyCollector; class FSIndexCursor; class FSCollectionCursor; -class FlmRecord; -class FlmDefaultRec; -class FDynSearchSet; class F_CachedBlock; class F_CachedNode; class F_GlobalCacheMgr; @@ -4692,7 +4689,7 @@ private: FLMUINT m_uiObjectListSize; FLMUINT m_uiObjectCount; FLMBOOL m_bRemoveDups; - FDynSearchSet * m_pDocIdSet; + F_DynSearchSet * m_pDocIdSet; FLMUINT m_uiIndex; FLMBOOL m_bIndexSet; FLMUINT m_uiTimeLimit; diff --git a/xflaim/src/fquery.cpp b/xflaim/src/fquery.cpp index 9788416..4a7ab12 100644 --- a/xflaim/src/fquery.cpp +++ b/xflaim/src/fquery.cpp @@ -26,7 +26,6 @@ #include "flaimsys.h" #include "fquery.h" #include "fscursor.h" -#include "fdynsset.h" #define MIN_OPT_COST 8 @@ -10532,7 +10531,7 @@ RCODE F_Query::getAppNode( { if (RC_BAD( rc = m_pDocIdSet->findMatch( &ui64DocId, NULL))) { - if (rc != NE_XFLM_NOT_FOUND) + if (rc != NE_FLM_NOT_FOUND) { goto Exit; } @@ -11058,7 +11057,7 @@ RCODE F_Query::getKey( if (RC_BAD( rc = m_pDocIdSet->findMatch( &ui64DocId, NULL))) { - if (rc != NE_XFLM_NOT_FOUND) + if (rc != NE_FLM_NOT_FOUND) { goto Exit; } @@ -11415,7 +11414,7 @@ RCODE F_Query::getANode( if (RC_BAD( rc = m_pDocIdSet->findMatch( &ui64DocId, NULL))) { - if (rc != NE_XFLM_NOT_FOUND) + if (rc != NE_FLM_NOT_FOUND) { goto Exit; } @@ -12317,7 +12316,7 @@ RCODE F_Query::getDocFromIndexScan( ui64DocId = key.getDocumentID(); if (RC_BAD( rc = m_pDocIdSet->findMatch( &ui64DocId, NULL))) { - if (rc != NE_XFLM_NOT_FOUND) + if (rc != NE_FLM_NOT_FOUND) { goto Exit; } @@ -13658,7 +13657,7 @@ RCODE F_Query::allocDupCheckSet( void) m_pDocIdSet = NULL; } - if ((m_pDocIdSet = f_new FDynSearchSet) == NULL) + if ((m_pDocIdSet = f_new F_DynSearchSet) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; @@ -13737,7 +13736,7 @@ RCODE F_Query::checkIfDup( if (RC_BAD( rc = m_pDocIdSet->addEntry( &ui64DocId))) { - if (rc == NE_XFLM_EXISTS) + if (rc == NE_FLM_EXISTS) { *pbPassed = FALSE; rc = NE_XFLM_OK; diff --git a/xflaim/src/fscursor.cpp b/xflaim/src/fscursor.cpp index 8d5a612..92e08d2 100644 --- a/xflaim/src/fscursor.cpp +++ b/xflaim/src/fscursor.cpp @@ -137,7 +137,7 @@ RCODE FSIndexCursor::allocDupCheckSet( void) m_pNodeIdSet->Release(); m_pNodeIdSet = NULL; } - if ((m_pNodeIdSet = f_new FDynSearchSet) == NULL) + if ((m_pNodeIdSet = f_new F_DynSearchSet) == NULL) { rc = RC_SET( NE_XFLM_MEM); goto Exit; @@ -214,7 +214,7 @@ RCODE FSIndexCursor::checkIfDup( if (RC_BAD( rc = m_pNodeIdSet->addEntry( &ui64NodeId))) { - if (rc == NE_XFLM_EXISTS) + if (rc == NE_FLM_EXISTS) { *pbDup = TRUE; rc = NE_XFLM_OK; @@ -877,7 +877,7 @@ RCODE FSIndexCursor::firstKey( if (RC_BAD( rc = m_pNodeIdSet->addEntry( &ui64NodeId))) { - flmAssert( rc != NE_XFLM_EXISTS); + flmAssert( rc != NE_FLM_EXISTS); goto Exit; } } @@ -1116,7 +1116,7 @@ RCODE FSIndexCursor::lastKey( if (RC_BAD( rc = m_pNodeIdSet->addEntry( &ui64NodeId))) { - flmAssert( rc != NE_XFLM_EXISTS); + flmAssert( rc != NE_FLM_EXISTS); goto Exit; } } diff --git a/xflaim/src/fscursor.h b/xflaim/src/fscursor.h index b165ef3..30c3b8f 100644 --- a/xflaim/src/fscursor.h +++ b/xflaim/src/fscursor.h @@ -26,8 +26,6 @@ #ifndef FSCURSOR_H #define FSCURSOR_H -#include "fdynsset.h" - typedef struct KeyPosition { FLMBYTE ucKey [XFLM_MAX_KEY_SIZE]; @@ -185,7 +183,7 @@ private: FLMUINT m_uiCurKeyDataLen; F_Btree * m_pbTree; FLMBOOL m_bTreeOpen; - FDynSearchSet * m_pNodeIdSet; + F_DynSearchSet * m_pNodeIdSet; FLMBOOL m_bElimDups; FLMBOOL m_bMovingForward; IXKeyCompare m_ixCompare;