text: //---------------------------------------------------------------------------
  //	Greenplum Database
  //	Copyright (C) 2011 EMC Corp.
  //
  //	@filename:
  //		CJobFactory.cpp
  //
  //	@doc:
  //		Implementation of optimizer job base class
  //---------------------------------------------------------------------------
  
  #include "gpopt/search/CJobFactory.h"
  
  #include "gpos/base.h"
  #include "gpos/task/CAutoSuspendAbort.h"
  #include "gpos/task/CWorker.h"
  
  #include "gpopt/search/CGroupExpression.h"
  
  
  using namespace gpopt;
  using namespace gpos;
  
  
  //---------------------------------------------------------------------------
  //	@function:
  //		CJobFactory::CJobFactory
  //
  //	@doc:
  //		Ctor
  //
  //---------------------------------------------------------------------------
  CJobFactory::CJobFactory(CMemoryPool *mp, ULONG ulJobs)
  	: m_mp(mp),
  	  m_ulJobs(ulJobs),
  	  m_pspjTest(nullptr),
  	  m_pspjGroupOptimization(nullptr),
  	  m_pspjGroupImplementation(nullptr),
  	  m_pspjGroupExploration(nullptr),
  	  m_pspjGroupExpressionOptimization(nullptr),
  	  m_pspjGroupExpressionImplementation(nullptr),
  	  m_pspjGroupExpressionExploration(nullptr),
  	  m_pspjTransformation(nullptr)
  {
  	// initialize factories to be used first
  	Release(PjCreate(CJob::EjtGroupExploration));
  	Release(PjCreate(CJob::EjtGroupExpressionExploration));
  	Release(PjCreate(CJob::EjtTransformation));
  }
  
  
  //---------------------------------------------------------------------------
  //	@function:
  //		CJobFactory::~CJobFactory
  //
  //	@doc:
  //		Dtor
  //
  //---------------------------------------------------------------------------
  CJobFactory::~CJobFactory()
  {
  	Truncate(CJob::EjtTest);
  	Truncate(CJob::EjtGroupExploration);
  	Truncate(CJob::EjtGroupImplementation);
  	Truncate(CJob::EjtGroupOptimization);
  	Truncate(CJob::EjtGroupExpressionExploration);
  	Truncate(CJob::EjtGroupExpressionExploration);
  	Truncate(CJob::EjtGroupExpressionOptimization);
  	Truncate(CJob::EjtTransformation);
  }
  
  
  //---------------------------------------------------------------------------
  //	@function:
  //		CJobFactory::PjCreate
  //
  //	@doc:
  //		Create job of specific type
  //
  //---------------------------------------------------------------------------
  CJob *
  CJobFactory::PjCreate(CJob::EJobType ejt)
  {
  	CJob *pj = nullptr;
  
  	switch (ejt)
  	{
  		case CJob::EjtTest:
  			pj = PtRetrieve<CJobTest>(m_pspjTest);
  			break;
  
  		case CJob::EjtGroupOptimization:
  			pj = PtRetrieve<CJobGroupOptimization>(m_pspjGroupOptimization);
  			break;
  
  		case CJob::EjtGroupImplementation:
  			pj = PtRetrieve<CJobGroupImplementation>(m_pspjGroupImplementation);
  			break;
  
  		case CJob::EjtGroupExploration:
  			pj = PtRetrieve<CJobGroupExploration>(m_pspjGroupExploration);
  			break;
  
  		case CJob::EjtGroupExpressionOptimization:
  			pj = PtRetrieve<CJobGroupExpressionOptimization>(
  				m_pspjGroupExpressionOptimization);
  			break;
  
  		case CJob::EjtGroupExpressionImplementation:
  			pj = PtRetrieve<CJobGroupExpressionImplementation>(
  				m_pspjGroupExpressionImplementation);
  			break;
  
  		case CJob::EjtGroupExpressionExploration:
  			pj = PtRetrieve<CJobGroupExpressionExploration>(
  				m_pspjGroupExpressionExploration);
  			break;
  
  		case CJob::EjtTransformation:
  			pj = PtRetrieve<CJobTransformation>(m_pspjTransformation);
  			break;
  
  		case CJob::EjtInvalid:
  			GPOS_ASSERT(!"Invalid job type");
  	}
  
  
  	// prepare task
  	pj->Reset();
  	pj->SetJobType(ejt);
  
  	return pj;
  }
  
  
  //---------------------------------------------------------------------------
  //	@function:
  //		CJobFactory::Release
  //
  //	@doc:
  //		Release completed job
  //
  //---------------------------------------------------------------------------
  void
  CJobFactory::Release(CJob *pj)
  {
  	GPOS_ASSERT(nullptr != pj);
  
  	switch (pj->Ejt())
  	{
  		case CJob::EjtTest:
  			Release(CJobTest::PjConvert(pj), m_pspjTest);
  			break;
  
  		case CJob::EjtGroupOptimization:
  			Release(CJobGroupOptimization::PjConvert(pj),
  					m_pspjGroupOptimization);
  			break;
  
  		case CJob::EjtGroupImplementation:
  			Release(CJobGroupImplementation::PjConvert(pj),
  					m_pspjGroupImplementation);
  			break;
  
  		case CJob::EjtGroupExploration:
  			Release(CJobGroupExploration::PjConvert(pj),
  					m_pspjGroupExploration);
  			break;
  
  		case CJob::EjtGroupExpressionOptimization:
  			Release(CJobGroupExpressionOptimization::PjConvert(pj),
  					m_pspjGroupExpressionOptimization);
  			break;
  
  		case CJob::EjtGroupExpressionImplementation:
  			Release(CJobGroupExpressionImplementation::PjConvert(pj),
  					m_pspjGroupExpressionImplementation);
  			break;
  
  		case CJob::EjtGroupExpressionExploration:
  			Release(CJobGroupExpressionExploration::PjConvert(pj),
  					m_pspjGroupExpressionExploration);
  			break;
  
  		case CJob::EjtTransformation:
  			Release(CJobTransformation::PjConvert(pj), m_pspjTransformation);
  			break;
  
  		default:
  			GPOS_ASSERT(!"Invalid job type");
  	}
  }
  
  
  //---------------------------------------------------------------------------
  //	@function:
  //		CJobFactory::Truncate
  //
  //	@doc:
  //		Truncate the container for the specific job type
  //
  //---------------------------------------------------------------------------
  void
  CJobFactory::Truncate(CJob::EJobType ejt)
  {
  	// need to suspend cancellation while truncating job pool
  	{
  		CAutoSuspendAbort asa;
  
  		switch (ejt)
  		{
  			case CJob::EjtTest:
  				TruncatePool(m_pspjTest);
  				break;
  
  			case CJob::EjtGroupOptimization:
  				TruncatePool(m_pspjGroupOptimization);
  				break;
  
  			case CJob::EjtGroupImplementation:
  				TruncatePool(m_pspjGroupImplementation);
  				break;
  
  			case CJob::EjtGroupExploration:
  				TruncatePool(m_pspjGroupExploration);
  				break;
  
  			case CJob::EjtGroupExpressionOptimization:
  				TruncatePool(m_pspjGroupExpressionOptimization);
  				break;
  
  			case CJob::EjtGroupExpressionImplementation:
  				TruncatePool(m_pspjGroupExpressionImplementation);
  				break;
  
  			case CJob::EjtGroupExpressionExploration:
  				TruncatePool(m_pspjGroupExpressionExploration);
  				break;
  
  			case CJob::EjtTransformation:
  				TruncatePool(m_pspjTransformation);
  				break;
  
  			case CJob::EjtInvalid:
  				GPOS_ASSERT(!"Invalid job type");
  		}
  	}
  }
  
  // EOF
  