//--------------------------------------------------------------------------- // Greenplum Database // Copyright (C) 2009 - 2012 EMC Corp. // // @filename: // CMaxCard.h // // @doc: // Data type to carry maximal card information; // // This numeric is NOT an estimate but a guaranteed upper bound // on the cardinality, ie., plans can be pruned based on this information //--------------------------------------------------------------------------- #ifndef GPOPT_CMaxCard_H #define GPOPT_CMaxCard_H #include "gpos/base.h" // use gpos::ulong_max instead of gpos::ullong_max to make sure arithmetic does not cause overflows #define GPOPT_MAX_CARD ((ULLONG)(gpos::ulong_max)) namespace gpopt { using namespace gpos; //--------------------------------------------------------------------------- // @class: // CMaxCard // // @doc: // Maximum Cardinality, including basic operators // //--------------------------------------------------------------------------- class CMaxCard { // friends that enforce 'literal == variable' order friend BOOL operator==(ULLONG, const CMaxCard &); friend BOOL operator==(const CMaxCard &, const CMaxCard &); private: // actual (cropped) value ULLONG m_ull; // equality BOOL operator==(ULLONG ull) const { GPOS_ASSERT(ull <= GPOPT_MAX_CARD); return m_ull == ull; } public: // ctor explicit CMaxCard(ULLONG ull = GPOPT_MAX_CARD) : m_ull(ull) { GPOS_ASSERT(m_ull <= GPOPT_MAX_CARD); m_ull = std::min(m_ull, GPOPT_MAX_CARD); } // copy ctor CMaxCard(const CMaxCard &mc) { *this = mc; } // accessor ULLONG Ull() const { return m_ull; } // assignment void operator=(const CMaxCard &mc) { m_ull = mc.m_ull; } // arithmetic operators void operator*=(const CMaxCard &mc) { m_ull = std::min(mc.m_ull * m_ull, GPOPT_MAX_CARD); } // arithmetic operators void operator+=(const CMaxCard &mc) { m_ull = std::min(mc.m_ull + m_ull, GPOPT_MAX_CARD); } // print IOstream & OsPrint(IOstream &os) const { if (GPOPT_MAX_CARD == m_ull) { return os << "unbounded"; } return os << m_ull; } }; // class CMaxCard // shorthand for printing inline IOstream & operator<<(IOstream &os, const CMaxCard &mc) { return mc.OsPrint(os); } // shorthand for less-than equal inline BOOL operator<=(const CMaxCard &mcLHS, const CMaxCard &mcRHS) { if (mcLHS.Ull() <= mcRHS.Ull()) { return true; } return false; } // shorthand for equality inline BOOL operator==(const CMaxCard &mcLHS, const CMaxCard &mcRHS) { return mcLHS.operator==(mcRHS.Ull()); } // shorthand for equality inline BOOL operator==(ULLONG ull, const CMaxCard &mc) { return mc.operator==(ull); } } // namespace gpopt #endif // !GPOPT_CMaxCard_H // EOF