void CRURefreshTaskExecutor::UpdateRootMVCurrentEpochVector()
{
	CRUMV &rootMV = GetRootMV();
	CRUTblList &tblList = rootMV.GetTablesUsedByMe();

	DSListPosition pos = tblList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUTbl *pTbl = tblList.GetNext(pos);
		rootMV.SetEpoch(pTbl->GetUID(), pTbl->GetCurrentEpoch());
	}
}
BOOL CRULockEquivSetTask::HasObject(TInt64 uid) const
{
	DSListPosition pos = tblList_.GetHeadPosition();
	while (NULL != pos)
	{
		CRUTbl *pTbl = tblList_.GetNext(pos);
		if (pTbl->GetUID() == uid)
		{
			return TRUE;
		}
	}
	return FALSE;
}
void CRUTblEquivSetBuilder::AddOnRequestMV(CRUMV *pMV)
{
	RUASSERT(CDDObject::eON_REQUEST == pMV->GetRefreshType());

	GetDisJointAlg().AddVertex(pMV->GetUID());

	// All tables in this list are involved tables by definition
	CRUTblList &tblList = pMV->GetTablesUsedByMe();
		
	DSListPosition tblPos = tblList.GetHeadPosition();

	while (NULL != tblPos)
	{
		CRUTbl *pTbl = tblList.GetNext(tblPos);
		
		if (TRUE == pTbl->IsFullySynchronized())
		{
			// This is as syncronized table ,we must place it in the 
			// syncronized table list and in the disjoint graph
			AddSyncTable(pTbl);

			GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());
		}

		if (FALSE == pTbl->IsInvolvedMV())
		{
			// This is not an involved mv do not add it to the set.
			// A not involved mv does not require syncronization 
			// because it may only be changed by the refresh utility
			// and this is prevented by the ddl locks that are place on this
			// object
			continue;
		}

		GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());
	}
}
Ejemplo n.º 4
0
CRUTbl *CRUCache::GetTable(TInt64 objUid) const
{
	DSListPosition pos = tableList_.GetHeadPosition();
	while (NULL != pos)
	{
		CRUTbl *pTbl = tableList_.GetNext(pos);
		
		if (pTbl->GetUID() == objUid)
		{
			return pTbl;
		}
	}

	return NULL;
}
//--------------------------------------------------------------------------//
//	CRUTableLockProtocol::Init()
//
//--------------------------------------------------------------------------//
void CRUTableLockProtocol::Init(CRUTblList &tblList, 
				CRUDeltaDefList &DeltaDefList)
{
  CRUDeltaDef *pDdef    = NULL;
  CRUTbl      *curTable = NULL;

  // For each table in the used table list, find the 
  // corresponding delta def.
  DSListPosition tPos = tblList.GetHeadPosition();
  while (tPos != NULL)
  {
    curTable = tblList.GetNext(tPos);

    DSListPosition dPos = DeltaDefList.GetHeadPosition();
    while (dPos != NULL)
    {
      pDdef = DeltaDefList.GetNext(dPos);

      // Match each table to its delta def by table UID.
      if (curTable->GetUID() == pDdef->tblUid_)
      { 
	// We have a match!
        // We need this lock only if the range log has any data in it.
	if (TRUE == pDdef->isRangeLogNonEmpty_)
	{
	  if (LocksList_ == NULL)
	  {
	    // This is the first match we have found - alloc the list.
	    LocksList_ = new LocksList();
	    NothingToLock_ = FALSE;
	  }

	  // Alloc a new lock object, init it and add it to the list.
	  CRUSingleTableLockProtocol *thisLock = new CRUSingleTableLockProtocol();
	  thisLock->Init(curTable, pDdef->toEpoch_);
	  LocksList_->AddTail(thisLock);
	}

	break; // Done with this table.

      } // if Matching table UID

    } // Loop on DeltaDefList

  } // Loop on tblList

}
void CRUTblEquivSetBuilder::BuildSets()
{
	// Initialize the array of sets of CRUTbl
	Int32 equivSetsSize = GetDisJointAlg().GetNumOfSets();
	
	// Initialize the sets of CRUTbl
	for (Int32 i=0;i<equivSetsSize;i++)
	{
		equivSetsList_.AddTail(
			new CRUTblList(eItemsArentOwned));
	}

	// Pass all regular tables and add them to the appropriate list
	DSListPosition tblPos = syncTablesList_.GetHeadPosition();

	while (NULL != tblPos)
	{
		CRUTbl *pTbl = syncTablesList_.GetNext(tblPos);
		
		Int32 setId = GetDisJointAlg().GetNodeSetId(pTbl->GetUID());
		
		equivSetsList_.GetAt(setId)->AddTail(pTbl);
	}

	// Remove set with zero size
	DSListPosition setsPos = equivSetsList_.GetHeadPosition();

	while (NULL != setsPos)
	{
		DSListPosition setsPrevpos = setsPos;

		CRUTblList *pTblList = equivSetsList_.GetNext(setsPos);
		if (0 == pTblList->GetCount())
		{
			equivSetsList_.RemoveAt(setsPrevpos);
		}
	}	
}
//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::GetDefaultMdamOptForTable()
//
// If the table has more then two key columns and the range log is not empty
// then mdam must be forced on the table unless the user forced otherwise
//--------------------------------------------------------------------------//
CRUForceOptions::MdamOptions CRURefreshTaskExecutor::GetDefaultMdamOptForTable(CRUTbl &tbl)
{
	Int32 numTableKeyCol = tbl.GetKeyColumnList().GetCount();

	if (numTableKeyCol < 2)
	{
		return CRUForceOptions::MDAM_NO_FORCE;
	}

	if (FALSE == GetRefreshTask()->IsSingleDeltaRefresh())
	{
		return CRUForceOptions::MDAM_NO_FORCE;
	}

	const CRUDeltaDef *pDdef = GetRootMV().GetDeltaDefByUid(tbl.GetUID());
	
	if (NULL != pDdef && TRUE == pDdef->isRangeLogNonEmpty_)
	{
		return CRUForceOptions::MDAM_ON;
	}

	return CRUForceOptions::MDAM_NO_FORCE;
}
void CRUTblEquivSetBuilder::AddRecomputeTree(CRUMV *pMV)
{
	RUASSERT(CDDObject::eRECOMPUTE == pMV->GetRefreshType());

	if (TRUE == GetDisJointAlg().HasVertex(pMV->GetUID()))
	{
		// The mv is already in the graph and his sub tree must also be there  
		// by induction 
		return;
	}
	
	GetDisJointAlg().AddVertex(pMV->GetUID());
	
	// Go over all the childs
	CRUTblList &tblList = pMV->GetTablesUsedByMe();
	DSListPosition tblPos = tblList.GetHeadPosition();
	while (NULL != tblPos)
	{
		CRUTbl *pTbl = tblList.GetNext(tblPos);
		
		if (TRUE == pTbl->IsFullySynchronized())
		{
			GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());

			AddSyncTable(pTbl);
		
			pTbl->SetLongLockIsNeeded();
			
			continue;
		}

		if (FALSE == pTbl->IsInvolvedMV())
		{
			// This is not an involved mv do not add it to the set.
			// A not involved mv does not require syncronization 
			// because it may only be changed by the refresh utility
			// and this is prevented by the ddl locks that are place on this
			// object
			continue;
		}

		// The object is an mv - if its on request we should do nothing
		// forcing lock may be skipped and all involved on request 
		// are already in the graph
		
		GetDisJointAlg().AddEdge(pTbl->GetUID(),pMV->GetUID());

		CRUMV *pNextMV = pTbl->GetMVInterface();

		RUASSERT(NULL != pNextMV);

		if (CDDObject::eON_REQUEST == pNextMV->GetRefreshType() )
		{
			// All on requests mv's are already in the graph 
			continue;
		}
		
		RUASSERT(CDDObject::eRECOMPUTE == 
			     pNextMV->GetRefreshType());

		// call this function recursively for adding all sub tree 
		AddRecomputeTree(pNextMV);
	}
}