INT32 _rtnIXScanner::resumeScan( BOOLEAN isReadOnly ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__RTNIXSCAN_RESUMESCAN ) ; if ( !_indexCB ) { PD_LOG ( PDERROR, "Failed to allocate memory for indexCB" ) ; rc = SDB_OOM ; goto error ; } if ( !_indexCB->isInitialized() ) { rc = SDB_RTN_INDEX_NOTEXIST ; goto done ; } if ( _indexCB->getFlag() != IXM_INDEX_FLAG_NORMAL ) { rc = SDB_IXM_UNEXPECTED_STATUS ; goto done ; } if ( !_init || _curIndexRID.isNull() || _savedObj.isEmpty() ) { rc = SDB_OK ; goto done ; } // for write mode, since we write _savedRID and _savedObj in advance, we // don't do it here, so let's jump to done directly if ( !isReadOnly ) { goto done ; } // compare the historical index OID with the current index oid, to make // sure the index is not changed during the time if ( !_indexCB->isStillValid ( _indexOID ) || _indexLID != _indexCB->getLogicalID() ) { rc = SDB_RTN_INDEX_NOTEXIST ; goto done ; } { // we assume _indexCB remains valid as long as the indexCBExtent still // pointing to the same index oid (which should be unique against each // index) because the storage unit should never be remapped in memory // during its run ixmExtent indexExtent ( _curIndexRID._extent, _su->index() ) ; CHAR *dataBuffer = NULL ; if ( indexExtent.isStillValid( _indexCB->getMBID() ) ) { dataBuffer = indexExtent.getKeyData ( _curIndexRID._slot ) ; } if ( dataBuffer ) { try { BSONObj curObj = ixmKey(dataBuffer).toBson() ; // make sure key is the same if ( curObj.shallowEqual(_savedObj) ) { dmsRecordID onDiskRID = indexExtent.getRID ( _curIndexRID._slot ) ; // make sure rid is the same if ( onDiskRID == _savedRID ) { // this means the last scaned record is still here, so let's // reset _savedRID so that we'll call advance() _savedRID.reset() ; // if both key and rid are not changed, let's continue goto done ; } } } catch ( std::exception &e ) { PD_LOG ( PDERROR, "Failed to convert buffer to bson from " "current rid: %d,%d: %s", _curIndexRID._extent, _curIndexRID._slot, e.what() ) ; rc = SDB_SYS ; goto error ; } } // when we get here, it means something changed and we need to // relocateRID // note relocateRID may relocate to the index that already read. However // after advance() returning the RID we'll check if the index already has // been read, so we should be save to not reset _savedRID { rc = relocateRID () ; if ( rc ) { PD_LOG ( PDERROR, "Failed to relocate RID, rc: %d", rc ) ; goto error ; } } } done : PD_TRACE_EXITRC ( SDB__RTNIXSCAN_RESUMESCAN, rc ) ; return rc ; error : goto done ; }
INT32 _rtnIXScanner::resumeScan( BOOLEAN isReadOnly ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__RTNIXSCAN_RESUMESCAN ) ; if ( !_indexCB ) { PD_LOG ( PDERROR, "Failed to allocate memory for indexCB" ) ; rc = SDB_OOM ; goto error ; } if ( !_indexCB->isInitialized() ) { rc = SDB_RTN_INDEX_NOTEXIST ; goto done ; } if ( _indexCB->getFlag() != IXM_INDEX_FLAG_NORMAL ) { rc = SDB_IXM_UNEXPECTED_STATUS ; goto done ; } if ( !_init || _curIndexRID.isNull() || _savedObj.isEmpty() ) { rc = SDB_OK ; goto done ; } if ( !isReadOnly ) { goto done ; } if ( !_indexCB->isStillValid ( _indexOID ) || _indexLID != _indexCB->getLogicalID() ) { rc = SDB_RTN_INDEX_NOTEXIST ; goto done ; } { ixmExtent indexExtent ( _curIndexRID._extent, _su->index() ) ; CHAR *dataBuffer = NULL ; if ( indexExtent.isStillValid( _indexCB->getMBID() ) ) { dataBuffer = indexExtent.getKeyData ( _curIndexRID._slot ) ; } if ( dataBuffer ) { try { BSONObj curObj = ixmKey(dataBuffer).toBson() ; if ( curObj.shallowEqual(_savedObj) ) { dmsRecordID onDiskRID = indexExtent.getRID ( _curIndexRID._slot ) ; if ( onDiskRID == _savedRID ) { _savedRID.reset() ; goto done ; } } } catch ( std::exception &e ) { PD_LOG ( PDERROR, "Failed to convert buffer to bson from " "current rid: %d,%d: %s", _curIndexRID._extent, _curIndexRID._slot, e.what() ) ; rc = SDB_SYS ; goto error ; } } { rc = relocateRID () ; if ( rc ) { PD_LOG ( PDERROR, "Failed to relocate RID, rc: %d", rc ) ; goto error ; } } } done : PD_TRACE_EXITRC ( SDB__RTNIXSCAN_RESUMESCAN, rc ) ; return rc ; error : goto done ; }