bdb_query.cpp

来自「ncbi源码」· C++ 代码 · 共 1,189 行 · 第 1/2 页

CPP
1,189
字号
/// GT function ////// @internalclass CScannerFunctorGT : public CScannerFunctorComp{public:    CScannerFunctorGT(CQueryExecEnv& env)     : CScannerFunctorComp(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        int cmpres = CmpEval(tr);        bool res = cmpres > 0;        SetResult(tr.GetValue(), res);    }};/// GE function ////// @internalclass CScannerFunctorGE : public CScannerFunctorComp{public:    CScannerFunctorGE(CQueryExecEnv& env)     : CScannerFunctorComp(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        int cmpres = CmpEval(tr);        bool res = cmpres >= 0;        SetResult(tr.GetValue(), res);    }};/// LT function ////// @internalclass CScannerFunctorLT : public CScannerFunctorComp{public:    CScannerFunctorLT(CQueryExecEnv& env)     : CScannerFunctorComp(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        int cmpres = CmpEval(tr);        bool res = cmpres < 0;        SetResult(tr.GetValue(), res);    }};/// LE function ////// @internalclass CScannerFunctorLE : public CScannerFunctorComp{public:    CScannerFunctorLE(CQueryExecEnv& env)     : CScannerFunctorComp(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        int cmpres = CmpEval(tr);        bool res = cmpres <= 0;        SetResult(tr.GetValue(), res);    }};/// AND function ////// @internalclass CScannerFunctorAND : public CScannerFunctorArgN{public:    CScannerFunctorAND(CQueryExecEnv& env)     : CScannerFunctorArgN(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        GetArguments(tr, eCheckAll);        CBDB_QueryNode& qnode = tr.GetValue();        unsigned int size = m_ArgVector.size();        _ASSERT(size);        for (unsigned int i = 0; i < size; ++i) {            const string* arg = GetArg(i);            if (*arg == "0") {                qnode.SetValue("0");                return;            }        }        qnode.SetValue("1");    }};/// OR function ////// @internalclass CScannerFunctorOR : public CScannerFunctorArgN{public:    CScannerFunctorOR(CQueryExecEnv& env)     : CScannerFunctorArgN(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        GetArguments(tr, eCheckAll);        CBDB_QueryNode& qnode = tr.GetValue();        unsigned int size = m_ArgVector.size();        _ASSERT(size);        for (unsigned int i = 0; i < size; ++i) {            const string* arg = GetArg(i);            if (*arg == "1") {                qnode.SetValue("1");                return;            }        }        qnode.SetValue("0");    }};/// NOT function ////// @internalclass CScannerFunctorNOT : public CScannerFunctorArgN{public:    CScannerFunctorNOT(CQueryExecEnv& env)     : CScannerFunctorArgN(env)    {}    void Eval(CTreeNode<CBDB_QueryNode>& tr)    {        GetArguments(tr, eCheckAll);        CBDB_QueryNode& qnode = tr.GetValue();        unsigned int size = m_ArgVector.size();        _ASSERT(size);        const string* arg = GetArg(0);        if (*arg == "0") {            qnode.SetValue("1");        } else {            qnode.SetValue("0");        }    }};///////////////////////////////////////////////////////////////////////////////  CBDB_FileScanner//CBDB_FileScanner::CBDB_FileScanner(CBDB_File& db_file) : m_File(db_file){}CBDB_FileScanner::~CBDB_FileScanner(){}CBDB_FileScanner::EScanAction CBDB_FileScanner::OnRecordFound(){    return eContinue;}void CBDB_FileScanner::Scan(CBDB_Query& query){    ResolveFields(query);    CBDB_FileCursor cur(m_File);    cur.SetCondition(CBDB_FileCursor::eFirst);    while (cur.Fetch() == eBDB_Ok) {        bool res = Evaluate(query);        if (res) {            EScanAction act = OnRecordFound();            if (act == eStop) {                break;            }        }        query.ResetQueryClause();    } // while}void CBDB_FileScanner::Scan(CBDB_FileCursor& cur,                             CBDB_Query&      query){    ResolveFields(query);    while (cur.Fetch() == eBDB_Ok) {        bool res = Evaluate(query);        if (res) {            EScanAction act = OnRecordFound();            if (act == eStop) {                break;            }        }        query.ResetQueryClause();    } // while}/// The main tree evaluation functor////// @internalclass CScannerEvaluateFunc{public:     CScannerEvaluateFunc(CQueryExecEnv& env)    : m_QueryEnv(env),      m_Matcher(0)    {    }    ~CScannerEvaluateFunc()    {        delete m_Matcher;    }    CScannerEvaluateFunc(const CScannerEvaluateFunc& func)    : m_QueryEnv(func.m_QueryEnv),      m_Matcher(0)    {    }      ETreeTraverseCode     operator()(CTreeNode<CBDB_QueryNode>& tr, int delta);protected:    CQueryExecEnv&       m_QueryEnv;    CBoyerMooreMatcher*  m_Matcher;};ETreeTraverseCode CScannerEvaluateFunc::operator()(CTreeNode<CBDB_QueryNode>& tr, int delta){    CBDB_QueryNode& qnode = tr.GetValue();    // cout << delta << " " << tr.GetValue().GetValue() << endl;    if (delta == 0 || delta == 1) {        // If node has children, we skip it and process on the way back        if (!tr.IsLeaf())            return eTreeTraverse;    }    if (qnode.GetType() == CBDB_QueryNode::eValue) {        if (tr.GetParent() == 0) { // single top node            CBDB_File& dbf = m_QueryEnv.GetFile();                            if (!m_Matcher) {                const string& search_value = qnode.GetValue();                m_Matcher = s_MakeNewMatcher(search_value);            }            CBDB_File::TUnifiedFieldIndex fidx;            fidx = BDB_find_field(dbf, *m_Matcher);            qnode.SetAltValue(fidx ? "1" : "0");        }    }    if (!qnode.HasValue()) {        switch (qnode.GetType()) {        case CBDB_QueryNode::eValue:            break;        case CBDB_QueryNode::eOperator:        {            CBDB_QueryNode::EOperatorType eop = qnode.GetOperatorType();            switch (eop) {            case CBDB_QueryNode::eEQ:            {                CScannerFunctorEQ func(m_QueryEnv, qnode.IsNot());                func.Eval(tr);            }            break;            case CBDB_QueryNode::eGT:            {                CScannerFunctorGT func(m_QueryEnv);                func.Eval(tr);            }            break;            case CBDB_QueryNode::eGE:            {                CScannerFunctorGE func(m_QueryEnv);                func.Eval(tr);            }            break;            case CBDB_QueryNode::eLT:            {                CScannerFunctorLT func(m_QueryEnv);                func.Eval(tr);            }            break;            case CBDB_QueryNode::eLE:            {                CScannerFunctorLE func(m_QueryEnv);                func.Eval(tr);            }            break;            default:                _ASSERT(0);            } // switch eop        }        break;        case CBDB_QueryNode::eLogical:        {            CBDB_QueryNode::ELogicalType elogic = qnode.GetLogicType();            switch (elogic) {            case CBDB_QueryNode::eAnd:            {                CScannerFunctorAND func(m_QueryEnv);                func.Eval(tr);            }            break;            case CBDB_QueryNode::eOr:            {                CScannerFunctorOR func(m_QueryEnv);                func.Eval(tr);            }            break;            case CBDB_QueryNode::eNot:            {                CScannerFunctorNOT func(m_QueryEnv);                func.Eval(tr);            }            break;            default:                _ASSERT(0);            } // switch elogic        }        break;        default:            break;        } // switch node type    } // if    return eTreeTraverse;}bool CBDB_FileScanner::Evaluate(CBDB_Query& query){    ResolveFields(query);    CBDB_Query::TQueryClause& qtree = query.GetQueryClause();    CQueryExecEnv query_env(m_File);    CScannerEvaluateFunc scanner_eval(query_env);    TreeDepthFirstTraverse(qtree, scanner_eval);    const CBDB_QueryNode& qnode = qtree.GetValue();    const string& v_alt = qnode.GetAltValue();    if (v_alt.empty()) {        const string& v = qnode.GetValue();        if (v == "0")            return false;        return true;    } else {        if (v_alt == "0")            return false;    }    return true;}void CBDB_FileScanner::ResolveFields(CBDB_Query& query){    CBDB_Query::TQueryClause& qtree = query.GetQueryClause();    CQueryTreeFieldResolveFunc resolve_func(m_File);    TreeDepthFirstTraverse(qtree, resolve_func);}/// The main tree printing functor class./// Used for internal debugging purposes.////// @internal///class CQueryTreePrintFunc{public:     CQueryTreePrintFunc(CNcbiOstream& os)    : m_OStream(os),      m_Level(0)    {}    void PrintLevelMargin()    {        for (int i = 0; i < m_Level; ++i) {            m_OStream << "  ";        }    }      ETreeTraverseCode     operator()(const CTreeNode<CBDB_QueryNode>& tr, int delta)     {        const CBDB_QueryNode& qnode = tr.GetValue();        m_Level += delta;        if (delta < 0)            return eTreeTraverse;        PrintLevelMargin();        switch (qnode.GetType()) {        case CBDB_QueryNode::eValue:            m_OStream << qnode.GetValue();            break;        case CBDB_QueryNode::eOperator:            {                CBDB_QueryNode::EOperatorType eop = qnode.GetOperatorType();                switch (eop) {                case CBDB_QueryNode::eEQ:                    if (qnode.IsNot()) {                        m_OStream << "NOT EQ";                    } else {                        m_OStream << "EQ";                    }                    break;                case CBDB_QueryNode::eGT:                    m_OStream << "GT";                    break;                case CBDB_QueryNode::eGE:                    m_OStream << "GE";                    break;                case CBDB_QueryNode::eLT:                    m_OStream << "LT";                    break;                case CBDB_QueryNode::eLE:                    m_OStream << "LE";                    break;                default:                    _ASSERT(0);                } // switch eop            }            if (qnode.HasValue()) {                m_OStream << " => " << qnode.GetValue();            }            break;        case CBDB_QueryNode::eLogical:            {                CBDB_QueryNode::ELogicalType elogic = qnode.GetLogicType();                switch (elogic) {                case CBDB_QueryNode::eAnd:                    m_OStream << "AND";                    break;                case CBDB_QueryNode::eOr:                    m_OStream << "OR";                    break;                case CBDB_QueryNode::eNot:                    m_OStream << "NOT";                    break;                default:                    _ASSERT(0);                } // switch elogic            }            if (qnode.HasValue()) {                m_OStream << " => " << qnode.GetValue();            }            break;        case CBDB_QueryNode::eDBField:            m_OStream << "@" << qnode.GetValue();            break;        default:            if (qnode.HasValue()) {                m_OStream << qnode.GetValue();            }            break;        } // switch node type        m_OStream << "\n";        return eTreeTraverse;    }private:    CNcbiOstream&  m_OStream;    int            m_Level;};void BDB_PrintQueryTree(CNcbiOstream& os, const CBDB_Query& query){    // Here I use a const cast hack because TreeDepthFirstTraverse    // uses a non-cost iterators and semantics in the algorithm.    // When a const version of TreeDepthFirstTraverse is ready    // we can get rid of this...    const CBDB_Query::TQueryClause& qtree = query.GetQueryClause();    CBDB_Query::TQueryClause& qtree_nc =            const_cast<CBDB_Query::TQueryClause&>(qtree);    CQueryTreePrintFunc func(os);    TreeDepthFirstTraverse(qtree_nc, func);}END_NCBI_SCOPE/* * =========================================================================== * $Log: bdb_query.cpp,v $ * Revision 1000.1  2004/06/01 18:37:29  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13 * * Revision 1.13  2004/05/17 20:55:11  gorelenk * Added include of PCH ncbi_pch.hpp * * Revision 1.12  2004/03/23 16:58:18  kuznets * Fixed compilation warning (GCC) * * Revision 1.11  2004/03/23 16:37:54  kuznets * Implemented NOT predicate * * Revision 1.10  2004/03/23 14:51:19  kuznets * Implemented logical NOT, <, <=, >, >= * * Revision 1.9  2004/03/17 16:35:42  kuznets * EQ functor improved to enable substring searches * * Revision 1.8  2004/03/11 22:27:49  ucko * Pull the bodies of CScannerFunctorArgN::~CScannerFunctorArgN and * CScannerEvaluateFunc::operator() out of line so that they can call * s_MakeNewMatcher.  (WorkShop prohibits inline or template functions * from calling [file-]static functions.) * * Revision 1.7  2004/03/11 18:42:01  kuznets * code cleaned up, minor bug fix * * Revision 1.6  2004/03/11 13:16:10  kuznets * Bug fixed corner case when query is one word only * * Revision 1.5  2004/03/08 13:35:07  kuznets * Modified queries to do full text searches * * Revision 1.4  2004/03/01 14:03:57  kuznets * CQueryTreeFieldResolveFunc improved to remove string marks * * Revision 1.3  2004/02/24 14:12:45  kuznets * CBDB_Query add new constructor parameter and several helper functions * * Revision 1.2  2004/02/19 17:35:57  kuznets * + BDB_PrintQueryTree (tree printing utility function for debugging) * * Revision 1.1  2004/02/17 17:26:45  kuznets * Initial revision * * * =========================================================================== */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?