diff options
author | unknown <joreland@mysql.com> | 2004-05-26 13:24:14 +0200 |
---|---|---|
committer | unknown <joreland@mysql.com> | 2004-05-26 13:24:14 +0200 |
commit | 934b303359c8cb6a0ddc2eae268900a23b5c6374 (patch) | |
tree | 0280375c810eb97bcc0397cfd3872e453d350683 /ndb/src/ndbapi/NdbOperationScan.cpp | |
parent | d93d48c11ba2012b351547e8ff2c583c9c18e4f3 (diff) | |
download | mariadb-git-934b303359c8cb6a0ddc2eae268900a23b5c6374.tar.gz |
wl1671 - Sorted scan
Diffstat (limited to 'ndb/src/ndbapi/NdbOperationScan.cpp')
-rw-r--r-- | ndb/src/ndbapi/NdbOperationScan.cpp | 560 |
1 files changed, 0 insertions, 560 deletions
diff --git a/ndb/src/ndbapi/NdbOperationScan.cpp b/ndb/src/ndbapi/NdbOperationScan.cpp index df4f2421ec0..283eb591bdb 100644 --- a/ndb/src/ndbapi/NdbOperationScan.cpp +++ b/ndb/src/ndbapi/NdbOperationScan.cpp @@ -14,563 +14,3 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "NdbOperation.hpp" -#include "NdbScanReceiver.hpp" - -#include <signaldata/TcKeyReq.hpp> -#include <signaldata/ScanTab.hpp> -#include <signaldata/ScanFrag.hpp> -#include <signaldata/KeyInfo.hpp> - - -/****************************************************************************** - * int openScanRead(); - *****************************************************************************/ -int -NdbOperation::openScanRead(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, false, false); -} - -/**************************************************************************** - * int openScanExclusive(); - ****************************************************************************/ -int -NdbOperation::openScanExclusive(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, true, true, false); -} - -/****************************************************************************** - * int openScanReadHoldLock(); - *****************************************************************************/ -int -NdbOperation::openScanReadHoldLock(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, true, false); -} - -/****************************************************************************** - * int openScanReadCommitted(); - *****************************************************************************/ -int -NdbOperation::openScanReadCommitted(Uint32 aParallelism) -{ - aParallelism = checkParallelism(aParallelism); - - if ((theNdbCon->theCommitStatus != Started) && - (theStatus != Init) && - (aParallelism == 0)) { - setErrorCode(4200); - return -1; - } - return openScan(aParallelism, false, false, true); -} - -/**************************************************************************** - * int checkParallelism(); - * Remark If the parallelism is set wrong the number of scan-operations - * will not correspond to the number of TRANSID_AI signals returned - * from NDB and the result will be a crash, therefore - * we adjust it or return an error if the value is totally wrong. - ****************************************************************************/ -int -NdbOperation::checkParallelism(Uint32 aParallelism) -{ - if (aParallelism == 0) { - setErrorCodeAbort(4232); - return 0; - } - if (aParallelism > 16) { - if (aParallelism <= 240) { - - /** - * If tscanConcurrency > 16 it must be a multiple of 16 - */ - if (((aParallelism >> 4) << 4) < aParallelism) { - aParallelism = ((aParallelism >> 4) << 4) + 16; - }//if - - /*---------------------------------------------------------------*/ - /* We cannot have a parallelism > 16 per node */ - /*---------------------------------------------------------------*/ - if ((aParallelism / theNdb->theNoOfDBnodes) > 16) { - aParallelism = theNdb->theNoOfDBnodes * 16; - }//if - - } else { - setErrorCodeAbort(4232); - aParallelism = 0; - }//if - }//if - return aParallelism; -}//NdbOperation::checkParallelism() - -/********************************************************************** - * int openScan(); - *************************************************************************/ -int -NdbOperation::openScan(Uint32 aParallelism, - bool lockMode, bool lockHoldMode, bool readCommitted) -{ - aParallelism = checkParallelism(aParallelism); - if(aParallelism == 0){ - return 0; - } - NdbScanReceiver* tScanRec; - // It is only possible to call openScan if - // 1. this transcation don't already contain another scan operation - // 2. this transaction don't already contain other operations - // 3. theScanOp contains a NdbScanOperation - if (theNdbCon->theScanningOp != NULL){ - setErrorCode(4605); - return -1; - } - - if ((theNdbCon->theFirstOpInList != this) || - (theNdbCon->theLastOpInList != this)) { - setErrorCode(4603); - return -1; - } - theNdbCon->theScanningOp = this; - - initScan(); - theParallelism = aParallelism; - - // If the scan is on ordered index then it is a range scan - if (m_currentTable->m_indexType == NdbDictionary::Index::OrderedIndex || - m_currentTable->m_indexType == NdbDictionary::Index::UniqueOrderedIndex) { - assert(m_currentTable == m_accessTable); - m_currentTable = theNdb->theDictionary->getTable(m_currentTable->m_primaryTable.c_str()); - assert(m_currentTable != NULL); - // Modify operation state - theStatus = SetBound; - theOperationType = OpenRangeScanRequest; - } - - theScanReceiversArray = new NdbScanReceiver* [aParallelism]; - if (theScanReceiversArray == NULL){ - setErrorCodeAbort(4000); - return -1; - } - - for (Uint32 i = 0; i < aParallelism; i ++) { - tScanRec = theNdb->getNdbScanRec(); - if (tScanRec == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - tScanRec->init(this, lockMode); - theScanReceiversArray[i] = tScanRec; - } - - theSCAN_TABREQ = theNdb->getSignal(); - if (theSCAN_TABREQ == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - ScanTabReq * const scanTabReq = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); - scanTabReq->apiConnectPtr = theNdbCon->theTCConPtr; - scanTabReq->tableId = m_accessTable->m_tableId; - scanTabReq->tableSchemaVersion = m_accessTable->m_version; - scanTabReq->storedProcId = 0xFFFF; - scanTabReq->buddyConPtr = theNdbCon->theBuddyConPtr; - - Uint32 reqInfo = 0; - ScanTabReq::setParallelism(reqInfo, aParallelism); - ScanTabReq::setLockMode(reqInfo, lockMode); - ScanTabReq::setHoldLockFlag(reqInfo, lockHoldMode); - ScanTabReq::setReadCommittedFlag(reqInfo, readCommitted); - if (theOperationType == OpenRangeScanRequest) - ScanTabReq::setRangeScanFlag(reqInfo, true); - scanTabReq->requestInfo = reqInfo; - - Uint64 transId = theNdbCon->getTransactionId(); - scanTabReq->transId1 = (Uint32) transId; - scanTabReq->transId2 = (Uint32) (transId >> 32); - - for (Uint32 i = 0; i < 16 && i < aParallelism ; i++) { - scanTabReq->apiOperationPtr[i] = theScanReceiversArray[i]->ptr2int(); - }//for - - // Create one additional SCAN_TABINFO for each - // 16 of parallelism - NdbApiSignal* tSignal; - Uint32 tParallelism = aParallelism; - while (tParallelism > 16) { - tSignal = theNdb->getSignal(); - if (tSignal == NULL) { - setErrorCodeAbort(4000); - return -1; - }//if - if (tSignal->setSignal(GSN_SCAN_TABINFO) == -1) { - setErrorCode(4001); - return -1; - } - tSignal->next(theFirstSCAN_TABINFO_Send); - theFirstSCAN_TABINFO_Send = tSignal; - tParallelism -= 16; - }//while - - // Format all SCAN_TABINFO signals - tParallelism = 16; - tSignal = theFirstSCAN_TABINFO_Send; - while (tSignal != NULL) { - tSignal->setData(theNdbCon->theTCConPtr, 1); - for (int i = 0; i < 16 ; i++) { - tSignal->setData(theScanReceiversArray[i + tParallelism]->ptr2int(), i + 2); - }//for - tSignal = tSignal->next(); - tParallelism += 16; - }//while - - getFirstATTRINFOScan(); - return 0; -}//NdbScanOperation::openScan() - -/***************************************************************************** - * int getFirstATTRINFOScan( U_int32 aData ) - * - * Return Value: Return 0: Successful - * Return -1: All other cases - * Parameters: None: Only allocate the first signal. - * Remark: When a scan is defined we need to use this method instead - * of insertATTRINFO for the first signal. - * This is because we need not to mess up the code in - * insertATTRINFO with if statements since we are not - * interested in the TCKEYREQ signal. - *****************************************************************************/ -int -NdbOperation::getFirstATTRINFOScan() -{ - NdbApiSignal* tSignal; - - tSignal = theNdb->getSignal(); - if (tSignal == NULL){ - setErrorCodeAbort(4000); - return -1; - } - tSignal->setSignal(m_attrInfoGSN); - theAI_LenInCurrAI = 8; - theATTRINFOptr = &tSignal->getDataPtrSend()[8]; - theFirstATTRINFO = tSignal; - theCurrentATTRINFO = tSignal; - theCurrentATTRINFO->next(NULL); - return 0; -} - -/* - * After setBound() are done, move the accumulated ATTRINFO signals to - * a separate list. Then continue with normal scan. - */ -int -NdbOperation::saveBoundATTRINFO() -{ - theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - theBoundATTRINFO = theFirstATTRINFO; - theTotalBoundAI_Len = theTotalCurrAI_Len; - theTotalCurrAI_Len = 5; - theBoundATTRINFO->setData(theTotalBoundAI_Len, 4); - theBoundATTRINFO->setData(0, 5); - theBoundATTRINFO->setData(0, 6); - theBoundATTRINFO->setData(0, 7); - theBoundATTRINFO->setData(0, 8); - theStatus = GetValue; - return getFirstATTRINFOScan(); -} - -/***************************************************************************** - * void releaseScan() - * - * Return Value No return value. - * Parameters: No parameters. - * Remark: Release objects after scanning. - *****************************************************************************/ -void -NdbOperation::releaseScan() -{ - NdbScanReceiver* tScanRec; - TransporterFacade::instance()->lock_mutex(); - for (Uint32 i = 0; i < theParallelism && theScanReceiversArray != NULL; i++) { - tScanRec = theScanReceiversArray[i]; - if (tScanRec != NULL) { - tScanRec->release(); - tScanRec->next(NULL); - } - } - TransporterFacade::instance()->unlock_mutex(); - releaseSignals(); - - if (theScanReceiversArray != NULL) { - for (Uint32 i = 0; i < theParallelism; i++) { - NdbScanReceiver* tScanRec; - tScanRec = theScanReceiversArray[i]; - if (tScanRec != NULL) { - theNdb->releaseNdbScanRec(tScanRec); - theScanReceiversArray[i] = NULL; - } - } - - delete [] theScanReceiversArray; - }//if - theScanReceiversArray = NULL; - - if (theSCAN_TABREQ != NULL){ - theNdb->releaseSignal(theSCAN_TABREQ); - theSCAN_TABREQ = NULL; - } -} - -void NdbOperation::releaseSignals(){ - theNdb->releaseSignalsInList(&theFirstSCAN_TABINFO_Send); - theFirstSCAN_TABINFO_Send = NULL; - theLastSCAN_TABINFO_Send = NULL; - // theNdb->releaseSignalsInList(&theFirstSCAN_TABINFO_Recv); - - while(theFirstSCAN_TABINFO_Recv != NULL){ - NdbApiSignal* tmp = theFirstSCAN_TABINFO_Recv; - theFirstSCAN_TABINFO_Recv = tmp->next(); - delete tmp; - } - theFirstSCAN_TABINFO_Recv = NULL; - theLastSCAN_TABINFO_Recv = NULL; - if (theSCAN_TABCONF_Recv != NULL){ - // theNdb->releaseSignal(theSCAN_TABCONF_Recv); - delete theSCAN_TABCONF_Recv; - theSCAN_TABCONF_Recv = NULL; - } -} - - -void NdbOperation::prepareNextScanResult(){ - NdbScanReceiver* tScanRec; - for (Uint32 i = 0; i < theParallelism; i++) { - tScanRec = theScanReceiversArray[i]; - assert(tScanRec != NULL); - tScanRec->prepareNextScanResult(); - tScanRec->next(NULL); - } - releaseSignals(); -} - -/****************************************************************************** - * void initScan(); - * - * Return Value: Return 0 : init was successful. - * Return -1: In all other case. - * Remark: Initiates operation record after allocation. - *****************************************************************************/ -void -NdbOperation::initScan() -{ - theTotalRecAI_Len = 0; - theCurrRecAI_Len = 0; - theStatus = GetValue; - theOperationType = OpenScanRequest; - theCurrentRecAttr = theFirstRecAttr; - theScanInfo = 0; - theMagicNumber = 0xABCDEF01; - theTotalCurrAI_Len = 5; - - theFirstLabel = NULL; - theLastLabel = NULL; - theFirstBranch = NULL; - theLastBranch = NULL; - - theFirstCall = NULL; - theLastCall = NULL; - theFirstSubroutine = NULL; - theLastSubroutine = NULL; - - theNoOfLabels = 0; - theNoOfSubroutines = 0; - - theSubroutineSize = 0; - theInitialReadSize = 0; - theInterpretedSize = 0; - theFinalUpdateSize = 0; - theFinalReadSize = 0; - theInterpretIndicator = 1; - - - theFirstSCAN_TABINFO_Send = NULL; - theLastSCAN_TABINFO_Send = NULL; - theFirstSCAN_TABINFO_Recv = NULL; - theLastSCAN_TABINFO_Recv = NULL; - theSCAN_TABCONF_Recv = NULL; - - theScanReceiversArray = NULL; - - theTotalBoundAI_Len = 0; - theBoundATTRINFO = NULL; - return; -} - -NdbOperation* NdbOperation::takeOverForDelete(NdbConnection* updateTrans){ - return takeOverScanOp(DeleteRequest, updateTrans); -} - -NdbOperation* NdbOperation::takeOverForUpdate(NdbConnection* updateTrans){ - return takeOverScanOp(UpdateRequest, updateTrans); -} -/****************************************************************************** - * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); - * - * Parameters: The update transactions NdbConnection pointer. - * Return Value: A reference to the transferred operation object - * or NULL if no success. - * Remark: Take over the scanning transactions NdbOperation - * object for a tuple to an update transaction, - * which is the last operation read in nextScanResult() - * (theNdbCon->thePreviousScanRec) - * - * FUTURE IMPLEMENTATION: (This note was moved from header file.) - * In the future, it will even be possible to transfer - * to a NdbConnection on another Ndb-object. - * In this case the receiving NdbConnection-object must call - * a method receiveOpFromScan to actually receive the information. - * This means that the updating transactions can be placed - * in separate threads and thus increasing the parallelism during - * the scan process. - *****************************************************************************/ -NdbOperation* -NdbOperation::takeOverScanOp(OperationType opType, NdbConnection* updateTrans) -{ - if (opType != UpdateRequest && opType != DeleteRequest) { - setErrorCode(4604); - return NULL; - } - - const NdbScanReceiver* tScanRec = theNdbCon->thePreviousScanRec; - if (tScanRec == NULL){ - // No operation read by nextScanResult - setErrorCode(4609); - return NULL; - } - - if (tScanRec->theFirstKEYINFO20_Recv == NULL){ - // No KEYINFO20 received - setErrorCode(4608); - return NULL; - } - - NdbOperation * newOp = updateTrans->getNdbOperation(m_currentTable); - if (newOp == NULL){ - return NULL; - } - - /** - * Copy and caclulate attributes from the scanned operation to the - * new operation - */ - const KeyInfo20 * const firstKeyInfo20 = - CAST_CONSTPTR(KeyInfo20, tScanRec->theFirstKEYINFO20_Recv->getDataPtr()); - const Uint32 totalKeyLen = firstKeyInfo20->keyLen; - newOp->theTupKeyLen = totalKeyLen; - - newOp->theOperationType = opType; - if (opType == DeleteRequest) { - newOp->theStatus = GetValue; - } else { - newOp->theStatus = SetValue; - } - const Uint32 tScanInfo = firstKeyInfo20->scanInfo_Node & 0xFFFF; - const Uint32 tTakeOverNode = firstKeyInfo20->scanInfo_Node >> 16; - { - UintR scanInfo = 0; - TcKeyReq::setTakeOverScanFlag(scanInfo, 1); - TcKeyReq::setTakeOverScanNode(scanInfo, tTakeOverNode); - TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo); - newOp->theScanInfo = scanInfo; - } - - /** - * Copy received KEYINFO20 signals into TCKEYREQ and KEYINFO signals - * put them in list of the new op - */ - TcKeyReq * const tcKeyReq = - CAST_PTR(TcKeyReq, newOp->theTCREQ->getDataPtrSend()); - - // Copy the first 8 words of key info from KEYINF20 into TCKEYREQ - for (Uint32 i = 0; i < TcKeyReq::MaxKeyInfo; i++) { - tcKeyReq->keyInfo[i] = firstKeyInfo20->keyData[i]; - } - if (totalKeyLen > TcKeyReq::MaxKeyInfo) { - - Uint32 keyWordsCopied = TcKeyReq::MaxKeyInfo; - - // Create KEYINFO signals in newOp - for (Uint32 i = keyWordsCopied; i < totalKeyLen; i += KeyInfo::DataLength){ - NdbApiSignal* tSignal = theNdb->getSignal(); - if (tSignal == NULL){ - setErrorCodeAbort(4000); - return NULL; - } - if (tSignal->setSignal(GSN_KEYINFO) == -1){ - setErrorCodeAbort(4001); - return NULL; - } - tSignal->next(newOp->theFirstKEYINFO); - newOp->theFirstKEYINFO = tSignal; - } - - // Init pointers to KEYINFO20 signal - NdbApiSignal* currKeyInfo20 = tScanRec->theFirstKEYINFO20_Recv; - const KeyInfo20 * keyInfo20 = - CAST_CONSTPTR(KeyInfo20, currKeyInfo20->getDataPtr()); - Uint32 posInKeyInfo20 = keyWordsCopied; - - // Init pointers to KEYINFO signal - NdbApiSignal* currKeyInfo = newOp->theFirstKEYINFO; - KeyInfo * keyInfo = CAST_PTR(KeyInfo, currKeyInfo->getDataPtrSend()); - Uint32 posInKeyInfo = 0; - - // Copy from KEYINFO20 to KEYINFO - while(keyWordsCopied < totalKeyLen){ - keyInfo->keyData[posInKeyInfo++] = keyInfo20->keyData[posInKeyInfo20++]; - keyWordsCopied++; - if(keyWordsCopied >= totalKeyLen) - break; - if (posInKeyInfo20 >= - (currKeyInfo20->getLength()-KeyInfo20::HeaderLength)){ - currKeyInfo20 = currKeyInfo20->next(); - keyInfo20 = CAST_CONSTPTR(KeyInfo20, currKeyInfo20->getDataPtr()); - posInKeyInfo20 = 0; - } - if (posInKeyInfo >= KeyInfo::DataLength){ - currKeyInfo = currKeyInfo->next(); - keyInfo = CAST_PTR(KeyInfo, currKeyInfo->getDataPtrSend()); - posInKeyInfo = 0; - } - } - } - - return newOp; -} - - - |