//--------------------------------------------------------------------------- // @function: // CBitSetTest::EresUnittest_Basics // // @doc: // Testing ctors/dtor // //--------------------------------------------------------------------------- GPOS_RESULT CBitSetTest::EresUnittest_Basics() { // create memory pool CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); ULONG cSizeBits = 32; CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); ULONG cInserts = 10; for (ULONG i = 0; i < cInserts; i += 2) { // forces addition of new link pbs->FExchangeSet(i * cSizeBits); } GPOS_ASSERT(cInserts / 2 == pbs->CElements()); for (ULONG i = 1; i < cInserts; i += 2) { // new link between existing links pbs->FExchangeSet(i * cSizeBits); } GPOS_ASSERT(cInserts == pbs->CElements()); CBitSet *pbsCopy = GPOS_NEW(pmp) CBitSet(pmp, *pbs); GPOS_ASSERT(pbsCopy->FEqual(pbs)); // delete old bitset to make sure we're not accidentally // using any of its memory pbs->Release(); for (ULONG i = 0; i < cInserts; i++) { GPOS_ASSERT(pbsCopy->FBit(i * cSizeBits)); } CWStringDynamic str(pmp); COstreamString os(&str); os << *pbsCopy << std::endl; GPOS_TRACE(str.Wsz()); pbsCopy->Release(); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CBitSetTest::EresUnittest_SetOps // // @doc: // Test for set operations // //--------------------------------------------------------------------------- GPOS_RESULT CBitSetTest::EresUnittest_SetOps() { // create memory pool CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); ULONG cSizeBits = 32; ULONG cInserts = 10; CBitSet *pbs1 = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); for (ULONG i = 0; i < cInserts; i += 2) { pbs1->FExchangeSet(i * cSizeBits); } CBitSet *pbs2 = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); for (ULONG i = 1; i < cInserts; i += 2) { pbs2->FExchangeSet(i * cSizeBits); } CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); pbs->Union(pbs1); GPOS_ASSERT(pbs->FEqual(pbs1)); pbs->Intersection(pbs1); GPOS_ASSERT(pbs->FEqual(pbs1)); GPOS_ASSERT(pbs->FEqual(pbs)); GPOS_ASSERT(pbs1->FEqual(pbs1)); pbs->Union(pbs2); GPOS_ASSERT(!pbs->FEqual(pbs1) && !pbs->FEqual(pbs2)); GPOS_ASSERT(pbs->FSubset(pbs1) && pbs->FSubset(pbs2)); pbs->Difference(pbs2); GPOS_ASSERT(pbs->FEqual(pbs1)); pbs1->Release(); pbs->Union(pbs2); pbs->Intersection(pbs2); GPOS_ASSERT(pbs->FEqual(pbs2)); GPOS_ASSERT(pbs->FSubset(pbs2)); GPOS_ASSERT(pbs->CElements() == pbs2->CElements()); pbs2->Release(); pbs->Release(); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CBitSetTest::EresUnittest_Removal // // @doc: // Cleanup test // //--------------------------------------------------------------------------- GPOS_RESULT CBitSetTest::EresUnittest_Removal() { // create memory pool CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); ULONG cSizeBits = 32; CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); CBitSet *pbsEmpty = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits); GPOS_ASSERT(pbs->FEqual(pbsEmpty)); GPOS_ASSERT(pbsEmpty->FEqual(pbs)); ULONG cInserts = 10; for (ULONG i = 0; i < cInserts; i++) { pbs->FExchangeSet(i * cSizeBits); GPOS_ASSERT(i + 1 == pbs->CElements()); } for (ULONG i = 0; i < cInserts; i++) { // cleans up empty links pbs->FExchangeClear(i * cSizeBits); GPOS_ASSERT(cInserts - i - 1 == pbs->CElements()); } GPOS_ASSERT(pbs->FEqual(pbsEmpty)); GPOS_ASSERT(pbsEmpty->FEqual(pbs)); pbs->Release(); pbsEmpty->Release(); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CJoinOrderDP::PexprBuildPred // // @doc: // Build predicate connecting the two given sets // //--------------------------------------------------------------------------- CExpression * CJoinOrderDP::PexprBuildPred ( CBitSet *pbsFst, CBitSet *pbsSnd ) { // collect edges connecting the given sets CBitSet *pbsEdges = GPOS_NEW(m_pmp) CBitSet(m_pmp); CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp, *pbsFst); pbs->Union(pbsSnd); for (ULONG ul = 0; ul < m_ulEdges; ul++) { SEdge *pedge = m_rgpedge[ul]; if ( pbs->FSubset(pedge->m_pbs) && !pbsFst->FDisjoint(pedge->m_pbs) && !pbsSnd->FDisjoint(pedge->m_pbs) ) { #ifdef GPOS_DEBUG BOOL fSet = #endif // GPOS_DEBUG pbsEdges->FExchangeSet(ul); GPOS_ASSERT(!fSet); } } pbs->Release(); CExpression *pexprPred = NULL; if (0 < pbsEdges->CElements()) { DrgPexpr *pdrgpexpr = GPOS_NEW(m_pmp) DrgPexpr(m_pmp); CBitSetIter bsi(*pbsEdges); while (bsi.FAdvance()) { ULONG ul = bsi.UlBit(); SEdge *pedge = m_rgpedge[ul]; pedge->m_pexpr->AddRef(); pdrgpexpr->Append(pedge->m_pexpr); } pexprPred = CPredicateUtils::PexprConjunction(m_pmp, pdrgpexpr); } pbsEdges->Release(); return pexprPred; }
//--------------------------------------------------------------------------- // @function: // CJoinOrderDP::DConnectedness // // @doc: // Return connectedness measure of given component // //--------------------------------------------------------------------------- CDouble CJoinOrderDP::DConnectedness ( ULONG ulComp ) { CBitSet *pbsConnected = GPOS_NEW(m_pmp) CBitSet(m_pmp); for (ULONG ul = 0; ul < m_ulEdges; ul++) { SEdge *pedge = m_rgpedge[ul]; if (pedge->m_pbs->FBit(ulComp)) { pbsConnected->Union(pedge->m_pbs); } } (void) pbsConnected->FExchangeClear(ulComp); DOUBLE dConnectedness = (DOUBLE) pbsConnected->CElements() / m_ulComps; pbsConnected->Release(); return CDouble(dConnectedness); }
//--------------------------------------------------------------------------- // @function: // CJoinOrderDP::PexprBestJoinOrder // // @doc: // find best join order for a given set of elements; // //--------------------------------------------------------------------------- CExpression * CJoinOrderDP::PexprBestJoinOrder ( CBitSet *pbs ) { GPOS_CHECK_STACK_SIZE; GPOS_CHECK_ABORT; GPOS_ASSERT(NULL != pbs); // start by looking-up cost in the DP map CExpression *pexpr = PexprLookup(pbs); if (pexpr == m_pexprDummy) { // no join order could be created return NULL; } if (NULL != pexpr) { // join order is found by looking up map return pexpr; } // find maximal covered subset CBitSet *pbsCovered = PbsCovered(pbs); if (0 == pbsCovered->CElements()) { // set is not covered, return a cross product pbsCovered->Release(); return PexprCross(pbs); } if (!pbsCovered->FEqual(pbs)) { // create a cross product for uncovered subset CBitSet *pbsUncovered = GPOS_NEW(m_pmp) CBitSet(m_pmp, *pbs); pbsUncovered->Difference(pbsCovered); CExpression *pexprResult = PexprJoinCoveredSubsetWithUncoveredSubset(pbs, pbsCovered, pbsUncovered); pbsCovered->Release(); pbsUncovered->Release(); return pexprResult; } pbsCovered->Release(); // if set has size 2, there is only one possible solution if (2 == pbs->CElements()) { return PexprJoin(pbs); } // otherwise, compute best join order using dynamic programming CExpression *pexprBestJoinOrder = PexprBestJoinOrderDP(pbs); if (pexprBestJoinOrder == m_pexprDummy) { // no join order could be created return NULL; } return pexprBestJoinOrder; }