void CRUTbl::BuildListOfIncrementalInvolvedMVsUsingMe() { // Verify that the list is not initialized already RUASSERT(TRUE == pIncInvolvedMVsUsingMe_->IsEmpty()); DSListPosition pos = pOnRequestInvolvedMVsUsingMe_->GetHeadPosition(); while (NULL != pos) { CRUMV *pMV = pOnRequestInvolvedMVsUsingMe_->GetNext(pos); RUASSERT(CDDObject::eON_REQUEST == pMV->GetRefreshType() && TRUE == pMV->IsInvolved() ); if (TRUE == pMV->WillBeRecomputed()) { continue; } pIncInvolvedMVsUsingMe_->AddTail(pMV); CDDObject::EMVQueryType qt = pMV->GetQueryType(); if (CDDObject::eMJV == qt || CDDObject::eOTHER == qt // Is this MJV on single table? ) { isUsedByIncrementalMJV_ = TRUE; } } }
void CRUTbl::BuildEmpCheckVector() { // Verify that the vector is non-initialized RUASSERT(FALSE == pEmpCheckVector_->IsValid()); // CRUEmpCheckTask is created only if there is // at least one incrementally refreshed MV. RUASSERT(FALSE == pIncInvolvedMVsUsingMe_->IsEmpty()); TInt64 tblUid = GetUID(); DSListPosition lpos = pIncInvolvedMVsUsingMe_->GetHeadPosition(); while (NULL != lpos) { CRUMV *pMV = pIncInvolvedMVsUsingMe_->GetNext(lpos); RUASSERT (TRUE == pMV->IsInvolved() && FALSE == pMV->WillBeRecomputed()); // Register the epoch in the vector ... pEmpCheckVector_->AddEpochForCheck(pMV->GetEpoch(tblUid)); } pEmpCheckVector_->Build(); }
void CRUDupElimLogScanner::StartScan(Int32 phase) { RUASSERT(NULL == pCurrentStmt_ && NULL == pResultSet_); if (0 == phase) { pCurrentStmt_ = GetPreparedStatement(CRUDupElimConst::PHASE_0_QUERY); } else { RUASSERT(phase > 0); // The same statement for each phase starting from 1 pCurrentStmt_ = GetPreparedStatement(CRUDupElimConst::PHASE_1_QUERY); // Set the parameters for the lower bound ... CopyLowerBoundParams(); } // Start the execution ... pCurrentStmt_->ExecuteQuery(); pResultSet_ = pCurrentStmt_->GetResultSet(); if (0 == phase) { // Allocate the buffer space and setup the output descriptors SetupScan(); } else { // Nothing. Both queries have the same result set's structure. // Hence, we need not re-allocate the buffers. } }
void CRURefreshSQLComposer:: AddRngDeltaStatisticsClause(const CRUDeltaDef *pDdef) { sql_ += "\n\t"; if (FALSE == pDdef->isRangeLogNonEmpty_) { sql_ += " USE NO RANGELOG"; return; } CRUDeltaStatistics *pStat = pDdef->pStat_; RUASSERT(CRUDeltaDef::NO_DE != pDdef->deLevel_ && NULL != pStat); // USE RANGELOG <number> NUM_OF_RANGES <number> ROWS_COVERED TInt32 nRanges = pStat->nRanges_; RUASSERT(nRanges > 0); sql_ += "USE RANGELOG " + TInt32ToStr(nRanges) + " NUM_OF_RANGES "; TInt32 nCoveredRows = pStat->nRangeCoveredRows_; if (CRUDeltaStatistics::RANGE_SIZE_UNKNOWN != nCoveredRows) { sql_ += TInt32ToStr(nCoveredRows) + " ROWS_COVERED"; } }
void CRULogCleanupTaskExecutor::Work() { switch(GetState()) { case EX_START: { RUASSERT(FALSE == IsTransactionOpen()); Start(); break; } case EX_CLEAN: { RUASSERT(FALSE == IsTransactionOpen()); Clean(); break; } case EX_EPILOGUE: { RUASSERT(FALSE == IsTransactionOpen()); Epilogue(); break; } default: RUASSERT(FALSE); } }
CRUTblList& CRUTblEquivSetBuilder::GetSet(Int32 num) { RUASSERT (GetNumOfSets() >= num && 0 <= num ); CRUTblList *pTblList = equivSetsList_.GetAt(num); RUASSERT (NULL != pTblList); return *pTblList; }
Lng32 CRUTbl::GetUpdateBitmapSize() { RUASSERT (NULL != pddIUDLogTbl_); CDSString colName("UPDATE_BITMAP"); colName = CRUSQLComposer::ComposeQuotedColName( CRUTbl::logCrtlColPrefix, colName ); CDDColumn *pCol = pddIUDLogTbl_->GetColumn(colName); RUASSERT (NULL != pCol); return pCol->GetSize(); }
void CRUTopologicalDGIterator::Next() { RUASSERT(FALSE == allTasksLinkMap_.IsEmpty()); CRUTask *pTask = GetCurrentTask(); if (NULL == pTask) { return; // all the tasks have been already traversed } // The tasks that need to be traversed after me CRUTaskList &refTaskList = (DIRECT == dir_) ? pTask->GetTasksThatDependOnMe() : pTask->GetTasksThatIDependOn(); // For all of these tasks, decrecase the reference count // Update the "ready" list, if any of the tasks have become ready. UpdateIterator(refTaskList); // Select a new current task if (TRUE == readyTasksList_.IsEmpty()) { SetCurrentTask(NULL); // The last task has just been traversed } else { // Retrieve a new task from the "ready" list SetCurrentTask(readyTasksList_.RemoveHead()); } }
void CRUTopologicalDGIterator::UpdateIterator(CRUTaskList &taskList) { TaskLink link = {NULL, 0}; DSListPosition pos = taskList.GetHeadPosition(); while (NULL != pos) { CRUTask *pTask = taskList.GetNext(pos); // Locate the link in the link map BOOL ret = allTasksLinkMap_.Lookup(pTask->GetId(), link); RUASSERT(TRUE == ret); // One reference less to the task link.refCount_--; if (0 == link.refCount_) { // One more task has no dependencies, place it to the ready list readyTasksList_.AddHead(link.pTask_); } else { // Update the link's reference count in the hash allTasksLinkMap_[pTask->GetId()] = link; } } }
void CRUUnAuditRefreshTaskExecutor::PopulateIndexes() { RUASSERT(TRUE == isPopindex_); if (0 == numOfIndexes_) { return; } // ????? // Temporary - Should be removed when read commited from unaudited table is implemented BeginTransaction(); #ifdef _DEBUG CDSString msg( "\nPopulating the secondary indexes of materialized view " + GetRootMVName() + "...\n"); CRUGlobals::GetInstance()-> LogDebugMessage(CRUGlobals::DUMP_POPINDEX,"",msg); #endif ExecuteIndexStatmenents(*pUnAuditPopIndexdynamicContainer_, IDS_RU_POPINDEX_FAILED); // ????? // Temporary - Should be removed when read commited from unaudited table is implemented CommitTransaction(); TESTPOINT2(CRUGlobals::TESTPOINT105, GetRootMVName()); SetState(EX_EPILOGUE); }
void CRURefreshSQLComposer::AddPipeLineClause() { CRUMVList &mvList = GetRefreshTask().GetMVList(); RUASSERT(mvList.GetCount() > 1); DSListPosition pos = mvList.GetHeadPosition(); mvList.GetNext(pos); // Skip the root MV // Generate root clause CRUMV *pTopMV = mvList.GetNext(pos); sql_ += " PIPELINE " ; sql_ += "(" + pTopMV->GetFullName() + ")"; // Continue with the upper mv's while (NULL != pos) { sql_ += pTopMV->GetFullName(); // Retrieve the next MV from the list pTopMV = mvList.GetNext(pos); sql_ += " PIPELINE " ; sql_ += "(" + pTopMV->GetFullName() + ")"; if (NULL != pos) { sql_ += ","; } else { return; } } }
//--------------------------------------------------------------------------// // CRURefreshTaskExecutor::ComposeControlTableStmtForUsedTables() // // Compose the Control MDAM option for all base tables for forced tables //--------------------------------------------------------------------------// // LCOV_EXCL_START :rfi void CRURefreshTaskExecutor::ComposeControlTableStmtForUsedTables() { CRUMV &rootMV = GetRefreshTask()->GetRootMV(); const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption(); CRUForceOptions::MdamOptions mdamOpt = CRUForceOptions::MDAM_NO_FORCE; Int32 stmtIndex = FIRST_TBL_STAT; if (NULL != pForceOption) { VerifyForceTblListCorrectness(); if (pForceOption->IsTableStarUsed()) { mdamOpt = pForceOption->GetTableStarOption(); } } CRUTblList &tblList = rootMV.GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); RUASSERT(NULL != pTbl); ComposeControlTableStmtForUsedTable(*pTbl,stmtIndex,mdamOpt); } }
void CRUDependenceGraph::InsertTask(CRUTask *pTask) { RUASSERT (NULL != pTask); allTaskList_.AddTail(pTask); availableTaskList_.AddTail(pTask); }
CRUEmpCheckVector &CRUEmpCheckVector:: operator = (const CRUEmpCheckVector& other) { if (this == &other) { return *this; } if (NULL != pVec_) { RUASSERT(size_ == other.size_); } else { size_ = other.size_; pVec_ = new Elem[size_]; } for (Int32 i=0; i<size_; i++) { pVec_[i] = other.pVec_[i]; // Default copy } return *this; }
void CRUDupElimSQLComposer::ComposeIUDUpdateBitmapText() { CDSString pred; sql_ += "UPDATE " + iudLogName_; const CRULogCtlColDesc &desc = iudLogCtlColDescVec[CRUDupElimConst::OFS_UPD_BMP]; // Compose the real datatype // of the @UPDATE_BITMAP column - CHAR(<size>) CDSString datatype(desc.datatype_); RUASSERT(updateBmpSize_ > 0); datatype += "(" + TInt32ToStr(updateBmpSize_) + ")"; // ------------------------------------------------------------- // Date: 2008-03-19 Caroline: // In UNICODE config: ISO_MAPPING=UTF8, DEFAULT_CHARSET= UCS2 // The IUD_LOG_TABLE Clause: // SET "@UPDATE_BITMAP" = CAST (? AS CHAR(8)) // The "@UPDATE_BITMAP" column is in ISO88591, and the CAST Clause // is implied to UCS2, so we got the incompatible error. // To fix the error, we explicitly say "CHARACTER SET ISO88591". datatype += " CHARACTER SET ISO88591 "; //--------------------------------------------- sql_ += "\nSET " + ComposeQuotedColName(desc.name_) + " = "; sql_ += ComposeCastExpr(datatype); ComposeUpdateRecsSearchPredicate(pred); sql_+= pred + ";"; }
void CRUTopologicalDGIterator::Build() { TaskLink link; // Fill the data structures by references to available tasks DSListPosition pos = GetAllTasksList().GetHeadPosition(); while (NULL != pos) { CRUTask *pTask = GetAllTasksList().GetNext(pos); link.pTask_ = pTask; // The tasks that need to be traversed before me CRUTaskList &refTaskList = (DIRECT == dir_) ? pTask->GetTasksThatIDependOn() : pTask->GetTasksThatDependOnMe(); link.refCount_ = refTaskList.GetCount(); // Place the link into the hash allTasksLinkMap_[pTask->GetId()] = link; // If this is a ready task, // place a reference to it into the ready list if (0 == link.refCount_) { readyTasksList_.AddHead(link.pTask_); } } // My guess is that this is a circular graph RUASSERT(FALSE == readyTasksList_.IsEmpty()); SetCurrentTask(readyTasksList_.RemoveHead()); }
void CRUCache::RecursiveFetchCascadedMVs(CDDMV *pddRootMV) { // Setup the wrapper object for the MV FetchSingleInvolvedMV(pddRootMV); CDDUIDTripleList &uList = pddRootMV->GetUsedObjects(); DSListPosition pos = uList.GetHeadPosition(); while (NULL != pos) { CDDUIDTriple& uidt = uList.GetNext(pos); // Skip the regular tables if (FALSE == pddRootMV->IsUsedObjectAnMV(uidt.objUID)) { continue; } CDDMV *pddMV = GetDDMVByUID(uidt); // An ON STATEMENT MV is a regular table // for the purpose of cascade. Stop drilling inside. if (CDDObject::eON_STATEMENT == pddMV->GetRefreshType()) { continue; } // Since the same object cannot be used twice by the same MV, // the used MV should not have been referenced before // (and placed in the MV list). RUASSERT (NULL != GetMV(pddRootMV->GetUID())); RecursiveFetchCascadedMVs(pddMV); } }
void CRUDupElimLogScanner::UpdateSingleRowStatistics(CRUDeltaStatistics &stat) { RUASSERT (TRUE == GetDupElimGlobals().IsSingleRowResolv()); if (FALSE == pCurrentRec_->IsPartOfUpdate()) { if (TRUE == pCurrentRec_->IsInsert()) { stat.IncrementCounter(stat.nInsertedRows_); } else { stat.IncrementCounter(stat.nDeletedRows_); } } else { stat.IncrementCounter(stat.nUpdatedRows_); // Compute the superposition of update bitmaps CRUUpdateBitmap bmp(*(pCurrentRec_->GetUpdateBitmap())); if (NULL == stat.pUpdateBitmap_) { stat.pUpdateBitmap_ = new CRUUpdateBitmap(bmp); } else { *(stat.pUpdateBitmap_) |= bmp; } } }
void CRUAuditRefreshTaskExecutor::Prologue() { RUASSERT(FALSE == IsTransactionOpen()); BeginTransaction(); if (CDDObject::eON_STATEMENT == GetRootMVType()) { PrologueHandleOnStatementMV(); } SetObjectsUnavailable(); CommitTransaction(); TESTPOINT2(CRUGlobals::TESTPOINT102, GetRootMVName()); if (TRUE == isPurgedata_) { // purgedata is done in main process SetState(EX_PURGE_DATA); } else { // refresh, recompute, and popindex done in remote process SetState(EX_REMOTE_START); } }
void CRUAuditRefreshTaskExecutor::Epilogue() { RUASSERT(FALSE == IsTransactionOpen()); EndTimer(); BeginTransaction(); // if this is the first refresh, the MV status can be // changed to initialized if( TRUE == GetRefreshTask()->NeedToExecuteInternalRefresh() ) { if (CDDObject::eON_STATEMENT == GetRootMVType()) { EpilogueHandleOnStatementMV(); } ResetObjectsAvailable(); } FinalMetadataUpdate(); CommitTransaction(); TESTPOINT2(CRUGlobals::TESTPOINT131, GetRootMVName()); LogClosureMessage(); SetState(EX_COMPLETE); }
void CRUCacheDDLLockHandler::SortObjectsByUid() { RUASSERT(NULL == pObjSortedArray_); Lng32 size = objMap_.GetCount(); // Copy the pointers to the links to the array first ... pObjSortedArray_ = new PObjectLink[size]; CDSMapPosition<ObjectLink *> pos; ObjectLink *pLink; TInt64 *uid; objMap_.GetStartPosition(pos); for (Int32 i=0; TRUE == pos.IsValid(); i++) { objMap_.GetNextAssoc(pos, uid, pLink); pObjSortedArray_[i] = pLink; } // ... and sort the array qsort(pObjSortedArray_, size, sizeof(PObjectLink), CompareElem); }
BOOL CRUTbl::IsUsedOnlyByMultiTxnMvs() const { if (TRUE == pIncInvolvedMVsUsingMe_->IsEmpty()) { return FALSE; } DSListPosition pos = pIncInvolvedMVsUsingMe_->GetHeadPosition(); while (NULL != pos) { CRUMV *pMV = pIncInvolvedMVsUsingMe_->GetNext(pos); RUASSERT( CDDObject::eON_REQUEST == pMV->GetRefreshType() && TRUE == pMV->IsInvolved() ); if (0 == pMV->GetCommitNRows()) { return FALSE; } } return TRUE; }
void CRUSimpleRefreshSQLComposer::AddDeltaDefListClause() { RUASSERT(GetRefreshTask().GetDeltaDefList().GetCount() > 0); sql_ += "\n FROM "; sql_ += (TRUE == GetRefreshTask().IsSingleDeltaRefresh()) ? "SINGLEDELTA " : "MULTIDELTA "; DSListPosition pos = GetRefreshTask().GetDeltaDefList().GetHeadPosition(); for (;;) { CRUDeltaDef *pDdef = GetRefreshTask().GetDeltaDefList().GetNext(pos); CDSString fromEpoch(TInt32ToStr(pDdef->fromEpoch_)) ; CDSString toEpoch(TInt32ToStr(pDdef->toEpoch_)); AddDeltaDefClause(pDdef,fromEpoch,toEpoch); if (NULL == pos) { break; // The last clause } else { sql_ += ", "; } } if (FALSE == GetRefreshTask().IsSingleDeltaRefresh()) { AddPhaseParam(); } }
void CRUTbl::ReleaseResources() { if (TRUE == IsDDLLockPending()) { if (TRUE == CanReleaseDDLLock()) { ReleaseDDLLock(); // This is generally the case } else { // The table is a non-involved NON-AUDITED/MULTI-TXN MV, // which carried the DDL lock from some previous // invocation of Refresh. // Take care not to drop it accidentally! RUASSERT(FALSE == IsFullySynchronized()); } } // The log's read-protected open (if there was one) // should have been released by the TableSync task. // However, if TableSync has crashed, I must do the job. if (TRUE == IsLogRPOpenPending()) { ReleaseLogReadProtectedOpen(); } if (TRUE == IsRPOpenPending()) { ReleaseReadProtectedOpen(); } }
//--------------------------------------------------------------------------// // CRUSingleTableLockProtocol::LoadDataFileNameList() //--------------------------------------------------------------------------// void CRUSingleTableLockProtocol:: LoadDataFileNameList(CUOFsIpcMessageTranslator &translator) { Int32 size; translator.ReadBlock(&size,sizeof(Int32)); pUsedTblFileNameList_ = new CDSStringList(); for (Int32 i=0;i<size;i++) { Int32 stringSize; const Int32 bufSize = CUOFsSystem::IpcMaxGuardianPathNameLength; char buf[bufSize]; translator.ReadBlock(&stringSize, sizeof(Int32)); RUASSERT(bufSize > stringSize); #pragma nowarn(1506) // warning elimination translator.ReadBlock(buf, stringSize); #pragma warn(1506) // warning elimination CDSString *objName = new CDSString(buf); pUsedTblFileNameList_->AddTail(objName); } }
void CRUTableSyncTaskExecutor::Epilogue() { CRUTableSyncTask *pParentTask = (CRUTableSyncTask *)GetParentTask(); RUASSERT(NULL != pParentTask); CRUTbl &tbl = pParentTask->GetTable(); if (TRUE == tbl.IsIncEpochNeeded()) { if (TRUE == tbl.IsLongLockNeeded()) { BeginTransaction(); tbl.ExecuteReadProtectedOpen(); CommitTransaction(); } if (TRUE == tbl.IsLogRPOpenPending()) { // The above condition is false only in case of // a non involved incremental mv.We do not need to lock the logs // because we rely on the ddl locks tbl.ReleaseLogReadProtectedOpen(); } } SetState(EX_COMPLETE); }
void CRURefreshTaskExecutor::UpdateRootMVStatistics(TInt32 currDuration) { CRURefreshTask &task = *GetRefreshTask(); if (FALSE == task.NeedToExecuteInternalRefresh()) { return; } CRUDeltaDefList &deltaDefList = task.GetDeltaDefList(); TInt32 prevDuration, nextDuration; CRUMV &rootMV = GetRootMV(); if (TRUE == IsRecompute()) { prevDuration = rootMV.GetRecomputeDurationEstimate(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRecomputeDurationEstimate(nextDuration); return; } switch(deltaDefList.GetCount()) { case 0: { // This cannot happen // (NeedToExecuteInternalRefresh() must have returned FALSE). RUASSERT(FALSE); } case 1: { CRUDeltaDef *pDdef = deltaDefList.GetAt(0); // A special case: update the refresh duration, // and (optionally) the delta size. UpdateSingleDeltaStatistics(pDdef, currDuration); break; } case 2: { prevDuration = rootMV.GetRefreshDurationEstimateWith_2_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_2_Deltas(nextDuration); break; } case 3: { prevDuration = rootMV.GetRefreshDurationEstimateWith_3_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_3_Deltas(nextDuration); break; } default: { prevDuration = rootMV.GetRefreshDurationEstimateWith_N_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_N_Deltas(nextDuration); break; } } }
void CRURangeCollection::InsertRangeBoundary(const CRUIUDLogRecord *pRec) { RUASSERT(FALSE == pRec->IsSingleRowOp()); // The scan order guarantees that the last record has the greatest CK. pMaxCKRecord_ = pRec; TInt32 ep = pRec->GetEpoch(); UpdateMinEpoch(ep); if (FALSE == pRec->IsBeginRange()) { balanceCounter_--; if (balanceCounter_ < 0) { // Incorrent (unbalanced) logging - should never happen CRUException ex; ex.SetError(IDS_RU_UNBALANCED_LOGGING); throw ex; } // Find the open range which has a Begin-range record // that matches this End-range record LocateMatchForER(pRec); } else { balanceCounter_++; // Open a new range CRURange *pNewRange = new CRURange(); pNewRange->SetBRRecord(pRec); rangeList_.AddTail(pNewRange); } }
void CRUTableSyncTaskExecutor::Init() { inherited::Init(); CRUTableSyncTask *pParentTask = (CRUTableSyncTask *)GetParentTask(); RUASSERT(NULL != pParentTask); CRUTbl &tbl = pParentTask->GetTable(); if (FALSE == tbl.IsIncEpochNeeded()) { ResetHasWork(); return; } tableName_ = tbl.GetFullName(); // Decides whether the table needs a long lock,and set the table attribute // prepare the sql text and update the ddol cache object PrepareCatApi(); SetState(EX_INC_EPOCH); }
void CRUEmpCheckTaskExecutor::Init() { inherited::Init(); CRUEmpCheckTask *pParentTask = (CRUEmpCheckTask *)GetParentTask(); RUASSERT(NULL != pParentTask); CRUTbl &tbl = pParentTask->GetTable(); pEmpCheck_ = new CRUEmpCheck(tbl.GetEmpCheckVector()); // We are interested only in the the records that are logged // BEFORE the epoch increment, so we place an upper bound TInt32 upperBound; if (TRUE == tbl.IsInvolvedMV()) { // The check happens before the epoch increment upperBound = tbl.GetCurrentEpoch(); } else { // The check happens after the epoch increment upperBound = tbl.GetCurrentEpoch()-1; } pEmpCheck_->ComposeSQL(tbl, upperBound); SetState(EX_CHECK); }