1
0
Fork 0

micro optimizations

This commit is contained in:
jsteemann 2016-11-01 15:23:28 +01:00
parent 5e3a643df3
commit 31350a5c14
7 changed files with 34 additions and 33 deletions

View File

@ -28,6 +28,7 @@
#include "Aql/Graphs.h"
#include "Aql/Query.h"
#include "Basics/Exceptions.h"
#include "Basics/StringRef.h"
#include "Basics/StringUtils.h"
#include "Basics/tri-strings.h"
#include "Cluster/ClusterInfo.h"
@ -1041,12 +1042,12 @@ AstNode* Ast::createNodeCollectionList(AstNode const* edgeCollections) {
auto ci = ClusterInfo::instance();
auto ss = ServerState::instance();
auto doTheAdd = [&](std::string name) {
auto doTheAdd = [&](std::string const& name) {
_query->collections()->add(name, TRI_TRANSACTION_READ);
if (ss->isCoordinator()) {
try {
auto c = ci->getCollection(_query->vocbase()->name(), name);
auto names = c->realNames();
auto const& names = c->realNames();
for (auto const& n : names) {
_query->collections()->add(n, TRI_TRANSACTION_READ);
}
@ -1374,7 +1375,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
bool isWriteCollection = false;
for (auto const& it : _writeCollections) {
if (it->type == NODE_TYPE_PARAMETER && param == it->getString()) {
if (it->type == NODE_TYPE_PARAMETER && StringRef(param) == StringRef(it->getStringValue(), it->getStringLength())) {
isWriteCollection = true;
break;
}
@ -1411,7 +1412,7 @@ void Ast::injectBindParameters(BindParameters& parameters) {
// parameter
for (size_t i = 0; i < _writeCollections.size(); ++i) {
if (_writeCollections[i]->type == NODE_TYPE_PARAMETER &&
param == _writeCollections[i]->getString()) {
StringRef(param) == StringRef(_writeCollections[i]->getStringValue(), _writeCollections[i]->getStringLength())) {
_writeCollections[i] = node;
// no break here. replace all occurrences
}
@ -2468,7 +2469,7 @@ AstNode* Ast::optimizeBinaryOperatorRelational(AstNode* node) {
bool const lhsIsConst = lhs->isConstant();
if (!lhsIsConst) {
if (rhs->numMembers() >= 8 &&
if (rhs->numMembers() >= AstNode::SortNumberThreshold &&
rhs->type == NODE_TYPE_ARRAY &&
(node->type == NODE_TYPE_OPERATOR_BINARY_IN ||
node->type == NODE_TYPE_OPERATOR_BINARY_NIN)) {
@ -2476,7 +2477,7 @@ AstNode* Ast::optimizeBinaryOperatorRelational(AstNode* node) {
// it, so we can find elements quicker later using a binary search
// note that sorting will also set a flag for the node
rhs->sort();
// set sortedness for IN/NIN operator node
// remove the sortedness bit for IN/NIN operator node, as the operand is now sorted
node->setBoolValue(false);
}
@ -2776,7 +2777,7 @@ AstNode* Ast::optimizeIndexedAccess(AstNode* node) {
// found a string value (e.g. a['foo']). now turn this into
// an attribute access (e.g. a.foo) in order to make the node qualify
// for being turned into an index range later
std::string indexValue(index->getString());
StringRef indexValue(index->getString());
if (!indexValue.empty() && (indexValue[0] < '0' || indexValue[0] > '9')) {
// we have to be careful with numeric values here...

View File

@ -1033,7 +1033,7 @@ void AstNode::toVelocyPackValue(VPackBuilder& builder) const {
for (size_t i = 0; i < n; ++i) {
auto member = getMemberUnchecked(i);
if (member != nullptr) {
builder.add(VPackValue(member->getString()));
builder.add(VPackValuePair(member->getStringValue(), member->getStringLength(), VPackValueType::String));
member->getMember(0)->toVelocyPackValue(builder);
}
}
@ -1084,7 +1084,7 @@ void AstNode::toVelocyPack(VPackBuilder& builder, bool verbose) const {
type == NODE_TYPE_ATTRIBUTE_ACCESS ||
type == NODE_TYPE_OBJECT_ELEMENT || type == NODE_TYPE_FCALL_USER) {
// dump "name" of node
builder.add("name", VPackValue(getString()));
builder.add("name", VPackValuePair(getStringValue(), getStringLength(), VPackValueType::String));
}
if (type == NODE_TYPE_FCALL) {
auto func = static_cast<Function*>(getData());

View File

@ -232,6 +232,8 @@ struct AstNode {
public:
static constexpr size_t SortNumberThreshold = 8;
/// @brief return the string value of a node, as an std::string
std::string getString() const;

View File

@ -172,9 +172,6 @@ static ShortestPathOptions CreateShortestPathOptions(AstNode const* node) {
return options;
}
/// @brief create the plan
ExecutionPlan::ExecutionPlan(Ast* ast)
: _ids(),

View File

@ -260,7 +260,7 @@ bool Expression::findInArray(AqlValue const& left, AqlValue const& right,
size_t const n = right.length();
if (n > 3 &&
if (n >= AstNode::SortNumberThreshold &&
(node->getMember(1)->isSorted() ||
((node->type == NODE_TYPE_OPERATOR_BINARY_IN ||
node->type == NODE_TYPE_OPERATOR_BINARY_NIN) && node->getBoolValue()))) {
@ -699,10 +699,11 @@ AqlValue Expression::executeSimpleExpressionObject(
Functions::Stringify(trx, adapter, slice);
std::string key(buffer->begin(), buffer->length());
builder->add(VPackValue(key));
builder->add(VPackValuePair(buffer->begin(), buffer->length(), VPackValueType::String));
if (mustCheckUniqueness) {
std::string key(buffer->begin(), buffer->length());
// note each individual object key name with latest value position
auto it = uniqueKeyValues.find(key);
@ -721,9 +722,10 @@ AqlValue Expression::executeSimpleExpressionObject(
} else {
TRI_ASSERT(member->type == NODE_TYPE_OBJECT_ELEMENT);
builder->add(VPackValuePair(member->getStringValue(), member->getStringLength(), VPackValueType::String));
if (mustCheckUniqueness) {
std::string key(member->getString());
builder->add(VPackValue(key));
// note each individual object key name with latest value position
auto it = uniqueKeyValues.find(key);
@ -736,10 +738,6 @@ AqlValue Expression::executeSimpleExpressionObject(
(*it).second = i;
isUnique = false;
}
} else {
// object has only one key or multiple unique keys. no need to de-duplicate
builder->add(VPackValuePair(member->getStringValue(), member->getStringLength(), VPackValueType::String));
}
// value
@ -852,8 +850,8 @@ AqlValue Expression::executeSimpleExpressionFCall(
AstNode const* node, arangodb::Transaction* trx, bool& mustDestroy) {
mustDestroy = false;
// some functions have C++ handlers
// check if the called function has one
// only some functions have C++ handlers
// check that the called function actually has one
auto func = static_cast<Function*>(node->getData());
TRI_ASSERT(func->implementation != nullptr);
@ -872,7 +870,7 @@ AqlValue Expression::executeSimpleExpressionFCall(
auto arg = member->getMemberUnchecked(i);
if (arg->type == NODE_TYPE_COLLECTION) {
parameters.emplace_back(AqlValue(arg->getString()));
parameters.emplace_back(arg->getStringValue(), arg->getStringLength());
destroyParameters.push_back(true);
} else {
bool localMustDestroy;
@ -883,11 +881,12 @@ AqlValue Expression::executeSimpleExpressionFCall(
}
TRI_ASSERT(parameters.size() == destroyParameters.size());
TRI_ASSERT(parameters.size() == n);
AqlValue a = func->implementation(_ast->query(), trx, parameters);
mustDestroy = true; // function result is always dynamic
for (size_t i = 0; i < parameters.size(); ++i) {
for (size_t i = 0; i < n; ++i) {
if (destroyParameters[i]) {
parameters[i].destroy();
}
@ -1033,7 +1032,7 @@ AqlValue Expression::executeSimpleExpressionNaryAndOr(
if (node->type == NODE_TYPE_OPERATOR_NARY_AND) {
for (size_t i = 0; i < count; ++i) {
AqlValue check =
executeSimpleExpression(node->getMember(i), trx, mustDestroy, true);
executeSimpleExpression(node->getMemberUnchecked(i), trx, mustDestroy, true);
if (!check.toBoolean()) {
// Check is false. Return it.
return check;
@ -1050,7 +1049,7 @@ AqlValue Expression::executeSimpleExpressionNaryAndOr(
// OR
for (size_t i = 0; i < count; ++i) {
AqlValue check =
executeSimpleExpression(node->getMember(i), trx, mustDestroy, true);
executeSimpleExpression(node->getMemberUnchecked(i), trx, mustDestroy, true);
if (check.toBoolean()) {
// Check is true. Return it.
return check;

View File

@ -120,7 +120,6 @@ void arangodb::aql::sortInValuesRule(Optimizer* opt, ExecutionPlan* plan,
continue;
}
static size_t const Threshold = 8;
auto ast = plan->getAst();
AstNode const* originalArg = nullptr;
@ -150,7 +149,7 @@ void arangodb::aql::sortInValuesRule(Optimizer* opt, ExecutionPlan* plan,
}
if (testNode->type == NODE_TYPE_ARRAY &&
testNode->numMembers() < Threshold) {
testNode->numMembers() < AstNode::SortNumberThreshold) {
// number of values is below threshold
continue;
}
@ -169,7 +168,7 @@ void arangodb::aql::sortInValuesRule(Optimizer* opt, ExecutionPlan* plan,
size_t nrItems = 0;
sub->getSubquery()->getCost(nrItems);
if (nrItems < Threshold) {
if (nrItems < AstNode::SortNumberThreshold) {
continue;
}

View File

@ -42,12 +42,15 @@ namespace basics {
struct AttributeName {
std::string name;
bool shouldExpand;
explicit AttributeName(std::string const& name, bool expand)
: name(name), shouldExpand(expand) {}
explicit AttributeName(arangodb::StringRef const& name);
AttributeName(std::string const& name, bool expand)
: name(name), shouldExpand(expand) {}
AttributeName(std::string&& name, bool expand)
: name(std::move(name)), shouldExpand(expand) {}
AttributeName(arangodb::StringRef const& name, bool expand);
AttributeName(AttributeName const& other)