|
NCBI C++ ToolKit
|
00001 /* $Id: query_exec.cpp 51033 2011-08-26 17:19:51Z falkrb $ 00002 * =========================================================================== 00003 * 00004 * PUBLIC DOMAIN NOTICE 00005 * National Center for Biotechnology Information 00006 * 00007 * This software/database is a "United States Government Work" under the 00008 * terms of the United States Copyright Act. It was written as part of 00009 * the author's official duties as a United States Government employee and 00010 * thus cannot be copyrighted. This software/database is freely available 00011 * to the public for use. The National Library of Medicine and the U.S. 00012 * Government have not placed any restriction on its use or reproduction. 00013 * 00014 * Although all reasonable efforts have been taken to ensure the accuracy 00015 * and reliability of the software and data, the NLM and the U.S. 00016 * Government do not and cannot warrant the performance or results that 00017 * may be obtained by using this software or data. The NLM and the U.S. 00018 * Government disclaim all warranties, express or implied, including 00019 * warranties of performance, merchantability or fitness for any particular 00020 * purpose. 00021 * 00022 * Please cite the author in any work or product based on this material. 00023 * 00024 * =========================================================================== 00025 * 00026 * Authors: Anatoliy Kuznetsov 00027 * 00028 * File Description: 00029 * Query execution implementations 00030 * 00031 */ 00032 00033 00034 #include <ncbi_pch.hpp> 00035 #include <corelib/ncbitime.hpp> 00036 #include <util/qparse/query_exec.hpp> 00037 00038 BEGIN_NCBI_SCOPE 00039 00040 CQueryFunctionBase::~CQueryFunctionBase() 00041 { 00042 } 00043 00044 void CQueryFunctionBase::MakeArgVector(CQueryParseTree::TNode& qnode, 00045 TArgVector& args) 00046 { 00047 args.resize(0); 00048 CTreeNode<CQueryParseNode>::TNodeList_I it = qnode.SubNodeBegin(); 00049 CTreeNode<CQueryParseNode>::TNodeList_I it_end = qnode.SubNodeEnd(); 00050 int i = 0; 00051 for (; it != it_end; ++it, ++i) { 00052 CTreeNode<CQueryParseNode>* arg_node = *it; 00053 args.push_back(arg_node); 00054 } // for 00055 } 00056 00057 CQueryParseTree::TNode* 00058 CQueryFunctionBase::GetArg0(CQueryParseTree::TNode& qnode) 00059 { 00060 CTreeNode<CQueryParseNode>::TNodeList_I it = qnode.SubNodeBegin(); 00061 CTreeNode<CQueryParseNode>::TNodeList_I it_end = qnode.SubNodeEnd(); 00062 if (it == it_end) 00063 return 0; 00064 return *it; 00065 } 00066 00067 00068 CQueryParseTree& CQueryFunctionBase::GetQueryTree() 00069 { 00070 return *(GetExec().GetQTree()); 00071 } 00072 00073 00074 00075 00076 00077 00078 CQueryExec::CQueryExec() 00079 : m_FuncReg(CQueryParseNode::eMaxType), 00080 m_QTree(0), 00081 m_ExceptionCount(0), 00082 m_QueriedCount(0) 00083 { 00084 for (size_t i = 0; i < m_FuncReg.size(); ++i) { 00085 m_FuncReg[i] = 0; 00086 } 00087 } 00088 00089 CQueryExec::~CQueryExec() 00090 { 00091 for (size_t i = 0; i < m_FuncReg.size(); ++i) { 00092 delete m_FuncReg[i]; 00093 } 00094 } 00095 00096 void CQueryExec::AddFunc(CQueryParseNode::EType func_type, 00097 CQueryFunctionBase* func) 00098 { 00099 int i = func_type; 00100 delete m_FuncReg[i]; 00101 m_FuncReg[i] = func; 00102 func->SetExec(*this); 00103 } 00104 00105 void CQueryExec::AddImplicitSearchFunc(CQueryFunctionBase* func) 00106 { 00107 m_ImplicitSearchFunc.reset(func); 00108 } 00109 00110 00111 00112 00113 00114 /// Expression evaluation visitor functor 00115 /// 00116 /// @internal 00117 /// 00118 class CQueryExecEvalFunc 00119 { 00120 public: 00121 CQueryExecEvalFunc(CQueryExec& exec) 00122 : m_Exec(exec) 00123 {} 00124 00125 00126 ETreeTraverseCode 00127 operator()(CTreeNode<CQueryParseNode>& tr, int delta) 00128 { 00129 CQueryParseNode& qnode = tr.GetValue(); 00130 if (delta == 0 || delta == 1) { 00131 // If node has children, we skip it and process on the way back 00132 if (!tr.IsLeaf()) { 00133 return eTreeTraverse; 00134 } 00135 } 00136 CQueryParseNode::EType func_type = qnode.GetType(); 00137 CQueryFunctionBase* func = 0; 00138 00139 // check if execution env has implicit search configured 00140 // and value node is derives from a logical node (AND, OR). 00141 // in this case we fire implicit search 00142 // 00143 if (m_Exec.GetImplicitSearchFunc()) { 00144 if (qnode.IsValue()) { 00145 CTreeNode<CQueryParseNode>* parent = tr.GetParent(); 00146 if (parent && parent->GetValue().IsLogic()) { 00147 func = m_Exec.GetImplicitSearchFunc(); 00148 } 00149 } 00150 } 00151 00152 if (!func) { 00153 func = m_Exec.GetFunc(func_type); 00154 } 00155 if (func == 0) { // function not registered 00156 // values (string, int, etc) do not require evaluation 00157 if (qnode.IsValue()) { 00158 return eTreeTraverse; 00159 } 00160 NCBI_THROW(CQueryParseException, eUnknownFunction, 00161 "Query execution failed. Unknown function:" + qnode.GetOrig()); 00162 } 00163 00164 CStopWatch sw(CStopWatch::eStart); 00165 {{ 00166 func->Evaluate(tr); 00167 }} 00168 double e = sw.Elapsed(); 00169 qnode.SetElapsed(e); 00170 00171 return eTreeTraverse; 00172 } 00173 private: 00174 CQueryExec& m_Exec; 00175 }; 00176 00177 00178 void CQueryExec::Evaluate(CQueryParseTree& qtree) 00179 { 00180 m_QTree = &qtree; 00181 CQueryExecEvalFunc visitor(*this); 00182 TreeDepthFirstTraverse(*qtree.GetQueryTree(), visitor); 00183 m_QTree = 0; 00184 } 00185 00186 00187 void CQueryExec::Evaluate(CQueryParseTree& qtree, CQueryParseTree::TNode& node) 00188 { 00189 m_QTree = &qtree; 00190 CQueryExecEvalFunc visitor(*this); 00191 TreeDepthFirstTraverse(node, visitor); 00192 m_QTree = 0; 00193 } 00194 00195 00196 END_NCBI_SCOPE
1.7.5.1
Modified on Wed May 23 13:38:18 2012 by modify_doxy.py rev. 337098