void CRUDependenceGraph::MergePipelinedTasks(const CRUTaskList &pplTaskList)
{
	if (TRUE == pplTaskList.IsEmpty())
	{
		return;
	}

	CRURefreshTask *pTopTask = (CRURefreshTask*) pScheduledTask_;
	CRURefreshTask *pNewTopTask;

	CRUMVList &mvList = pTopTask->GetMVList();

	DSListPosition pos = pplTaskList.GetHeadPosition();
	while (NULL != pos)
	{
		// The next task to merge ...
		pNewTopTask = (CRURefreshTask*)(pplTaskList.GetNext(pos));
		CRUMV &topMV = pNewTopTask->GetRootMV();
		mvList.AddTail(&topMV);

		// Inherit the connectivity of the newly merged task
		InheritTopTaskConnectivity(pNewTopTask);
		RemoveFromAvailableList(pNewTopTask);

		pTopTask = pNewTopTask;
	}
}
void CRURefreshTaskExecutor::FinalMetadataUpdate()
{
	CRURefreshTask *pParentTask = GetRefreshTask();
	RUASSERT (NULL != pParentTask);


	TInt32 currDuration = 0;
        TInt64 ts = CalculateTimeStamp();

	if (TRUE == pParentTask->NeedToExecuteInternalRefresh())
	{
		currDuration = GetTimerDuration();
	}
	
	CRUMV *pPrevMV, *pCurrMV = NULL;
	CRUMVList &mvList = pParentTask->GetMVList();
	DSListPosition pos = mvList.GetHeadPosition();

	while (NULL != pos)
	{
		pPrevMV = pCurrMV;
		pCurrMV = mvList.GetNext(pos);

		// Update the MV's REFRESHED_AT timestamp
		pCurrMV->SetTimestamp(ts);

                // publish the refresh event to the PUBLISH table
           NABoolean isRecomputePublish = (IsRecompute() == TRUE);
           pCurrMV->PublishMVRefresh(isRecomputePublish);
   
	   if (CDDObject::eON_STATEMENT != pCurrMV->GetRefreshType())
           {
		if (NULL == pPrevMV)
		{
			// This is the Root MV (the first in the list)
			if (CDDObject::eON_REQUEST == pCurrMV->GetRefreshType())
			{
				// For every table T used by MV, 
				// set MV.EPOCH[T]<--T.CURRENT_EPOCH.
				UpdateRootMVCurrentEpochVector();
			}
			
			UpdateRootMVStatistics(currDuration);
		}
		else
		{
			UpdateNonRootMVStatistics(pCurrMV, pPrevMV, currDuration);
		}
	   }
		
		pCurrMV->SaveMetadata();
	}

        if (CDDObject::eON_STATEMENT != GetRootMV().GetRefreshType())
        {
	IncrementTopMvCurrentEpoch();
        }
}
void CRUUnAuditRefreshTaskExecutor::ComposeMySql()
{
	CRURefreshTask *pTask = GetRefreshTask();
	CRUMV &mv = pTask->GetRootMV();

	CRUSimpleRefreshSQLComposer myComposer(pTask);

	// UNLOCK TABLE statement
	myComposer.ComposeUnLock(GetRootMVName());
	
	unAuditRefreshTEDynamicContainer_.SetStatementText
				(RU_UNLOCK_TABLE, myComposer.GetSQL());

	// POPINDEX CatApi request
	if (TRUE == isPopindex_)
	{
		numOfIndexes_ = mv.GetIndexList().GetCount();
		
		if (0 < numOfIndexes_)
		{
			ComposeIndexesSql();
		}
	}

	// Compose the LOCK TABLE sql statements for locking all tables 
	// in the on statement MV initialization 
	if (CDDObject::eON_STATEMENT == GetRootMVType())
	{	
		CRUTblList &tblList = mv.GetTablesUsedByMe();
		
		DSListPosition pos = tblList.GetHeadPosition();
		
		pLockTablesTEDynamicContainer_ = 
			new CRUSQLDynamicStatementContainer((short)tblList.GetCount());
		
		Int32 i=0;
		
		while (NULL != pos)
		{
			CRUTbl *pTbl = tblList.GetNext(pos);
			myComposer.ComposeLock(pTbl->GetFullName(), FALSE /*shared*/);
			pLockTablesTEDynamicContainer_->SetStatementText
#pragma nowarn(1506)   // warning elimination 
				(i,myComposer.GetSQL());
#pragma warn(1506)  // warning elimination 
			i++;
		}
	}
}
void CRUDependenceGraph::BuildPipelinedTasksList(CRUTaskList &pplTaskList)
{
	CRURefreshTask *pTopTask = (CRURefreshTask *)pScheduledTask_;
	CRURefreshTask *pNewTopTask = pTopTask;
	TInt64 nextCandidateUid;

	BOOL isRoot = TRUE;

	for (;;)
	{
		if (pplTaskList.GetCount() + 1 == maxPipelining_)
		{
			// The user-given limit (including the root task) is reached.
			// If the value is 0, the number of tasks is unlimited.
			break;
		}

		CRUMV &topMV = pTopTask->GetRootMV();
		if (FALSE 
			== 
			topMV.CanPipelineFromMe(isRoot, nextCandidateUid/*by ref*/))
		{
			break;
		}
		
		// After the first time, the top task is no more the root
		isRoot = FALSE;	

		pNewTopTask = 
			(CRURefreshTask *)GetTask(nextCandidateUid, CRUTask::REFRESH);

		if (NULL == pNewTopTask)
		{
			break;
		}

		if (FALSE == pNewTopTask->GetRootMV().CanPipelineToMe(topMV))
		{
			break;
		}

		pplTaskList.AddTail(pNewTopTask); // Queue the candidate

		pTopTask = pNewTopTask;	// Move the top task pointer
	}
}