Column-oriented GPU-accelerated Database Management System
CoGaDB
|
00001 00002 #pragma once 00003 00004 #include <map> 00005 00006 #include <core/scheduling_decision.hpp> 00007 00008 #include <boost/shared_ptr.hpp> 00009 #include <core/specification.hpp> 00010 #include <query_processing/typed_operator.hpp> 00011 #include <util/get_name.hpp> 00012 00013 namespace hype { 00014 namespace queryprocessing { 00015 00016 //forward declaration 00017 class Node; 00018 //forward declaration 00019 template <typename Type> 00020 class TypedNode; 00021 00022 template <typename Type> 00023 class PhysicalQueryPlan; 00024 00025 //make Operator Mapper a singleton! 00026 //when OperatorMapper is instanciated, add second tempel argument where user has to specify a function that returns the Physical_Operator_Map; 00027 00028 //OperatorMapper<TablePtr,initFunction> mapper; 00029 //boost::function<std::map<std::string,boost::function<boost::shared_ptr<TypedOperator<Type> > (const stemod::SchedulingDecision&)> > function> ()> 00030 //each node has to get one 00031 00032 template <typename Type> 00033 struct OperatorMapper_Helper_Template { 00034 typedef Type type; 00035 typedef TypedNode<Type> TypedLogicalNode; 00036 typedef boost::shared_ptr<TypedLogicalNode> TypedNodePtr; 00037 //typedef TypedOperator<Type> TypedOperator; 00038 typedef boost::shared_ptr<TypedOperator<Type> > TypedOperatorPtr; 00039 typedef boost::function < TypedOperatorPtr(TypedLogicalNode&, const hype::SchedulingDecision&, TypedOperatorPtr, TypedOperatorPtr) > Create_Typed_Operator_Function; 00040 typedef std::map<std::string, Create_Typed_Operator_Function> Physical_Operator_Map; 00041 typedef boost::shared_ptr<Physical_Operator_Map> Physical_Operator_Map_Ptr; 00042 //typedef boost::function<Physical_Operator_Map_Ptr ()> Map_Init_Function; 00043 typedef Physical_Operator_Map_Ptr(Map_Init_Function)(); 00044 typedef boost::shared_ptr<PhysicalQueryPlan<Type> > PhysicalQueryPlanPtr; 00045 }; 00046 00047 template <typename Type, typename OperatorMapper_Helper_Template<Type>::Map_Init_Function& function> 00048 class OperatorMapper { 00049 public: 00050 //typedef boost::shared_ptr<boost::shared_ptr<TypedOperator<Type> > > (*Create_Typed_Operator_Function)(const stemod::SchedulingDecision& sched_dec); 00051 //typedef boost::function<boost::shared_ptr<TypedOperator<Type> > (const stemod::SchedulingDecision&)> Create_Typed_Operator_Function_t; 00052 //typedef std::map<std::string,Create_Typed_Operator_Function_t> Physical_Operator_Map; 00053 00054 typedef typename OperatorMapper_Helper_Template<Type>::Create_Typed_Operator_Function Create_Typed_Operator_Function; 00055 typedef typename OperatorMapper_Helper_Template<Type>::Physical_Operator_Map Physical_Operator_Map; 00056 typedef typename OperatorMapper_Helper_Template<Type>::Physical_Operator_Map_Ptr Physical_Operator_Map_Ptr; 00057 typedef typename OperatorMapper_Helper_Template<Type>::Map_Init_Function Map_Init_Function; 00058 //typedef typename OperatorMapper_Helper_Template<Type>::TypedOperator TypedOperator; 00059 typedef typename OperatorMapper_Helper_Template<Type>::TypedOperatorPtr TypedOperatorPtr; 00060 typedef typename OperatorMapper_Helper_Template<Type>::TypedLogicalNode TypedLogicalNode; 00061 typedef typename OperatorMapper_Helper_Template<Type>::TypedNodePtr TypedNodePtr; 00062 00063 00064 static const Physical_Operator_Map_Ptr static_algorithm_name_to_physical_operator_map_ptr; //=function(); 00065 00066 OperatorMapper() { 00067 } //: algorithm_name_to_physical_operator_map_(){} 00068 00070 TypedOperatorPtr getPhysicalOperator(TypedLogicalNode& logical_node, const hype::Tuple& features_of_input_dataset, TypedOperatorPtr left_child, TypedOperatorPtr right_child, DeviceTypeConstraint dev_constr) const { 00071 const std::string& operation_name = logical_node.getOperationName(); 00072 00073 OperatorSpecification op_spec(operation_name, 00074 features_of_input_dataset, 00075 //parameters are the same, because in the query processing engine, we model copy oeprations explicitely, so the copy cost have to be zero 00076 hype::PD_Memory_0, //input data is in CPU RAM 00077 hype::PD_Memory_0); //output data has to be stored in CPU RAM 00078 00079 //DeviceConstraint dev_constr; 00080 00081 hype::SchedulingDecision sched_dec = hype::Scheduler::instance().getOptimalAlgorithm(op_spec, dev_constr); 00082 //find operation name in map 00083 typename Physical_Operator_Map::iterator it = static_algorithm_name_to_physical_operator_map_ptr->find(sched_dec.getNameofChoosenAlgorithm()); 00084 if (it == static_algorithm_name_to_physical_operator_map_ptr->end()) { 00085 std::cout << "[HyPE library] FATAL Error! " << typeid (OperatorMapper<Type, function>).name() << ": Missing entry in PhysicalOperatorMap for Algorithm '" 00086 << sched_dec.getNameofChoosenAlgorithm() << "'" << std::endl; 00087 exit(-1); 00088 } 00089 TypedOperatorPtr physical_operator; 00090 //call create function 00091 if (it->second) { 00092 physical_operator = it->second(logical_node, sched_dec, left_child, right_child); 00093 } else { 00094 std::cout << "[HyPE library] FATAL Error! Invalid Function Pointer in OperationMapper::getPhysicalOperator()" << std::endl; 00095 exit(-1); 00096 } 00097 //return physical operator 00098 return physical_operator; 00099 } 00100 //insert map definition here 00101 //Physical_Operator_Map algorithm_name_to_physical_operator_map_; 00102 }; 00103 00104 template <typename Type, typename OperatorMapper_Helper_Template<Type>::Map_Init_Function& function> 00105 const typename OperatorMapper<Type, function>::Physical_Operator_Map_Ptr OperatorMapper<Type, function>::static_algorithm_name_to_physical_operator_map_ptr = function(); 00106 00107 00108 00109 //for logical plan, create derived class, which gets as template argument the Types of the corresponding physical Operators 00110 00111 class Node { 00112 public: 00113 typedef boost::shared_ptr<Node> NodePtr; 00114 00115 Node(DeviceConstraint dev_constr = DeviceConstraint()) : parent_(), left_(), right_(), level_(0), dev_constr_(dev_constr) { 00116 00117 } 00118 00119 /* 00120 Node(NodePtr parent) : parent_(parent), left_(), right_(), level_(0){ 00121 00122 } 00123 00124 Node(NodePtr parent, NodePtr left, NodePtr right) : parent_(parent), left_(left), right_(right), level_(0){ 00125 00126 }*/ 00127 00128 virtual ~Node() { 00129 } 00130 00131 bool isRoot() const { 00132 if (parent_.get() == NULL) return true; 00133 return false; 00134 } 00135 00136 bool isLeaf() const { 00137 if (left_.get() == NULL && right_.get() == NULL) return true; 00138 return false; 00139 } 00140 00141 const NodePtr getLeft() const { 00142 return left_; 00143 } 00144 00145 const NodePtr getRight() const { 00146 return right_; 00147 } 00148 00149 const NodePtr getParent() const{ 00150 return parent_; 00151 } 00152 00153 unsigned int getLevel() { 00154 return level_; 00155 } 00156 00157 void setLevel(unsigned int level) { 00158 level_ = level; 00159 } 00160 00161 virtual unsigned int getOutputResultSize() const = 0; 00162 00163 virtual double getSelectivity() const = 0; 00164 00165 virtual std::string getOperationName() const = 0; 00166 00167 virtual std::string toString(bool verbose=false) const{ 00168 if(verbose){ 00169 return this->getOperationName(); 00170 //return this->getOperationName()+std::string("\t")+util::getName(this->dev_constr_); 00171 }else{ 00172 return this->getOperationName(); 00173 } 00174 } 00175 00176 //const std::string& getOperationName() const; 00177 00178 void setLeft(NodePtr left) { 00179 left_ = left; 00180 //left->setParent(left_); 00181 } 00182 00183 void setRight(NodePtr right) { 00184 right_ = right; 00185 //right->setParent(right_); 00186 } 00187 00188 void setParent(NodePtr parent) { 00189 parent_ = parent; 00190 } 00191 00192 const DeviceConstraint& getDeviceConstraint() const { 00193 return this->dev_constr_; 00194 } 00195 00196 protected: 00197 NodePtr parent_; 00198 NodePtr left_; 00199 NodePtr right_; 00200 unsigned int level_; 00201 DeviceConstraint dev_constr_; 00202 //std::string operation_name_; 00203 }; 00204 00205 // std::string Node::toString(bool) const{ 00206 // return this->getOperationName(); 00207 // } 00208 00209 typedef Node::NodePtr NodePtr; 00210 00211 /* 00212 Automatic Processing Device Selector 00213 AProDeS 00214 00215 Automatic Processing Device Selector for Coprocessing 00216 AProDeSCo*/ 00217 00218 template <typename Type> 00219 class TypedNode : public Node { 00220 public: 00221 typedef Type NodeElementType; 00222 typedef typename OperatorMapper_Helper_Template<Type>::Physical_Operator_Map Physical_Operator_Map; 00223 typedef typename OperatorMapper_Helper_Template<Type>::Physical_Operator_Map_Ptr Physical_Operator_Map_Ptr; 00224 typedef typename OperatorMapper_Helper_Template<Type>::TypedOperatorPtr TypedOperatorPtr; 00225 00226 TypedNode(DeviceConstraint dev_constr) : Node(dev_constr) { 00227 00228 } 00229 00230 virtual TypedOperatorPtr getOptimalOperator(TypedOperatorPtr left_child = NULL, TypedOperatorPtr right_child = NULL, DeviceTypeConstraint dev_constr = ANY_DEVICE) = 0; 00231 virtual Physical_Operator_Map_Ptr getPhysical_Operator_Map() = 0; 00232 00233 virtual ~TypedNode() { 00234 } 00235 00236 }; 00237 00238 template <typename Type, typename OperatorMapper_Helper_Template<Type>::Map_Init_Function& function> 00239 class TypedNode_Impl : public TypedNode<Type> { 00240 public: 00241 00242 typedef typename TypedNode<Type>::Physical_Operator_Map Physical_Operator_Map; 00243 typedef typename TypedNode<Type>::Physical_Operator_Map_Ptr Physical_Operator_Map_Ptr; 00244 typedef typename TypedNode<Type>::TypedOperatorPtr TypedOperatorPtr; 00245 //typedef OperatorMapper<Type,function> OperatorMapper; 00246 00247 TypedNode_Impl(bool use_selectivity_estimation = false, DeviceConstraint dev_constr = DeviceConstraint()) : TypedNode<Type>(dev_constr), operator_mapper_(), use_selectivity_estimation_(use_selectivity_estimation) { 00248 customSelectivity = -1; 00249 } 00250 00251 virtual ~TypedNode_Impl() { 00252 } 00253 00254 virtual TypedOperatorPtr getOptimalOperator(TypedOperatorPtr left_child, TypedOperatorPtr right_child, DeviceTypeConstraint dev_constr) { 00255 hype::Tuple t; 00256 if (this->left_) { //if left child is valid (has to be by convention!), add input data size 00257 t.push_back(this->left_->getOutputResultSize()); 00258 if (this->right_) { //if right child is valid (not null), add input data size for it as well 00259 t.push_back(this->right_->getOutputResultSize()); 00260 } 00261 } 00262 if (use_selectivity_estimation_) 00263 t.push_back(this->getSelectivity()); //add selectivity of this operation, when use_selectivity_estimation_ is true 00264 00265 return operator_mapper_.getPhysicalOperator(*this, t, left_child, right_child, dev_constr); //this->getOperationName(), t, left_child, right_child); 00266 } 00267 00268 virtual Physical_Operator_Map_Ptr getPhysical_Operator_Map() { 00269 return OperatorMapper<Type, function>::static_algorithm_name_to_physical_operator_map_ptr; 00270 } 00271 00272 double getSelectivity() const { 00273 if (customSelectivity != -1) { 00274 return customSelectivity; 00275 } else { 00276 return getCalculatedSelectivity(); 00277 } 00278 } 00279 00280 void setSelectivity(double selectivity) { 00281 customSelectivity = selectivity; 00282 } 00283 //boost::shared_ptr<> toPhysicalNode(); 00284 00285 protected: 00286 OperatorMapper<Type, function> operator_mapper_; 00287 bool use_selectivity_estimation_; 00288 double customSelectivity; 00289 00290 virtual double getCalculatedSelectivity() const { 00291 return 0.1; 00292 } 00293 }; 00294 00295 }; //end namespace queryprocessing 00296 }; //end namespace hype