greenplumn CTreeMapTest 源码
greenplumn CTreeMapTest 代码
文件路径:/src/backend/gporca/server/src/unittest/gpopt/search/CTreeMapTest.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 EMC Corp.
//
// @filename:
// CTreeMapTest.cpp
//
// @doc:
// Test of tree map facility
//---------------------------------------------------------------------------
#include "unittest/gpopt/search/CTreeMapTest.h"
#include "gpos/error/CAutoTrace.h"
#include "gpos/io/COstreamString.h"
#include "gpos/string/CWStringDynamic.h"
#include "gpos/task/CAutoTraceFlag.h"
#include "gpos/task/CTask.h"
#include "gpos/types.h"
#include "gpopt/base/CDrvdPropCtxtPlan.h"
#include "gpopt/engine/CEngine.h"
#include "gpopt/eval/CConstExprEvaluatorDefault.h"
#include "gpopt/exception.h"
#include "gpopt/operators/CLogicalInnerJoin.h"
#include "unittest/base.h"
#include "unittest/gpopt/CTestUtils.h"
ULONG CTreeMapTest::m_ulTestCounter = 0; // start from first test
//---------------------------------------------------------------------------
// raw data for test
//---------------------------------------------------------------------------
const ULONG ulElems = 10;
static ULONG rgul[ulElems];
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest
//
// @doc:
// Unittest for state machine
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest()
{
CUnittest rgut[] = {
GPOS_UNITTEST_FUNC(CTreeMapTest::EresUnittest_Basic),
GPOS_UNITTEST_FUNC(CTreeMapTest::EresUnittest_Count),
GPOS_UNITTEST_FUNC(CTreeMapTest::EresUnittest_Unrank),
GPOS_UNITTEST_FUNC(CTreeMapTest::EresUnittest_Memo),
#ifdef GPOS_DEBUG
GPOS_UNITTEST_FUNC_ASSERT(CTreeMapTest::EresUnittest_Cycle),
#endif // GPOS_DEBUG
};
return CUnittest::EresExecute(rgut, GPOS_ARRAY_SIZE(rgut));
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::CNode::OsPrint
//
// @doc:
// Debug print function
//
//---------------------------------------------------------------------------
IOstream &
CTreeMapTest::CNode::OsPrintWithIndent(IOstream &os, ULONG ulIndent) const
{
for (ULONG ul = 0; ul < ulIndent; ul++)
{
os << " ";
}
os << "node: " << m_ulData << std::endl;
for (ULONG ulChild = 0; ulChild < m_pdrgpnd->Size(); ulChild++)
{
(void) (*m_pdrgpnd)[ulChild]->OsPrintWithIndent(os, ulIndent + 2);
}
return os;
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::CNode::CNode
//
// @doc:
// ctor
//
//---------------------------------------------------------------------------
CTreeMapTest::CNode::CNode(CMemoryPool *, // mp
const ULONG *pulData, CNodeArray *pdrgpnd)
: m_ulData(gpos::ulong_max), m_pdrgpnd(pdrgpnd)
{
if (nullptr != pulData)
{
m_ulData = *pulData;
}
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::CNode::~CNode
//
// @doc:
// ctor
//
//---------------------------------------------------------------------------
CTreeMapTest::CNode::~CNode()
{
CRefCount::SafeRelease(m_pdrgpnd);
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::Pnd
//
// @doc:
// Constructor function for result tree
//
//---------------------------------------------------------------------------
CTreeMapTest::CNode *
CTreeMapTest::Pnd(CMemoryPool *mp, ULONG *pul, CNodeArray *pdrgpnd,
BOOL *fTestTrue)
{
// The test passes 'true' to PrUnrank and the rehydrate function expects to find it here.
GPOS_ASSERT(nullptr != fTestTrue);
GPOS_ASSERT(*fTestTrue && "Flag is expected to be true");
*fTestTrue = true;
return GPOS_NEW(mp) CNode(mp, pul, pdrgpnd);
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::PtmapLoad
//
// @doc:
// Create a semantically meaningful tree map by simulating a MEMO
// layout
//
//---------------------------------------------------------------------------
CTreeMapTest::TestMap *
CTreeMapTest::PtmapLoad(CMemoryPool *mp)
{
TestMap *ptmap = GPOS_NEW(mp) TestMap(mp, &Pnd);
// init raw data
for (ULONG pos = 0; pos < ulElems; pos++)
{
rgul[pos] = pos;
}
// simulate the following MEMO with individual edge insertions
struct SEdge
{
// number of parent node
ULONG m_ulParent;
// position of child
ULONG m_ulPos;
// number of child node
ULONG m_ulChild;
} rgedge[] = {
// root group: Join [4,3], HashJoin[4,3]{8}, HashJoin[3,4]{9}
{9, 1, 7},
{9, 0, 6},
{9, 0, 5},
{8, 0, 7},
{8, 1, 5},
{8, 1, 6},
// group 4: C, TabScan{7}
// group 3: Join[1,2], HashJoin[1,2]{5}, SortMergeJoin[1,2]{6}
{5, 0, 0},
{5, 0, 1},
{5, 1, 2},
{5, 1, 3},
{5, 1, 4},
{6, 0, 1},
{6, 1, 3},
{6, 1, 4},
// group 2: B, TabScan{2}, IndexScan{3}, Sort[2]{4}
{4, 0, 2}
// group 1: A, TabScan{0}, IndexScan{1}
};
for (ULONG ul = 0; ul < GPOS_ARRAY_SIZE(rgedge); ul++)
{
SEdge &edge = rgedge[ul];
ptmap->Insert(&rgul[edge.m_ulParent], edge.m_ulPos,
&rgul[edge.m_ulChild]);
}
return ptmap;
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest_Basic
//
// @doc:
// Basic test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Basic()
{
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
TestMap *ptmap = nullptr;
// create blank map
ptmap = GPOS_NEW(mp) TestMap(mp, &Pnd);
GPOS_ASSERT(0 == ptmap->UllCount());
GPOS_DELETE(ptmap);
// create map with test data
ptmap = PtmapLoad(mp);
GPOS_DELETE(ptmap);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest_Count
//
// @doc:
// Count and debug output of all counts at various nodes
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Count()
{
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
TestMap *ptmap = PtmapLoad(mp);
// debug print
CWStringDynamic str(mp);
COstreamString oss(&str);
ULLONG ullCount = ptmap->UllCount();
oss << "total number of trees: " << ullCount << std::endl;
#ifdef GPOS_DEBUG
for (ULONG ul = 0; ul < ulElems; ul++)
{
oss << "node: " << ul << " count: " << ptmap->UllCount(&rgul[ul])
<< std::endl;
}
(void) ptmap->OsPrint(oss);
#endif // GPOS_DEBUG
GPOS_TRACE(str.GetBuffer());
GPOS_DELETE(ptmap);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest_Unrank
//
// @doc:
// Rehydrate all trees encoded in the map
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Unrank()
{
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
TestMap *ptmap = PtmapLoad(mp);
// debug print
CWStringDynamic str(mp);
COstreamString oss(&str);
ULLONG ullCount = ptmap->UllCount();
for (ULONG ulRank = 0; ulRank < ullCount; ulRank++)
{
oss << "=== tree rank: " << ulRank << " ===" << std::endl;
BOOL fFlag = true;
CNode *pnd = ptmap->PrUnrank(mp, &fFlag, ulRank);
pnd->Release();
}
GPOS_TRACE(str.GetBuffer());
GPOS_DELETE(ptmap);
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest_Memo
//
// @doc:
// Test loading map from actual memo
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Memo()
{
GPOS_SET_TRACE(EtraceDisablePrintMemoryLeak);
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CEngine *peng = nullptr;
CExpression *pexpr = nullptr;
CQueryContext *pqc = nullptr;
CExpression *pexprPlan = nullptr;
{
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, nullptr, /* pceeval */
CTestUtils::GetCostModel(mp));
CAutoTraceFlag atf(EopttraceEnumeratePlans, true);
peng = GPOS_NEW(mp) CEngine(mp);
// generate join expression
pexpr = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(mp);
// generate query context
pqc = CTestUtils::PqcGenerate(mp, pexpr);
// Initialize engine
peng->Init(pqc, nullptr /*search_stage_array*/);
// optimize query
peng->Optimize();
// extract plan
pexprPlan = peng->PexprExtractPlan();
GPOS_ASSERT(nullptr != pexprPlan);
peng->Trace();
{
CAutoTrace at(mp);
ULLONG ullCount = peng->Pmemotmap()->UllCount();
#ifdef GPOS_DEBUG
// test resetting map and re-creating it
peng->ResetTreeMap();
ULLONG ullCount2 = peng->Pmemotmap()->UllCount();
GPOS_ASSERT(ullCount == ullCount2);
#endif // GPOS_DEBUG
for (ULONG ulRank = 0; ulRank < ullCount; ulRank++)
{
CDrvdPropCtxtPlan *pdpctxtplan =
GPOS_NEW(mp) CDrvdPropCtxtPlan(mp, false /*fUpdateCTEMap*/);
CExpression *pexprAlt = nullptr;
GPOS_TRY
{
pexprAlt =
peng->Pmemotmap()->PrUnrank(mp, pdpctxtplan, ulRank);
at.Os() << std::endl
<< "ALTERNATIVE [" << ulRank << "]:" << std::endl
<< *pexprAlt << std::endl;
}
GPOS_CATCH_EX(ex)
{
if (!GPOS_MATCH_EX(
ex, gpopt::ExmaGPOPT,
gpopt::ExmiUnsatisfiedRequiredProperties))
{
GPOS_RETHROW(ex);
}
IErrorContext *perrctxt = CTask::Self()->GetErrCtxt();
at.Os() << perrctxt->GetErrorMsg() << std::endl;
GPOS_RESET_EX;
}
GPOS_CATCH_END;
CRefCount::SafeRelease(pexprAlt);
CRefCount::SafeRelease(pdpctxtplan);
}
}
}
// clean up
CRefCount::SafeRelease(pexprPlan);
GPOS_DELETE(pqc);
CRefCount::SafeRelease(pexpr);
GPOS_DELETE(peng);
return GPOS_OK;
}
#ifdef GPOS_DEBUG
//---------------------------------------------------------------------------
// @function:
// CTreeMapTest::EresUnittest_Cycle
//
// @doc:
// Introduce cycle in graph; counting must assert
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Cycle()
{
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
TestMap *ptmap = GPOS_NEW(mp) TestMap(mp, &Pnd);
CAutoP<TestMap> a_ptmap;
a_ptmap = ptmap;
// build cycle
ptmap->Insert(&rgul[0], 0, &rgul[1]);
ptmap->Insert(&rgul[1], 0, &rgul[2]);
ptmap->Insert(&rgul[2], 0, &rgul[1]);
(void) ptmap->UllCount();
return GPOS_FAILED;
}
#endif // GPOS_FAILED
// EOF
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦