Ejemplo n.º 1
0
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;
		}
	}
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 7
0
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 + ";";
}
Ejemplo n.º 16
0
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());
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 22
0
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();
	}
}
Ejemplo n.º 24
0
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);
}