1
0
Fork 0
arangodb/arangod/Aql/ClusterNodes.cpp

232 lines
9.2 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Max Neunhoeffer
////////////////////////////////////////////////////////////////////////////////
#include "ClusterNodes.h"
#include "Aql/Ast.h"
#include "Aql/Collection.h"
#include "Aql/ExecutionPlan.h"
using namespace triagens::basics;
using namespace triagens::aql;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor for RemoteNode from Json
////////////////////////////////////////////////////////////////////////////////
RemoteNode::RemoteNode(ExecutionPlan* plan, triagens::basics::Json const& base)
: ExecutionNode(plan, base),
_vocbase(plan->getAst()->query()->vocbase()),
_collection(plan->getAst()->query()->collections()->get(
JsonHelper::checkAndGetStringValue(base.json(), "collection"))),
_server(JsonHelper::checkAndGetStringValue(base.json(), "server")),
_ownName(JsonHelper::checkAndGetStringValue(base.json(), "ownName")),
_queryId(JsonHelper::checkAndGetStringValue(base.json(), "queryId")),
_isResponsibleForInitCursor(JsonHelper::checkAndGetBooleanValue(
base.json(), "isResponsibleForInitCursor")) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for RemoteNode
////////////////////////////////////////////////////////////////////////////////
void RemoteNode::toJsonHelper(triagens::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("database", triagens::basics::Json(_vocbase->_name))(
"collection", triagens::basics::Json(_collection->getName()))(
"server", triagens::basics::Json(_server))(
"ownName", triagens::basics::Json(_ownName))(
"queryId", triagens::basics::Json(_queryId))(
"isResponsibleForInitCursor",
triagens::basics::Json(_isResponsibleForInitCursor));
// And add it:
nodes(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief estimateCost
////////////////////////////////////////////////////////////////////////////////
double RemoteNode::estimateCost(size_t& nrItems) const {
if (_dependencies.size() == 1) {
// This will usually be the case, however, in the context of the
// instantiation it is possible that there is no dependency...
double depCost = _dependencies[0]->estimateCost(nrItems);
return depCost + nrItems; // we need to process them all
}
// We really should not get here, but if so, do something bordering on
// sensible:
nrItems = 1;
return 1.0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct a scatter node from JSON
////////////////////////////////////////////////////////////////////////////////
ScatterNode::ScatterNode(ExecutionPlan* plan,
triagens::basics::Json const& base)
: ExecutionNode(plan, base),
_vocbase(plan->getAst()->query()->vocbase()),
_collection(plan->getAst()->query()->collections()->get(
JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for ScatterNode
////////////////////////////////////////////////////////////////////////////////
void ScatterNode::toJsonHelper(triagens::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("database", triagens::basics::Json(_vocbase->_name))(
"collection", triagens::basics::Json(_collection->getName()));
// And add it:
nodes(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief estimateCost
////////////////////////////////////////////////////////////////////////////////
double ScatterNode::estimateCost(size_t& nrItems) const {
double depCost = _dependencies[0]->getCost(nrItems);
auto shardIds = _collection->shardIds();
size_t nrShards = shardIds->size();
return depCost + nrItems * nrShards;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct a distribute node from JSON
////////////////////////////////////////////////////////////////////////////////
DistributeNode::DistributeNode(ExecutionPlan* plan,
triagens::basics::Json const& base)
: ExecutionNode(plan, base),
_vocbase(plan->getAst()->query()->vocbase()),
_collection(plan->getAst()->query()->collections()->get(
JsonHelper::checkAndGetStringValue(base.json(), "collection"))),
_varId(JsonHelper::checkAndGetNumericValue<VariableId>(base.json(),
"varId")),
_alternativeVarId(JsonHelper::checkAndGetNumericValue<VariableId>(
base.json(), "alternativeVarId")),
_createKeys(
JsonHelper::checkAndGetBooleanValue(base.json(), "createKeys")),
_allowKeyConversionToObject(JsonHelper::checkAndGetBooleanValue(
base.json(), "allowKeyConversionToObject")) {}
void DistributeNode::toJsonHelper(triagens::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("database", triagens::basics::Json(_vocbase->_name))(
"collection", triagens::basics::Json(_collection->getName()))(
"varId", triagens::basics::Json(static_cast<int>(_varId)))(
"alternativeVarId",
triagens::basics::Json(static_cast<int>(_alternativeVarId)))(
"createKeys", triagens::basics::Json(_createKeys))(
"allowKeyConversionToObject",
triagens::basics::Json(_allowKeyConversionToObject));
// And add it:
nodes(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief estimateCost
////////////////////////////////////////////////////////////////////////////////
double DistributeNode::estimateCost(size_t& nrItems) const {
double depCost = _dependencies[0]->getCost(nrItems);
return depCost + nrItems;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief construct a gather node from JSON
////////////////////////////////////////////////////////////////////////////////
GatherNode::GatherNode(ExecutionPlan* plan, triagens::basics::Json const& base,
SortElementVector const& elements)
: ExecutionNode(plan, base),
_elements(elements),
_vocbase(plan->getAst()->query()->vocbase()),
_collection(plan->getAst()->query()->collections()->get(
JsonHelper::checkAndGetStringValue(base.json(), "collection"))) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for GatherNode
////////////////////////////////////////////////////////////////////////////////
void GatherNode::toJsonHelper(triagens::basics::Json& nodes,
TRI_memory_zone_t* zone, bool verbose) const {
triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric(
nodes, zone, verbose)); // call base class method
if (json.isEmpty()) {
return;
}
json("database", triagens::basics::Json(_vocbase->_name))(
"collection", triagens::basics::Json(_collection->getName()));
triagens::basics::Json values(triagens::basics::Json::Array,
_elements.size());
for (auto it = _elements.begin(); it != _elements.end(); ++it) {
triagens::basics::Json element(triagens::basics::Json::Object);
element("inVariable", (*it).first->toJson())(
"ascending", triagens::basics::Json((*it).second));
values(element);
}
json("elements", values);
// And add it:
nodes(json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief estimateCost
////////////////////////////////////////////////////////////////////////////////
double GatherNode::estimateCost(size_t& nrItems) const {
double depCost = _dependencies[0]->getCost(nrItems);
return depCost + nrItems;
}