本文整理汇总了C++中CBitSet::Release方法的典型用法代码示例。如果您正苦于以下问题:C++ CBitSet::Release方法的具体用法?C++ CBitSet::Release怎么用?C++ CBitSet::Release使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CBitSet
的用法示例。
在下文中一共展示了CBitSet::Release方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: CBitSet
//---------------------------------------------------------------------------
// @function:
// CJoinOrderDP::PexprExpand
//
// @doc:
// Create join order
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprExpand()
{
CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp);
for (ULONG ul = 0; ul < m_ulComps; ul++)
{
(void) pbs->FExchangeSet(ul);
}
if (GPOPT_DP_JOIN_ORDERING_SIZE_THRESHOLD < m_ulComps &&
GPOPT_DP_JOIN_ORDERING_CONNECTEDNESS_THRESHOLD < DMaxConnectedness(pbs))
{
// terminate early if computation cost is expected to be large
pbs->Release();
return NULL;
}
CExpression *pexprResult = PexprBestJoinOrder(pbs);
if (NULL != pexprResult)
{
pexprResult->AddRef();
}
pbs->Release();
return pexprResult;
}
示例2: CBitSet
//---------------------------------------------------------------------------
// @function:
// CBitSetTest::EresUnittest_Performance
//
// @doc:
// Simple perf test -- simulates xform candidate sets
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Performance()
{
// create memory pool
CAutoMemoryPool amp;
IMemoryPool *pmp = amp.Pmp();
ULONG cSizeBits = 512;
CBitSet *pbsBase = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
for (ULONG i = 0; i < cSizeBits; i++)
{
(void) pbsBase->FExchangeSet(i);
}
CBitSet *pbsTest = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
for (ULONG j = 0; j < 100000; j++)
{
ULONG cRandomBits = 16;
for (ULONG i = 0; i < cRandomBits; i += ((cSizeBits - 1) / cRandomBits))
{
(void) pbsTest->FExchangeSet(i);
}
pbsTest->Intersection(pbsBase);
}
pbsTest->Release();
pbsBase->Release();
return GPOS_OK;
}
示例3: bsi
//---------------------------------------------------------------------------
// @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_mp) CBitSet(m_mp);
CBitSet *pbs = GPOS_NEW(m_mp) CBitSet(m_mp, *pbsFst);
pbs->Union(pbsSnd);
for (ULONG ul = 0; ul < m_ulEdges; ul++)
{
SEdge *pedge = m_rgpedge[ul];
if (
pbs->ContainsAll(pedge->m_pbs) &&
!pbsFst->IsDisjoint(pedge->m_pbs) &&
!pbsSnd->IsDisjoint(pedge->m_pbs)
)
{
#ifdef GPOS_DEBUG
BOOL fSet =
#endif // GPOS_DEBUG
pbsEdges->ExchangeSet(ul);
GPOS_ASSERT(!fSet);
}
}
pbs->Release();
CExpression *pexprPred = NULL;
if (0 < pbsEdges->Size())
{
CExpressionArray *pdrgpexpr = GPOS_NEW(m_mp) CExpressionArray(m_mp);
CBitSetIter bsi(*pbsEdges);
while (bsi.Advance())
{
ULONG ul = bsi.Bit();
SEdge *pedge = m_rgpedge[ul];
pedge->m_pexpr->AddRef();
pdrgpexpr->Append(pedge->m_pexpr);
}
pexprPred = CPredicateUtils::PexprConjunction(m_mp, pdrgpexpr);
}
pbsEdges->Release();
return pexprPred;
}
示例4: CBitSet
//---------------------------------------------------------------------------
// @function:
// CTranslatorDXLToExprUtils::AddKeySets
//
// @doc:
// Add key sets info from the MD relation to the table descriptor
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToExprUtils::AddKeySets
(
IMemoryPool *pmp,
CTableDescriptor *ptabdesc,
const IMDRelation *pmdrel,
HMUlUl *phmululColMapping
)
{
GPOS_ASSERT(NULL != ptabdesc);
GPOS_ASSERT(NULL != pmdrel);
const ULONG ulKeySets = pmdrel->UlKeySets();
for (ULONG ul = 0; ul < ulKeySets; ul++)
{
CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, ptabdesc->UlColumns());
const DrgPul *pdrgpulKeys = pmdrel->PdrgpulKeyset(ul);
const ULONG ulKeys = pdrgpulKeys->UlLength();
for (ULONG ulKey = 0; ulKey < ulKeys; ulKey++)
{
// populate current keyset
ULONG ulOriginalKey = *((*pdrgpulKeys)[ulKey]);
ULONG *pulRemappedKey = phmululColMapping->PtLookup(&ulOriginalKey);
GPOS_ASSERT(NULL != pulRemappedKey);
pbs->FExchangeSet(*pulRemappedKey);
}
if (!ptabdesc->FAddKeySet(pbs))
{
pbs->Release();
}
}
}
示例5: DrgPul
//---------------------------------------------------------------------------
// @function:
// CLogicalGbAggDeduplicate::PstatsDerive
//
// @doc:
// Derive statistics
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalGbAggDeduplicate::PstatsDerive
(
IMemoryPool *pmp,
CExpressionHandle &exprhdl,
DrgPstat * // not used
)
const
{
GPOS_ASSERT(Esp(exprhdl) > EspNone);
IStatistics *pstatsChild = exprhdl.Pstats(0);
// extract computed columns
DrgPul *pdrgpulComputedCols = GPOS_NEW(pmp) DrgPul(pmp);
exprhdl.Pdpscalar(1 /*ulChildIndex*/)->PcrsDefined()->ExtractColIds(pmp, pdrgpulComputedCols);
// construct bitset with keys of join child
CBitSet *pbsKeys = GPOS_NEW(pmp) CBitSet(pmp);
const ULONG ulKeys = m_pdrgpcrKeys->UlLength();
for (ULONG ul = 0; ul < ulKeys; ul++)
{
CColRef *pcr = (*m_pdrgpcrKeys)[ul];
pbsKeys->FExchangeSet(pcr->UlId());
}
IStatistics *pstats = CLogicalGbAgg::PstatsDerive(pmp, pstatsChild, Pdrgpcr(), pdrgpulComputedCols, pbsKeys);
pbsKeys->Release();
pdrgpulComputedCols->Release();
return pstats;
}
示例6: str
//---------------------------------------------------------------------------
// @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;
}
示例7: xml_serializer
//---------------------------------------------------------------------------
// @function:
// CSerializableOptimizerConfig::Serialize
//
// @doc:
// Serialize contents into provided stream
//
//---------------------------------------------------------------------------
void
CSerializableOptimizerConfig::Serialize
(
COstream &oos
)
{
CXMLSerializer xml_serializer(m_mp, oos, false /*Indent*/);
// Copy traceflags from global state
CBitSet *pbs = CTask::Self()->GetTaskCtxt()->copy_trace_flags(m_mp);
m_optimizer_config->Serialize(m_mp, &xml_serializer, pbs);
pbs->Release();
}
示例8: New
//---------------------------------------------------------------------------
// @function:
// CTranslatorDXLToQuery::MarkUnusedColumns
//
// @doc:
// Mark unused target list entries in the setop child
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToQuery::MarkUnusedColumns
(
Query *pquery,
RangeTblRef *prtref,
CStateDXLToQuery *pstatedxltoquery,
const DrgPul *pdrgpulColids
)
{
const ULONG ulRTIndex = prtref->rtindex;
RangeTblEntry *prte = (RangeTblEntry*) gpdb::PvListNth(pquery->rtable, ulRTIndex -1);
GPOS_ASSERT(RTE_SUBQUERY == prte->rtekind);
Query *pqueryDerTbl = prte->subquery;
// maintain the list of used columns in a bit set
CBitSet *pds = New(m_pmp) CBitSet(m_pmp);
const ULONG ulLen = pdrgpulColids->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
ULONG ulValue = *((*pdrgpulColids)[ul]);
(void) pds->FExchangeSet(ulValue);
}
// Mark all columns that are not in the list of required input columns as being unused
const ULONG ulSize = pstatedxltoquery->UlLength();
for (ULONG ul = 0; ul < ulSize; ul++)
{
ULONG ulColId = pstatedxltoquery->UlColId(ul);
BOOL fSet = pds->FBit(ulColId);
if (!fSet)
{
// mark the column as unused in the query
TargetEntry *pte2 = (TargetEntry*) gpdb::PvListNth(pqueryDerTbl->targetList, ul);
pte2->resjunk = true;
// mark the column as unused in the state
TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
pte->resjunk = true;
}
}
pds->Release();
}
示例9: CBitSet
//---------------------------------------------------------------------------
// @function:
// CJoinOrderDP::PexprExpand
//
// @doc:
// Create join order
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprExpand()
{
CBitSet *pbs = GPOS_NEW(m_mp) CBitSet(m_mp);
for (ULONG ul = 0; ul < m_ulComps; ul++)
{
(void) pbs->ExchangeSet(ul);
}
CExpression *pexprResult = PexprBestJoinOrder(pbs);
if (NULL != pexprResult)
{
pexprResult->AddRef();
}
pbs->Release();
return pexprResult;
}
示例10: CDouble
//---------------------------------------------------------------------------
// @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);
}
示例11: CBitSet
//---------------------------------------------------------------------------
// @function:
// CPartitionPropagationSpec::SplitPartPredicates
//
// @doc:
// Split the partition elimination predicates over the various levels
// as well as the residual predicate and add them to the appropriate
// hashmaps. These are to be used when creating the partition selector
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::SplitPartPredicates
(
IMemoryPool *mp,
CExpression *pexprScalar,
CColRef2dArray *pdrgpdrgpcrKeys,
UlongToExprMap *phmulexprEqFilter, // output
UlongToExprMap *phmulexprFilter, // output
CExpression **ppexprResidual // output
)
{
GPOS_ASSERT(NULL != pexprScalar);
GPOS_ASSERT(NULL != pdrgpdrgpcrKeys);
GPOS_ASSERT(NULL != phmulexprEqFilter);
GPOS_ASSERT(NULL != phmulexprFilter);
GPOS_ASSERT(NULL != ppexprResidual);
GPOS_ASSERT(NULL == *ppexprResidual);
CExpressionArray *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(mp, pexprScalar);
CBitSet *pbsUsed = GPOS_NEW(mp) CBitSet(mp);
CColRefSet *pcrsKeys = PcrsKeys(mp, pdrgpdrgpcrKeys);
const ULONG ulLevels = pdrgpdrgpcrKeys->Size();
for (ULONG ul = 0; ul < ulLevels; ul++)
{
CColRef *colref = CUtils::PcrExtractPartKey(pdrgpdrgpcrKeys, ul);
// find conjuncts for this key and mark their positions
CExpressionArray *pdrgpexprKey = PdrgpexprPredicatesOnKey(mp, pdrgpexprConjuncts, colref, pcrsKeys, &pbsUsed);
const ULONG length = pdrgpexprKey->Size();
if (length == 0)
{
// no predicates on this key
pdrgpexprKey->Release();
continue;
}
if (length == 1 && CPredicateUtils::FIdentCompare((*pdrgpexprKey)[0], IMDType::EcmptEq, colref))
{
// EqFilters
// one equality predicate (key = expr); take out the expression
// and add it to the equality filters map
CExpression *pexprPartKey = NULL;
CExpression *pexprOther = NULL;
IMDType::ECmpType cmp_type = IMDType::EcmptOther;
CPredicateUtils::ExtractComponents((*pdrgpexprKey)[0], colref, &pexprPartKey, &pexprOther, &cmp_type);
GPOS_ASSERT(NULL != pexprOther);
pexprOther->AddRef();
#ifdef GPOS_DEBUG
BOOL result =
#endif // GPOS_DEBUG
phmulexprEqFilter->Insert(GPOS_NEW(mp) ULONG(ul), pexprOther);
GPOS_ASSERT(result);
pdrgpexprKey->Release();
}
else
{
// Filters
// more than one predicate on this key or one non-simple-equality predicate
#ifdef GPOS_DEBUG
BOOL result =
#endif // GPOS_DEBUG
phmulexprFilter->Insert(GPOS_NEW(mp) ULONG(ul), CPredicateUtils::PexprConjunction(mp, pdrgpexprKey));
GPOS_ASSERT(result);
continue;
}
}
(*ppexprResidual) = PexprResidualFilter(mp, pdrgpexprConjuncts, pbsUsed);
pcrsKeys->Release();
pdrgpexprConjuncts->Release();
pbsUsed->Release();
}
示例12: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CPhysical::PppsRequiredPushThruNAry
//
// @doc:
// Helper for pushing required partition propagation to the children of
// an n-ary operator
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysical::PppsRequiredPushThruNAry
(
IMemoryPool *mp,
CExpressionHandle &exprhdl,
CPartitionPropagationSpec *pppsReqd,
ULONG child_index
)
{
GPOS_ASSERT(NULL != pppsReqd);
CPartIndexMap *ppimReqd = pppsReqd->Ppim();
CPartFilterMap *ppfmReqd = pppsReqd->Ppfm();
ULongPtrArray *pdrgpul = ppimReqd->PdrgpulScanIds(mp);
CPartIndexMap *ppimResult = GPOS_NEW(mp) CPartIndexMap(mp);
CPartFilterMap *ppfmResult = GPOS_NEW(mp) CPartFilterMap(mp);
const ULONG ulPartIndexIds = pdrgpul->Size();
const ULONG arity = exprhdl.UlNonScalarChildren();
// iterate over required part index ids and decide which ones to push to the outer
// and which to the inner side of the n-ary op
for (ULONG ul = 0; ul < ulPartIndexIds; ul++)
{
ULONG part_idx_id = *((*pdrgpul)[ul]);
GPOS_ASSERT(ppimReqd->Contains(part_idx_id));
CBitSet *pbsPartConsumer = GPOS_NEW(mp) CBitSet(mp);
for (ULONG ulChildIdx = 0; ulChildIdx < arity; ulChildIdx++)
{
if (exprhdl.GetRelationalProperties(ulChildIdx)->Ppartinfo()->FContainsScanId(part_idx_id))
{
(void) pbsPartConsumer->ExchangeSet(ulChildIdx);
}
}
if (arity == pbsPartConsumer->Size() &&
COperator::EopPhysicalSequence == exprhdl.Pop()->Eopid() &&
(*(exprhdl.Pgexpr()))[0]->FHasCTEProducer())
{
GPOS_ASSERT(2 == arity);
// this is a part index id that comes from both sides of a sequence
// with a CTE producer on the outer side, so pretend that part index
// id is not defined the inner sides
pbsPartConsumer->ExchangeClear(1);
}
if (!FCanPushPartReqToChild(pbsPartConsumer, child_index))
{
// clean up
pbsPartConsumer->Release();
continue;
}
// clean up
pbsPartConsumer->Release();
CPartKeysArray *pdrgppartkeys = exprhdl.GetRelationalProperties(child_index)->Ppartinfo()->PdrgppartkeysByScanId(part_idx_id);
GPOS_ASSERT(NULL != pdrgppartkeys);
pdrgppartkeys->AddRef();
// push requirements to child node
ppimResult->AddRequiredPartPropagation(ppimReqd, part_idx_id, CPartIndexMap::EppraPreservePropagators, pdrgppartkeys);
// check if there is a filter on the part index id and propagate that further down
if (ppfmReqd->FContainsScanId(part_idx_id))
{
CExpression *pexpr = ppfmReqd->Pexpr(part_idx_id);
// if the current child is inner child and the predicate is IsNull check and the parent is outer join,
// don't push IsNull check predicate to the partition filter.
// for all the other cases, push the filter down.
if (!(1 == child_index &&
CUtils::FScalarNullTest(pexpr) &&
CUtils::FPhysicalOuterJoin(exprhdl.Pop()))
)
{
pexpr->AddRef();
ppfmResult->AddPartFilter(mp, part_idx_id, pexpr, NULL /*stats */);
}
}
}
pdrgpul->Release();
return GPOS_NEW(mp) CPartitionPropagationSpec(ppimResult, ppfmResult);
}
示例13: CBitSet
//---------------------------------------------------------------------------
// @function:
// CPartitionPropagationSpec::SplitPartPredicates
//
// @doc:
// Split the partition elimination predicates over the various levels
// as well as the residual predicate and add them to the appropriate
// hashmaps. These are to be used when creating the partition selector
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::SplitPartPredicates
(
IMemoryPool *pmp,
CExpression *pexprScalar,
DrgDrgPcr *pdrgpdrgpcrKeys,
HMUlExpr *phmulexprEqFilter, // output
HMUlExpr *phmulexprFilter, // output
CExpression **ppexprResidual // output
)
{
GPOS_ASSERT(NULL != pexprScalar);
GPOS_ASSERT(NULL != pdrgpdrgpcrKeys);
GPOS_ASSERT(NULL != phmulexprEqFilter);
GPOS_ASSERT(NULL != phmulexprFilter);
GPOS_ASSERT(NULL != ppexprResidual);
GPOS_ASSERT(NULL == *ppexprResidual);
DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar);
CBitSet *pbsUsed = GPOS_NEW(pmp) CBitSet(pmp);
CColRefSet *pcrsKeys = PcrsKeys(pmp, pdrgpdrgpcrKeys);
const ULONG ulLevels = pdrgpdrgpcrKeys->UlLength();
for (ULONG ul = 0; ul < ulLevels; ul++)
{
CColRef *pcr = CUtils::PcrExtractPartKey(pdrgpdrgpcrKeys, ul);
// find conjuncts for this key and mark their positions
DrgPexpr *pdrgpexprKey = PdrgpexprPredicatesOnKey(pmp, pdrgpexprConjuncts, pcr, pcrsKeys, &pbsUsed);
const ULONG ulLen = pdrgpexprKey->UlLength();
if (0 == ulLen)
{
// no predicates on this key
pdrgpexprKey->Release();
continue;
}
if (1 < ulLen || (!CPredicateUtils::FEquality((*pdrgpexprKey)[0])))
{
// more than one predicate on this key or one non-equality predicate
#ifdef GPOS_DEBUG
BOOL fResult =
#endif // GPOS_DEBUG
phmulexprFilter->FInsert(GPOS_NEW(pmp) ULONG(ul), CPredicateUtils::PexprConjunction(pmp, pdrgpexprKey));
GPOS_ASSERT(fResult);
continue;
}
// one equality predicate (key = expr); take out the expression
// and add it to the equality filters map
CExpression *pexprPartKey = NULL;
CExpression *pexprOther = NULL;
IMDType::ECmpType ecmpt = IMDType::EcmptOther;
CPredicateUtils::ExtractComponents((*pdrgpexprKey)[0], pcr, &pexprPartKey, &pexprOther, &ecmpt);
GPOS_ASSERT(NULL != pexprOther);
pexprOther->AddRef();
#ifdef GPOS_DEBUG
BOOL fResult =
#endif // GPOS_DEBUG
phmulexprEqFilter->FInsert(GPOS_NEW(pmp) ULONG(ul), pexprOther);
GPOS_ASSERT(fResult);
pdrgpexprKey->Release();
}
(*ppexprResidual) = PexprResidualFilter(pmp, pdrgpexprConjuncts, pbsUsed);
pcrsKeys->Release();
pdrgpexprConjuncts->Release();
pbsUsed->Release();
}
示例14: PexprCross
//---------------------------------------------------------------------------
// @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->Size())
{
// set is not covered, return a cross product
pbsCovered->Release();
return PexprCross(pbs);
}
if (!pbsCovered->Equals(pbs))
{
// create a cross product for uncovered subset
CBitSet *pbsUncovered = GPOS_NEW(m_mp) CBitSet(m_mp, *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->Size())
{
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;
}
示例15: dMinCost
//---------------------------------------------------------------------------
// @function:
// CJoinOrderDP::PexprBestJoinOrderDP
//
// @doc:
// Find the best join order of a given set of elements using dynamic
// programming;
// given a set of elements (e.g., {A, B, C}), we find all possible splits
// of the set (e.g., {A}, {B, C}) where at least one edge connects the
// two subsets resulting from the split,
// for each split, we find the best join orders of left and right subsets
// recursively,
// the function finds the split with the least cost, and stores the join
// of its two subsets as the best join order of the given set
//
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBestJoinOrderDP
(
CBitSet *pbs // set of elements to be joined
)
{
CDouble dMinCost(0.0);
CExpression *pexprResult = NULL;
CBitSetArray *pdrgpbsSubsets = PdrgpbsSubsets(m_mp, pbs);
const ULONG ulSubsets = pdrgpbsSubsets->Size();
for (ULONG ul = 0; ul < ulSubsets; ul++)
{
CBitSet *pbsCurrent = (*pdrgpbsSubsets)[ul];
CBitSet *pbsRemaining = GPOS_NEW(m_mp) CBitSet(m_mp, *pbs);
pbsRemaining->Difference(pbsCurrent);
// check if subsets are connected with one or more edges
CExpression *pexprPred = PexprPred(pbsCurrent, pbsRemaining);
if (NULL != pexprPred)
{
// compute solutions of left and right subsets recursively
CExpression *pexprLeft = PexprBestJoinOrder(pbsCurrent);
CExpression *pexprRight = PexprBestJoinOrder(pbsRemaining);
if (NULL != pexprLeft && NULL != pexprRight)
{
// we found solutions of left and right subsets, we check if
// this gives a better solution for the input set
CExpression *pexprJoin = PexprJoin(pbsCurrent, pbsRemaining);
CDouble dCost = DCost(pexprJoin);
if (NULL == pexprResult || dCost < dMinCost)
{
// this is the first solution, or we found a better solution
dMinCost = dCost;
CRefCount::SafeRelease(pexprResult);
pexprJoin->AddRef();
pexprResult = pexprJoin;
}
if (m_ulComps == pbs->Size())
{
AddJoinOrder(pexprJoin, dCost);
}
pexprJoin->Release();
}
}
pbsRemaining->Release();
}
pdrgpbsSubsets->Release();
// store solution in DP table
if (NULL == pexprResult)
{
m_pexprDummy->AddRef();
pexprResult = m_pexprDummy;
}
DeriveStats(pexprResult);
pbs->AddRef();
#ifdef GPOS_DEBUG
BOOL fInserted =
#endif // GPOS_DEBUG
m_phmbsexpr->Insert(pbs, pexprResult);
GPOS_ASSERT(fInserted);
// add expression cost to cost map
InsertExpressionCost(pexprResult, dMinCost, false /*fValidateInsert*/);
return pexprResult;
}