diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 6fc667a4b7..6f93df7f8d 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -202,7 +202,15 @@ namespace triagens { //////////////////////////////////////////////////////////////////////////////// virtual void appendAsString (std::string& st, int indent = 0); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief estimate the cost of the node . . . +//////////////////////////////////////////////////////////////////////////////// + virtual double estimateCost () const = 0; + //TODO nodes should try harder to estimate their own cost, i.e. the cost + //of performing the operation of the node . . . + void walk (WalkerWorker* worker); //////////////////////////////////////////////////////////////////////////////// @@ -309,6 +317,14 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a singleton is 1 +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1; + } + }; // ----------------------------------------------------------------------------- @@ -374,6 +390,15 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an enumerate collection node is a multiple of the cost of +/// its unique dependency +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1000 * this[0].estimateCost(); //FIXME change this! + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -461,6 +486,14 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an enumerate list node is . . . FIXME +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1000 * this[0].estimateCost(); //FIXME change this, 1000 is arbitrary + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -543,6 +576,16 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a limit node is the minimum of the _limit, and the cost +/// the dependency . . . +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1.005 * std::min(static_cast(_limit), + this[0].estimateCost());//FIXME change this? + } + //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// @@ -617,6 +660,15 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a projection node is the cost of the unique dependency, +// times a small constant . . . +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1.005 * this[0].estimateCost();//FIXME change this? + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -732,6 +784,15 @@ namespace triagens { return _expression; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a calculation node is the cost of the unique dependency +// times a constant +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 2*this[0].estimateCost(); //FIXME change this! + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -820,6 +881,15 @@ namespace triagens { return _subquery; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a subquery node is the cost of its unique dependency +/// times a small constant +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 1.005*this[0].estimateCost();//FIXME change this! + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -899,6 +969,16 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a filter node is . . . FIXME +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return this[0].estimateCost() * 0.005 + this[0].estimateCost() * 0.10; + //FIXME! 0.005 is the cost of doing the filter node under the + //assumption that it returns 10% of the results of its dependency + } + //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// @@ -970,6 +1050,15 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a sort node is . . . FIXME +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + double depCost = this[0].estimateCost(); + return log(depCost) * depCost;//FIXME change this! + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -1049,6 +1138,14 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of an aggregate node is . . . FIXME +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return 2 * this[0].estimateCost();//FIXME change this! + } + //////////////////////////////////////////////////////////////////////////////// /// @brief private data //////////////////////////////////////////////////////////////////////////////// @@ -1135,6 +1232,14 @@ namespace triagens { return static_cast(c); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief the cost of a return node is the cost of its only dependency . . . +//////////////////////////////////////////////////////////////////////////////// + + double estimateCost () const { + return this[0].estimateCost(); + } + //////////////////////////////////////////////////////////////////////////////// /// @brief we need to know the offset and limit //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index 6482be5d97..f0bba48896 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -83,7 +83,8 @@ ExecutionPlan* ExecutionPlan::instanciateFromAst (Ast const* ast) { try { plan->_root = plan->fromNode(ast, root); - // std::cout << plan->_root->toJson().toString() << "\n"; + std::cout << plan->_root->toJson().toString() << "\n"; + std::cout << "ESTIMATED COST = €" << plan->_root->estimateCost() << "\n"; return plan; } diff --git a/arangod/Aql/ExecutionPlan.h b/arangod/Aql/ExecutionPlan.h index d97289366e..ff61366823 100644 --- a/arangod/Aql/ExecutionPlan.h +++ b/arangod/Aql/ExecutionPlan.h @@ -31,6 +31,7 @@ #define ARANGODB_AQL_EXECUTION_PLAN_H 1 #include "Basics/Common.h" +#include "arangod/Aql/ExecutionNode.h" namespace triagens { namespace aql { @@ -87,6 +88,15 @@ namespace triagens { return _root; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief get the estimated cost . . . +//////////////////////////////////////////////////////////////////////////////// + + //double estimateCost () const { + // TRI_ASSERT(_root != nullptr); + // return _root->estimateCost(); + //} + // ----------------------------------------------------------------------------- // --SECTION-- private methods // -----------------------------------------------------------------------------