/*API~*********************************************************************** Area : RETRIEVAL Desc: Retrieves a key from an index based on a passed-in GEDCOM tree and DRN. *END************************************************************************/ RCODE F_Db::keyRetrieve( FLMUINT uiIndex, // [IN] Index number. IF_DataVector * ifpSearchKey, // [IN] Pointer to the search key. FLMUINT uiFlags, // [IN] Flag (XFLM_FIRST, XFLM_LAST, XFLM_EXCL, XFLM_INCL, // XFLM_EXACT, XFLM_KEY_EXACT IF_DataVector * ifpFoundKey // [OUT] Returns key that was found - may also have data components. ) { RCODE rc = NE_XFLM_OK; IXD * pIxd = NULL; LFILE * pLFile; FLMBYTE * pucSearchKey = NULL; FLMBYTE * pucFoundKey = NULL; void * pvMark = m_tempPool.poolMark(); FLMUINT uiSearchKeyLen = 0; FLMUINT uiFoundKeyLen; FLMUINT uiOriginalFlags; F_Btree * pbtree = NULL; FLMUINT uiDataLen; FLMBOOL bStartedTrans = FALSE; FLMUINT uiIdMatchFlags = uiFlags & (XFLM_MATCH_IDS | XFLM_MATCH_DOC_ID); IXKeyCompare compareObject; FLMBOOL bCompareDocId = FALSE; FLMBOOL bCompareNodeIds = FALSE; F_DataVector * pSearchKey = (F_DataVector *)ifpSearchKey; F_DataVector * pFoundKey = (F_DataVector *)ifpFoundKey; // See if the database is being forced to close if (RC_BAD( rc = checkState( __FILE__, __LINE__))) { goto Exit; } // If we are not in a transaction, we cannot read. if (m_eTransType == XFLM_NO_TRANS) { if( RC_BAD( rc = transBegin( XFLM_READ_TRANS))) { goto Exit; } bStartedTrans = TRUE; } // See if we have a transaction going which should be aborted. if( RC_BAD( m_AbortRc)) { rc = RC_SET( NE_XFLM_ABORT_TRANS); goto Exit; } // Allocate key buffers. if (pSearchKey) { if (RC_BAD( rc = m_tempPool.poolAlloc( XFLM_MAX_KEY_SIZE, (void **)&pucSearchKey))) { goto Exit; } } if (RC_BAD( rc = m_tempPool.poolAlloc( XFLM_MAX_KEY_SIZE, (void **)&pucFoundKey))) { goto Exit; } // Make sure it is a valid index definition if (RC_BAD( rc = m_pDict->getIndex( uiIndex, &pLFile, &pIxd))) { goto Exit; } if (RC_BAD( rc = flushKeys())) { goto Exit; } if (uiFlags & XFLM_FIRST || (!pSearchKey && !(uiFlags & XFLM_FIRST) && !(uiFlags & XFLM_LAST))) { uiOriginalFlags = uiFlags = XFLM_FIRST; } else if (uiFlags & XFLM_LAST) { uiOriginalFlags = uiFlags = XFLM_LAST; } else { uiOriginalFlags = uiFlags; if( !(uiIdMatchFlags & XFLM_MATCH_IDS)) { flmAssert( !(uiFlags & XFLM_KEY_EXACT)); if (uiFlags & XFLM_EXCL) { uiFlags = XFLM_EXCL; } else if (uiFlags & XFLM_EXACT) { uiOriginalFlags = XFLM_EXACT | XFLM_KEY_EXACT; uiFlags = XFLM_INCL; } else { uiFlags = XFLM_INCL; } } else { if (uiFlags & XFLM_EXACT) { flmAssert( !(uiFlags & XFLM_KEY_EXACT)); uiFlags = XFLM_EXACT; } else if (uiFlags & XFLM_EXCL) { uiFlags = XFLM_EXCL; } else { uiFlags = XFLM_INCL; } } if (RC_BAD( rc = pSearchKey->outputKey( pIxd, uiIdMatchFlags, pucSearchKey, XFLM_MAX_KEY_SIZE, &uiSearchKeyLen, SEARCH_KEY_FLAG))) { goto Exit; } // If we are not matching on the IDs and this is an XFLM_EXCL // search, tack on a 0xFF for the IDs, which should get us past // all keys that match. We need to turn on the match IDs flags // in this case so that the comparison routine will match on the // 0xFF. if (!uiIdMatchFlags && (uiFlags & XFLM_EXCL)) { pucSearchKey [uiSearchKeyLen++] = 0xFF; bCompareDocId = TRUE; bCompareNodeIds = TRUE; } else { if (uiIdMatchFlags & XFLM_MATCH_IDS) { bCompareNodeIds = TRUE; bCompareDocId = TRUE; } else if (uiIdMatchFlags & XFLM_MATCH_DOC_ID) { bCompareDocId = TRUE; } } } compareObject.setIxInfo( this, pIxd); compareObject.setCompareNodeIds( bCompareNodeIds); compareObject.setCompareDocId( bCompareDocId); compareObject.setSearchKey( pSearchKey); // Get a btree if (RC_BAD( rc = gv_XFlmSysData.pBtPool->btpReserveBtree( &pbtree))) { goto Exit; } if( RC_BAD( rc = pbtree->btOpen( this, pLFile, (pIxd->uiFlags & IXD_ABS_POS) ? TRUE : FALSE, (pIxd->pFirstData) ? TRUE : FALSE, &compareObject))) { goto Exit; } // Search the for the key if (uiSearchKeyLen) { f_memcpy( pucFoundKey, pucSearchKey, uiSearchKeyLen); } uiFoundKeyLen = uiSearchKeyLen; if( RC_BAD( rc = pbtree->btLocateEntry( pucFoundKey, XFLM_MAX_KEY_SIZE, &uiFoundKeyLen, uiFlags, NULL, &uiDataLen))) { if (rc == NE_XFLM_EOF_HIT && uiOriginalFlags & XFLM_EXACT) { rc = RC_SET( NE_XFLM_NOT_FOUND); } goto Exit; } // See if we are in the same key if (uiOriginalFlags & XFLM_KEY_EXACT) { FLMINT iTmpCmp; if (RC_BAD( rc = ixKeyCompare( this, pIxd, (F_DataVector *)pSearchKey, NULL, NULL, (uiIdMatchFlags == XFLM_MATCH_DOC_ID) ? TRUE : FALSE, FALSE, pucFoundKey, uiFoundKeyLen, pucSearchKey, uiSearchKeyLen, &iTmpCmp))) { goto Exit; } if (iTmpCmp != 0) { rc = (uiOriginalFlags & (XFLM_INCL | XFLM_EXCL)) ? RC_SET( NE_XFLM_EOF_HIT) : RC_SET( NE_XFLM_NOT_FOUND); goto Exit; } } // Parse the found key into its individual components if (pFoundKey) { pFoundKey->reset(); if (RC_BAD( rc = pFoundKey->inputKey( pIxd, pucFoundKey, uiFoundKeyLen))) { goto Exit; } // See if there is a data part if (pIxd->pFirstData) { FLMUINT uiDataBufSize; FLMBYTE * pucData; // If the data will fit in the search key buffer, just // reuse it since we are not going to do anything with // it after this. Otherwise, allocate a new buffer. if (uiDataLen <= XFLM_MAX_KEY_SIZE && pucSearchKey) { uiDataBufSize = XFLM_MAX_KEY_SIZE; pucData = pucSearchKey; } else { uiDataBufSize = uiDataLen; if (RC_BAD( rc = m_tempPool.poolAlloc( uiDataBufSize, (void **)&pucData))) { goto Exit; } } // Retrieve the data if (RC_BAD( rc = pbtree->btGetEntry( pucFoundKey, XFLM_MAX_KEY_SIZE, uiFoundKeyLen, pucData, uiDataBufSize, &uiDataLen))) { goto Exit; } // Parse the data if (RC_BAD( rc = pFoundKey->inputData( pIxd, pucData, uiDataLen))) { goto Exit; } } } Exit: m_tempPool.poolReset( pvMark); if (pbtree) { gv_XFlmSysData.pBtPool->btpReturnBtree( &pbtree); } if( bStartedTrans) { transAbort(); } return( rc); }
/** * \brief flushes both key and commands queue */ void CInput::flushAll(void){ flushKeys(); flushCommands(); }
/** * \brief flushes all the input events */ void CInput::flushAll() { flushKeys(); flushCommands(); flushEvents(); }