Пример #1
0
void SG_dagfrag__equal(SG_context * pCtx,
					   const SG_dagfrag * pFrag1, const SG_dagfrag * pFrag2, SG_bool * pbResult)
{
	SG_rbtree_iterator * pIter1 = NULL;
	SG_rbtree_iterator * pIter2 = NULL;
	const char * szKey1;
	const char * szKey2;
	_my_data * pMyData1;
	_my_data * pMyData2;
	SG_bool bFound1, bFound2, bEqualDagnodes;
	SG_bool bFinalResult = SG_FALSE;

	SG_NULLARGCHECK_RETURN(pFrag1);
	SG_NULLARGCHECK_RETURN(pFrag2);
	SG_NULLARGCHECK_RETURN(pbResult);

	// we compare the RB-Cache because it has everything in it.
	// the work-queues are transient (used during __add_leaf()).
	// the generation-sorted-member-cache is only around when
	// needed and is a subset of the RB-Cache.

	// since the RB-Cache is ordered by HID, we don't need to do
	// any sorting.  just walk both versions in parallel.

	SG_ERR_CHECK(  SG_rbtree__iterator__first(pCtx,&pIter1,pFrag1->m_pRB_Cache,&bFound1,&szKey1,(void **)&pMyData1)  );
	SG_ERR_CHECK(  SG_rbtree__iterator__first(pCtx,&pIter2,pFrag2->m_pRB_Cache,&bFound2,&szKey2,(void **)&pMyData2)  );

	while (1)
	{
		if (!bFound1 && !bFound2)
			goto Equal;
		if (!bFound1 || !bFound2)
			goto Different;
		if (strcmp(szKey1,szKey2) != 0)
			goto Different;

		if (pMyData1->m_state != pMyData2->m_state)
			goto Different;

        if (SG_DFS_END_FRINGE != pMyData1->m_state)
        {
            if (pMyData1->m_genDagnode != pMyData2->m_genDagnode)
                goto Different;
            SG_ERR_CHECK(  SG_dagnode__equal(pCtx,pMyData1->m_pDagnode,pMyData2->m_pDagnode,&bEqualDagnodes)  );
            if (!bEqualDagnodes)
                goto Different;
        }

		SG_ERR_CHECK(  SG_rbtree__iterator__next(pCtx,pIter1,&bFound1,&szKey1,(void **)&pMyData1)  );
		SG_ERR_CHECK(  SG_rbtree__iterator__next(pCtx,pIter2,&bFound2,&szKey2,(void **)&pMyData2)  );
	}

Equal:
	bFinalResult = SG_TRUE;
Different:
	*pbResult = bFinalResult;
fail:
	SG_RBTREE_ITERATOR_NULLFREE(pCtx, pIter1);
	SG_RBTREE_ITERATOR_NULLFREE(pCtx, pIter2);
}
Пример #2
0
/**
 * Recursively compare dagnodes depth-first.
 */
static void _compare_dagnodes(SG_context* pCtx,
							  SG_repo* pRepo1,
							  SG_dagnode* pDagnode1,
							  SG_repo* pRepo2,
							  SG_dagnode* pDagnode2,
							  SG_bool* pbIdentical)
{
	SG_bool bDagnodesEqual = SG_FALSE;
	SG_uint32 iParentCount1, iParentCount2;
	const char** paParentIds1 = NULL;
	const char** paParentIds2 = NULL;
	SG_dagnode* pParentDagnode1 = NULL;
	SG_dagnode* pParentDagnode2 = NULL;

	SG_NULLARGCHECK_RETURN(pDagnode1);
	SG_NULLARGCHECK_RETURN(pDagnode2);
	SG_NULLARGCHECK_RETURN(pbIdentical);

	*pbIdentical = SG_TRUE;

	// Compare the dagnodes.  If they're different, return false.
	SG_ERR_CHECK(  SG_dagnode__equal(pCtx, pDagnode1, pDagnode2, &bDagnodesEqual)  );
	if (!bDagnodesEqual)
	{
#if TRACE_SYNC
		SG_ERR_CHECK(  SG_console(pCtx, SG_CS_STDERR, "dagnodes not equal\n")  );
#endif
		*pbIdentical = SG_FALSE;
		return;
	}

	// The dagnodes are identical.  Look at their parents.
	SG_ERR_CHECK(  SG_dagnode__get_parents(pCtx, pDagnode1, &iParentCount1, &paParentIds1)  );
	SG_ERR_CHECK(  SG_dagnode__get_parents(pCtx, pDagnode2, &iParentCount2, &paParentIds2)  );
	if (iParentCount1 == iParentCount2)
	{
		// The dagnodes have the same number of parents.  Compare the parents recursively.
		SG_uint32 i;
		for (i = 0; i < iParentCount1; i++)
		{
			SG_ERR_CHECK(  SG_repo__fetch_dagnode(pCtx, pRepo1, paParentIds1[i], &pParentDagnode1)  );
			SG_ERR_CHECK(  SG_repo__fetch_dagnode(pCtx, pRepo2, paParentIds2[i], &pParentDagnode2)  );

			SG_ERR_CHECK(  _compare_dagnodes(pCtx, pRepo1, pParentDagnode1, pRepo2, pParentDagnode2, pbIdentical)  );
			SG_DAGNODE_NULLFREE(pCtx, pParentDagnode1);
			SG_DAGNODE_NULLFREE(pCtx, pParentDagnode2);
			if (!(*pbIdentical))
				break;
		}
	}
	else
	{
		// The dagnodes have a different number of parents.
		*pbIdentical = SG_FALSE;
	}

	// fall through
fail:
	SG_NULLFREE(pCtx, paParentIds1);
	SG_NULLFREE(pCtx, paParentIds2);
	SG_DAGNODE_NULLFREE(pCtx, pParentDagnode1);
	SG_DAGNODE_NULLFREE(pCtx, pParentDagnode2);

}