//--------------------------------------------------------------------------- // @function: // CGroupExpression::CleanupContexts // // @doc: // Destroy stored cost contexts in hash table // //--------------------------------------------------------------------------- void CGroupExpression::CleanupContexts() { // need to suspend cancellation while cleaning up { CAutoSuspendAbort asa; ShtIter shtit(m_sht); CCostContext *pcc = NULL; while (NULL != pcc || shtit.FAdvance()) { if (NULL != pcc) { pcc->Release(); } // iter's accessor scope { ShtAccIter shtitacc(shtit); if (NULL != (pcc = shtitacc.Pt())) { shtitacc.Remove(pcc); } } } } #ifdef GPOS_DEBUG CWorker::PwrkrSelf()->ResetTimeSlice(); #endif // GPOS_DEBUG }
//--------------------------------------------------------------------------- // @function: // CGroupExpression::PccInsertBest // // @doc: // Insert given context in hash table only if a better context // does not already exist, // return the context that is kept in hash table // //--------------------------------------------------------------------------- CCostContext * CGroupExpression::PccInsertBest ( CCostContext *pcc ) { GPOS_ASSERT(NULL != pcc); COptimizationContext *poc = pcc->Poc(); const ULONG ulOptReq = pcc->UlOptReq(); // remove existing cost context, if any CCostContext *pccExisting = PccRemove(poc, ulOptReq); CCostContext *pccKept = NULL; // compare existing context with given context if (NULL == pccExisting || pcc->FBetterThan(pccExisting)) { // insert new context pccKept = PccInsert(pcc); GPOS_ASSERT(pccKept == pcc); if (NULL != pccExisting) { if (pccExisting == poc->PccBest()) { // change best cost context of the corresponding optimization context poc->SetBest(pcc); } pccExisting->Release(); } } else { // re-insert existing context pcc->Release(); pccKept = PccInsert(pccExisting); GPOS_ASSERT(pccKept == pccExisting); } return pccKept; }
//--------------------------------------------------------------------------- // @function: // CGroupExpression::PccComputeCost // // @doc: // Compute and store expression's cost under a given context; // the function returns the cost context containing the computed cost // //--------------------------------------------------------------------------- CCostContext * CGroupExpression::PccComputeCost ( IMemoryPool *pmp, COptimizationContext *poc, ULONG ulOptReq, DrgPoc *pdrgpoc, // array of child contexts BOOL fPruned, // is created cost context pruned based on cost bound CCost costLowerBound // lower bound on the cost of plan carried by cost context ) { GPOS_ASSERT(NULL != poc); GPOS_ASSERT_IMP(!fPruned, NULL != pdrgpoc); if (!fPruned && !FValid(pmp, poc, pdrgpoc)) { return NULL; } // check if the same cost context is already created for current group expression if (FCostContextExists(poc, pdrgpoc)) { return NULL; } poc->AddRef(); this->AddRef(); CCostContext *pcc = GPOS_NEW(pmp) CCostContext(pmp, poc, ulOptReq, this); BOOL fValid = true; // computing cost pcc->SetState(CCostContext::estCosting); if (!fPruned) { if (NULL != pdrgpoc) { pdrgpoc->AddRef(); } pcc->SetChildContexts(pdrgpoc); fValid = pcc->FValid(pmp); if (fValid) { CCost cost = CostCompute(pmp, pcc); pcc->SetCost(cost); } GPOS_ASSERT_IMP(COptCtxt::FAllEnforcersEnabled(), fValid && "Cost context carries an invalid plan"); } else { pcc->SetPruned(); pcc->SetCost(costLowerBound); } pcc->SetState(CCostContext::estCosted); if (fValid) { return PccInsertBest(pcc); } pcc->Release(); // invalid cost context return NULL; }