mirror of https://gitee.com/bigwinds/arangodb
fix profiling code (#6190)
This commit is contained in:
parent
102f15bece
commit
fc204a2b3e
|
@ -55,15 +55,6 @@ std::pair<ExecutionState, arangodb::Result> SingletonBlock::initializeCursor(
|
||||||
_inputRegisterValues.reset(items->slice(pos, _whitelist));
|
_inputRegisterValues.reset(items->slice(pos, _whitelist));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This could be omitted if ExecutionBlock::initializeCursor() was called
|
|
||||||
// here.
|
|
||||||
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
|
||||||
// Set block type in per-block statistics.
|
|
||||||
// Intentionally using operator[], which inserts a new element if it can't
|
|
||||||
// find one.
|
|
||||||
_engine->_stats.nodes[getPlanNode()->id()].type = this->getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
_done = false;
|
_done = false;
|
||||||
return {ExecutionState::DONE, TRI_ERROR_NO_ERROR};
|
return {ExecutionState::DONE, TRI_ERROR_NO_ERROR};
|
||||||
|
|
||||||
|
@ -458,6 +449,7 @@ std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> ReturnBlock::getSome(
|
||||||
|
|
||||||
auto res = ExecutionBlock::getSomeWithoutRegisterClearout(atMost);
|
auto res = ExecutionBlock::getSomeWithoutRegisterClearout(atMost);
|
||||||
if (res.first == ExecutionState::WAITING) {
|
if (res.first == ExecutionState::WAITING) {
|
||||||
|
traceGetSomeEnd(nullptr, ExecutionState::WAITING);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,6 @@ class SingletonBlock final : public ExecutionBlock {
|
||||||
/// above
|
/// above
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SINGLETON;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<ExecutionState, arangodb::Result> getOrSkipSome(size_t atMost, bool skipping,
|
std::pair<ExecutionState, arangodb::Result> getOrSkipSome(size_t atMost, bool skipping,
|
||||||
AqlItemBlock*& result, size_t& skipped) override;
|
AqlItemBlock*& result, size_t& skipped) override;
|
||||||
|
@ -67,10 +63,6 @@ class FilterBlock final : public ExecutionBlock {
|
||||||
std::pair<ExecutionState, arangodb::Result> initializeCursor(
|
std::pair<ExecutionState, arangodb::Result> initializeCursor(
|
||||||
AqlItemBlock* items, size_t pos) override final;
|
AqlItemBlock* items, size_t pos) override final;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::FILTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief internal function to actually decide if the document should be used
|
/// @brief internal function to actually decide if the document should be used
|
||||||
bool takeItem(AqlItemBlock* items, size_t index) const;
|
bool takeItem(AqlItemBlock* items, size_t index) const;
|
||||||
|
@ -119,10 +111,6 @@ class LimitBlock final : public ExecutionBlock {
|
||||||
AqlItemBlock*& result_,
|
AqlItemBlock*& result_,
|
||||||
size_t& skipped) override;
|
size_t& skipped) override;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::LIMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
ExecutionState getHasMoreState() override;
|
ExecutionState getHasMoreState() override;
|
||||||
|
@ -168,10 +156,6 @@ class ReturnBlock final : public ExecutionBlock {
|
||||||
/// returns the id of the register the final result can be found in
|
/// returns the id of the register the final result can be found in
|
||||||
RegisterId returnInheritedResults();
|
RegisterId returnInheritedResults();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::RETURN;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief if set to true, the return block will return the AqlItemBlocks it
|
/// @brief if set to true, the return block will return the AqlItemBlocks it
|
||||||
/// gets from above directly. if set to false, the return block will create a
|
/// gets from above directly. if set to false, the return block will create a
|
||||||
|
@ -189,10 +173,6 @@ class NoResultsBlock final : public ExecutionBlock {
|
||||||
/// above
|
/// above
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::NO_RESULTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<ExecutionState, arangodb::Result> getOrSkipSome(
|
std::pair<ExecutionState, arangodb::Result> getOrSkipSome(
|
||||||
size_t atMost, bool skipping, AqlItemBlock*& result,
|
size_t atMost, bool skipping, AqlItemBlock*& result,
|
||||||
|
|
|
@ -196,6 +196,7 @@ CalculationBlock::getSome(size_t atMost) {
|
||||||
|
|
||||||
auto res = ExecutionBlock::getSomeWithoutRegisterClearout(atMost);
|
auto res = ExecutionBlock::getSomeWithoutRegisterClearout(atMost);
|
||||||
if (res.first == ExecutionState::WAITING) {
|
if (res.first == ExecutionState::WAITING) {
|
||||||
|
traceGetSomeEnd(nullptr, ExecutionState::WAITING);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (res.second == nullptr) {
|
if (res.second == nullptr) {
|
||||||
|
|
|
@ -40,10 +40,6 @@ class CalculationBlock final : public ExecutionBlock {
|
||||||
|
|
||||||
~CalculationBlock();
|
~CalculationBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::CALCULATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief fill the target register in the item block with a reference to
|
/// @brief fill the target register in the item block with a reference to
|
||||||
/// another variable
|
/// another variable
|
||||||
|
|
|
@ -1126,7 +1126,6 @@ std::pair<ExecutionState, Result> RemoteBlock::shutdown(int errorCode) {
|
||||||
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> RemoteBlock::getSome(size_t atMost) {
|
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> RemoteBlock::getSome(size_t atMost) {
|
||||||
DEBUG_BEGIN_BLOCK();
|
DEBUG_BEGIN_BLOCK();
|
||||||
// For every call we simply forward via HTTP
|
// For every call we simply forward via HTTP
|
||||||
|
|
||||||
traceGetSomeBegin(atMost);
|
traceGetSomeBegin(atMost);
|
||||||
|
|
||||||
if (_lastError.fail()) {
|
if (_lastError.fail()) {
|
||||||
|
@ -1177,6 +1176,7 @@ std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> RemoteBlock::getSome(si
|
||||||
THROW_ARANGO_EXCEPTION(res);
|
THROW_ARANGO_EXCEPTION(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceGetSomeEnd(nullptr, ExecutionState::WAITING);
|
||||||
return {ExecutionState::WAITING, nullptr};
|
return {ExecutionState::WAITING, nullptr};
|
||||||
|
|
||||||
// cppcheck-suppress style
|
// cppcheck-suppress style
|
||||||
|
|
|
@ -121,10 +121,6 @@ class ScatterBlock final : public BlockWithClients {
|
||||||
std::vector<std::string> const& shardIds)
|
std::vector<std::string> const& shardIds)
|
||||||
: BlockWithClients(engine, ep, shardIds) {}
|
: BlockWithClients(engine, ep, shardIds) {}
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SCATTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
@ -156,10 +152,6 @@ class DistributeBlock final : public BlockWithClients {
|
||||||
std::vector<std::string> const& shardIds,
|
std::vector<std::string> const& shardIds,
|
||||||
Collection const* collection);
|
Collection const* collection);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::DISTRIBUTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
@ -249,10 +241,6 @@ class RemoteBlock final : public ExecutionBlock {
|
||||||
/// @brief handleAsyncResult
|
/// @brief handleAsyncResult
|
||||||
bool handleAsyncResult(ClusterCommResult* result) override;
|
bool handleAsyncResult(ClusterCommResult* result) override;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::REMOTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief internal method to send a request
|
/// @brief internal method to send a request
|
||||||
/// TODO:Deprecated!
|
/// TODO:Deprecated!
|
||||||
|
@ -321,10 +309,6 @@ class UnsortingGatherBlock final : public ExecutionBlock {
|
||||||
/// @brief skipSome
|
/// @brief skipSome
|
||||||
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::UNSORTING_GATHER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief _atDep: currently pulling blocks from _dependencies.at(_atDep),
|
/// @brief _atDep: currently pulling blocks from _dependencies.at(_atDep),
|
||||||
size_t _atDep{};
|
size_t _atDep{};
|
||||||
|
@ -374,10 +358,6 @@ class SortingGatherBlock final : public ExecutionBlock {
|
||||||
/// @brief skipSome
|
/// @brief skipSome
|
||||||
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SORTING_GATHER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void clearBuffers() noexcept;
|
void clearBuffers() noexcept;
|
||||||
|
@ -444,8 +424,6 @@ class SingleRemoteOperationBlock final : public ExecutionBlock {
|
||||||
/// @brief skipSome
|
/// @brief skipSome
|
||||||
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
std::pair<ExecutionState, size_t> skipSome(size_t atMost) override final;
|
||||||
|
|
||||||
Type getType() const override {return Type::SINGLEOPERATION; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// @brief _colectionName: the name of the sharded collection
|
/// @brief _colectionName: the name of the sharded collection
|
||||||
Collection const* _collection;
|
Collection const* _collection;
|
||||||
|
|
|
@ -95,10 +95,6 @@ class SortedCollectBlock final : public ExecutionBlock {
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SORTED_COLLECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::pair<ExecutionState, Result> getOrSkipSome(size_t atMost, bool skipping,
|
std::pair<ExecutionState, Result> getOrSkipSome(size_t atMost, bool skipping,
|
||||||
AqlItemBlock*& result,
|
AqlItemBlock*& result,
|
||||||
|
@ -146,10 +142,6 @@ class HashedCollectBlock final : public ExecutionBlock {
|
||||||
HashedCollectBlock(ExecutionEngine*, CollectNode const*);
|
HashedCollectBlock(ExecutionEngine*, CollectNode const*);
|
||||||
~HashedCollectBlock() final;
|
~HashedCollectBlock() final;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::HASHED_COLLECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items,
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items,
|
||||||
size_t pos) override;
|
size_t pos) override;
|
||||||
|
|
||||||
|
@ -188,10 +180,6 @@ class DistinctCollectBlock final : public ExecutionBlock {
|
||||||
DistinctCollectBlock(ExecutionEngine*, CollectNode const*);
|
DistinctCollectBlock(ExecutionEngine*, CollectNode const*);
|
||||||
~DistinctCollectBlock();
|
~DistinctCollectBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::DISTINCT_COLLECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
@ -214,10 +202,6 @@ class CountCollectBlock final : public ExecutionBlock {
|
||||||
public:
|
public:
|
||||||
CountCollectBlock(ExecutionEngine*, CollectNode const*);
|
CountCollectBlock(ExecutionEngine*, CollectNode const*);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::COUNT_COLLECT;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
std::pair<ExecutionState, Result> getOrSkipSome(size_t atMost, bool skipping,
|
std::pair<ExecutionState, Result> getOrSkipSome(size_t atMost, bool skipping,
|
||||||
|
|
|
@ -46,10 +46,6 @@ class EnumerateCollectionBlock final : public ExecutionBlock, public DocumentPro
|
||||||
EnumerateCollectionBlock(ExecutionEngine* engine,
|
EnumerateCollectionBlock(ExecutionEngine* engine,
|
||||||
EnumerateCollectionNode const* ep);
|
EnumerateCollectionNode const* ep);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::ENUMERATE_COLLECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,6 @@ class EnumerateListBlock final : public ExecutionBlock {
|
||||||
EnumerateListBlock(ExecutionEngine*, EnumerateListNode const*);
|
EnumerateListBlock(ExecutionEngine*, EnumerateListNode const*);
|
||||||
~EnumerateListBlock();
|
~EnumerateListBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::ENUMERATE_LIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we release our docs from this collection
|
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> getSome(
|
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> getSome(
|
||||||
|
|
|
@ -54,69 +54,6 @@ static std::string const& stateToString(ExecutionState state) {
|
||||||
return unknownString;
|
return unknownString;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExecutionBlockTypeHash {
|
|
||||||
size_t operator()(ExecutionBlock::Type value) const noexcept {
|
|
||||||
typedef std::underlying_type<decltype(value)>::type UnderlyingType;
|
|
||||||
return std::hash<UnderlyingType>()(UnderlyingType(value));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<std::string, arangodb::aql::ExecutionBlock::Type> const NamesToBlockTypeMap = {
|
|
||||||
{ "-undefined-", arangodb::aql::ExecutionBlock::Type::_UNDEFINED},
|
|
||||||
{ "CalculationBlock", arangodb::aql::ExecutionBlock::Type::CALCULATION},
|
|
||||||
{ "CountCollectBlock", arangodb::aql::ExecutionBlock::Type::COUNT_COLLECT},
|
|
||||||
{ "DistinctCollectBlock", arangodb::aql::ExecutionBlock::Type::DISTINCT_COLLECT},
|
|
||||||
{ "EnumerateCollectionBlock", arangodb::aql::ExecutionBlock::Type::ENUMERATE_COLLECTION},
|
|
||||||
{ "EnumerateListBlock", arangodb::aql::ExecutionBlock::Type::ENUMERATE_LIST},
|
|
||||||
{ "FilterBlock", arangodb::aql::ExecutionBlock::Type::FILTER},
|
|
||||||
{ "HashedCollectBlock", arangodb::aql::ExecutionBlock::Type::HASHED_COLLECT},
|
|
||||||
{ "IndexBlock", arangodb::aql::ExecutionBlock::Type::INDEX},
|
|
||||||
{ "LimitBlock", arangodb::aql::ExecutionBlock::Type::LIMIT},
|
|
||||||
{ "NoResultsBlock", arangodb::aql::ExecutionBlock::Type::NO_RESULTS},
|
|
||||||
{ "RemoteBlock", arangodb::aql::ExecutionBlock::Type::REMOTE},
|
|
||||||
{ "ReturnBlock", arangodb::aql::ExecutionBlock::Type::RETURN},
|
|
||||||
{ "ShortestPathBlock", arangodb::aql::ExecutionBlock::Type::SHORTEST_PATH},
|
|
||||||
{ "SingletonBlock", arangodb::aql::ExecutionBlock::Type::SINGLETON},
|
|
||||||
{ "SingleOperationBlock", arangodb::aql::ExecutionBlock::Type::SINGLEOPERATION},
|
|
||||||
{ "SortBlock", arangodb::aql::ExecutionBlock::Type::SORT},
|
|
||||||
{ "SortedCollectBlock", arangodb::aql::ExecutionBlock::Type::SORTED_COLLECT},
|
|
||||||
{ "SortingGatherBlock", arangodb::aql::ExecutionBlock::Type::SORTING_GATHER},
|
|
||||||
{ "SubqueryBlock", arangodb::aql::ExecutionBlock::Type::SUBQUERY},
|
|
||||||
{ "TraversalBlock", arangodb::aql::ExecutionBlock::Type::TRAVERSAL},
|
|
||||||
{ "UnsortingGatherBlock", arangodb::aql::ExecutionBlock::Type::UNSORTING_GATHER},
|
|
||||||
{ "RemoveBlock", arangodb::aql::ExecutionBlock::Type::REMOVE},
|
|
||||||
{ "InsertBlock", arangodb::aql::ExecutionBlock::Type::INSERT},
|
|
||||||
{ "UpdateBlock", arangodb::aql::ExecutionBlock::Type::UPDATE},
|
|
||||||
{ "ReplaceBlock", arangodb::aql::ExecutionBlock::Type::REPLACE},
|
|
||||||
{ "UpsertBlock", arangodb::aql::ExecutionBlock::Type::UPSERT},
|
|
||||||
{ "ScatterBlock", arangodb::aql::ExecutionBlock::Type::SCATTER},
|
|
||||||
{ "DistributeBlock", arangodb::aql::ExecutionBlock::Type::DISTRIBUTE},
|
|
||||||
#ifdef USE_IRESEARCH
|
|
||||||
{ "IResearchViewBlock", arangodb::aql::ExecutionBlock::Type::IRESEARCH_VIEW},
|
|
||||||
{ "IResearchViewOrderedBlock", arangodb::aql::ExecutionBlock::Type::IRESEARCH_VIEW_ORDERED},
|
|
||||||
{ "IResearchViewUnorderedBlock", arangodb::aql::ExecutionBlock::Type::IRESEARCH_VIEW_UNORDERED}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<
|
|
||||||
arangodb::aql::ExecutionBlock::Type,
|
|
||||||
std::reference_wrapper<const std::string>,
|
|
||||||
ExecutionBlockTypeHash
|
|
||||||
> blockTypeToNamesMap;
|
|
||||||
|
|
||||||
struct BlockTypeToNameMapInitializer {
|
|
||||||
BlockTypeToNameMapInitializer() {
|
|
||||||
blockTypeToNamesMap.reserve(NamesToBlockTypeMap.size());
|
|
||||||
std::for_each(NamesToBlockTypeMap.begin(),
|
|
||||||
NamesToBlockTypeMap.end(),
|
|
||||||
[](std::pair<std::string const&, arangodb::aql::ExecutionBlock::Type> const& p) {
|
|
||||||
blockTypeToNamesMap.emplace(p.second, p.first);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} initializeBlockTypeToNameMap;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ExecutionBlock::ExecutionBlock(ExecutionEngine* engine, ExecutionNode const* ep)
|
ExecutionBlock::ExecutionBlock(ExecutionEngine* engine, ExecutionNode const* ep)
|
||||||
|
@ -206,13 +143,6 @@ std::pair<ExecutionState, arangodb::Result> ExecutionBlock::initializeCursor(
|
||||||
_skipped = 0;
|
_skipped = 0;
|
||||||
_collector.clear();
|
_collector.clear();
|
||||||
|
|
||||||
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
|
||||||
// Set block type in per-block statistics.
|
|
||||||
// Intentionally using operator[], which inserts a new element if it can't
|
|
||||||
// find one.
|
|
||||||
_engine->_stats.nodes[getPlanNode()->id()].type = this->getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
TRI_ASSERT(getHasMoreState() == ExecutionState::HASMORE);
|
TRI_ASSERT(getHasMoreState() == ExecutionState::HASMORE);
|
||||||
TRI_ASSERT(_dependencyPos == _dependencies.end());
|
TRI_ASSERT(_dependencyPos == _dependencies.end());
|
||||||
return {ExecutionState::DONE, TRI_ERROR_NO_ERROR};
|
return {ExecutionState::DONE, TRI_ERROR_NO_ERROR};
|
||||||
|
@ -255,7 +185,9 @@ std::pair<ExecutionState, Result> ExecutionBlock::shutdown(int errorCode) {
|
||||||
// Trace the start of a getSome call
|
// Trace the start of a getSome call
|
||||||
void ExecutionBlock::traceGetSomeBegin(size_t atMost) {
|
void ExecutionBlock::traceGetSomeBegin(size_t atMost) {
|
||||||
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
||||||
_getSomeBegin = TRI_microtime();
|
if (_getSomeBegin == 0) {
|
||||||
|
_getSomeBegin = TRI_microtime();
|
||||||
|
}
|
||||||
if (_profile >= PROFILE_LEVEL_TRACE_1) {
|
if (_profile >= PROFILE_LEVEL_TRACE_1) {
|
||||||
auto node = getPlanNode();
|
auto node = getPlanNode();
|
||||||
LOG_TOPIC(INFO, Logger::QUERIES)
|
LOG_TOPIC(INFO, Logger::QUERIES)
|
||||||
|
@ -267,15 +199,18 @@ void ExecutionBlock::traceGetSomeBegin(size_t atMost) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace the end of a getSome call, potentially with result
|
// Trace the end of a getSome call, potentially with result
|
||||||
void ExecutionBlock::traceGetSomeEnd(AqlItemBlock const* result, ExecutionState state) const {
|
void ExecutionBlock::traceGetSomeEnd(AqlItemBlock const* result, ExecutionState state) {
|
||||||
TRI_ASSERT(result != nullptr || state != ExecutionState::HASMORE);
|
TRI_ASSERT(result != nullptr || state != ExecutionState::HASMORE);
|
||||||
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
if (_profile >= PROFILE_LEVEL_BLOCKS) {
|
||||||
ExecutionNode const* en = getPlanNode();
|
ExecutionNode const* en = getPlanNode();
|
||||||
ExecutionStats::Node stats;
|
ExecutionStats::Node stats;
|
||||||
stats.calls = 1;
|
stats.calls = 1;
|
||||||
stats.items = result != nullptr ? result->size() : 0;
|
stats.items = result != nullptr ? result->size() : 0;
|
||||||
stats.runtime = TRI_microtime() - _getSomeBegin;
|
if (state != ExecutionState::WAITING) {
|
||||||
stats.type = getType();
|
stats.runtime = TRI_microtime() - _getSomeBegin;
|
||||||
|
_getSomeBegin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
auto it = _engine->_stats.nodes.find(en->id());
|
auto it = _engine->_stats.nodes.find(en->id());
|
||||||
if (it != _engine->_stats.nodes.end()) {
|
if (it != _engine->_stats.nodes.end()) {
|
||||||
it->second += stats;
|
it->second += stats;
|
||||||
|
@ -695,24 +630,3 @@ RegisterId ExecutionBlock::getNrOutputRegisters() const {
|
||||||
|
|
||||||
return outputNrRegs;
|
return outputNrRegs;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExecutionBlock::typeToString(ExecutionBlock::Type type) {
|
|
||||||
auto got = ::blockTypeToNamesMap.find(type);
|
|
||||||
if (got == ::blockTypeToNamesMap.end()) {
|
|
||||||
// to please compiler in non-maintainer mode
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
|
||||||
std::string("when converting ExecutionBlock::Type to string: got invalid type"));
|
|
||||||
}
|
|
||||||
return got->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExecutionBlock::Type ExecutionBlock::typeFromString(std::string const& type) {
|
|
||||||
auto got = ::NamesToBlockTypeMap.find(type);
|
|
||||||
if (got == ::NamesToBlockTypeMap.end()) {
|
|
||||||
// to please compiler in non-maintainer mode
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
|
||||||
std::string("when converting string to ExecutionBlock::Type: got invalid string '" + type + "'"));
|
|
||||||
return arangodb::aql::ExecutionBlock::Type::_UNDEFINED;
|
|
||||||
}
|
|
||||||
return got->second;
|
|
||||||
}
|
|
||||||
|
|
|
@ -69,7 +69,6 @@ class Methods;
|
||||||
namespace aql {
|
namespace aql {
|
||||||
class AqlItemBlock;
|
class AqlItemBlock;
|
||||||
class ExecutionEngine;
|
class ExecutionEngine;
|
||||||
struct QueryProfile;
|
|
||||||
|
|
||||||
class ExecutionBlock {
|
class ExecutionBlock {
|
||||||
public:
|
public:
|
||||||
|
@ -80,54 +79,6 @@ class ExecutionBlock {
|
||||||
ExecutionBlock(ExecutionBlock const&) = delete;
|
ExecutionBlock(ExecutionBlock const&) = delete;
|
||||||
ExecutionBlock operator=(ExecutionBlock const&) = delete;
|
ExecutionBlock operator=(ExecutionBlock const&) = delete;
|
||||||
|
|
||||||
/// @brief type of the block. only the blocks actually instantiated are
|
|
||||||
// needed, so e.g. ModificationBlock or ExecutionBlock are omitted.
|
|
||||||
enum class Type {
|
|
||||||
_UNDEFINED,
|
|
||||||
CALCULATION,
|
|
||||||
COUNT_COLLECT,
|
|
||||||
DISTINCT_COLLECT,
|
|
||||||
ENUMERATE_COLLECTION,
|
|
||||||
ENUMERATE_LIST,
|
|
||||||
FILTER,
|
|
||||||
HASHED_COLLECT,
|
|
||||||
INDEX,
|
|
||||||
LIMIT,
|
|
||||||
NO_RESULTS,
|
|
||||||
REMOTE,
|
|
||||||
RETURN,
|
|
||||||
SHORTEST_PATH,
|
|
||||||
SINGLETON,
|
|
||||||
SINGLEOPERATION,
|
|
||||||
SORT,
|
|
||||||
SORTED_COLLECT,
|
|
||||||
SORTING_GATHER,
|
|
||||||
SUBQUERY,
|
|
||||||
TRAVERSAL,
|
|
||||||
UNSORTING_GATHER,
|
|
||||||
REMOVE,
|
|
||||||
INSERT,
|
|
||||||
UPDATE,
|
|
||||||
REPLACE,
|
|
||||||
UPSERT,
|
|
||||||
SCATTER,
|
|
||||||
DISTRIBUTE,
|
|
||||||
#ifdef USE_IRESEARCH
|
|
||||||
IRESEARCH_VIEW,
|
|
||||||
IRESEARCH_VIEW_ORDERED,
|
|
||||||
IRESEARCH_VIEW_UNORDERED,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
// omitted in this list are (because):
|
|
||||||
// WaitingExecutionBlockMock (mock)
|
|
||||||
// ExecutionBlockMock (mock)
|
|
||||||
// ModificationBlock (insert, update, etc.)
|
|
||||||
// BlockWithClients (scatter, distribute)
|
|
||||||
// IResearchViewBlockBase (IResearchView*)
|
|
||||||
|
|
||||||
static std::string typeToString(Type type);
|
|
||||||
static Type typeFromString(std::string const& type);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// @brief batch size value
|
/// @brief batch size value
|
||||||
static constexpr inline size_t DefaultBatchSize() { return 1000; }
|
static constexpr inline size_t DefaultBatchSize() { return 1000; }
|
||||||
|
@ -186,7 +137,7 @@ class ExecutionBlock {
|
||||||
size_t atMost);
|
size_t atMost);
|
||||||
|
|
||||||
void traceGetSomeBegin(size_t atMost);
|
void traceGetSomeBegin(size_t atMost);
|
||||||
void traceGetSomeEnd(AqlItemBlock const*, ExecutionState state) const;
|
void traceGetSomeEnd(AqlItemBlock const*, ExecutionState state);
|
||||||
|
|
||||||
/// @brief skipSome, skips some more items, semantic is as follows: not
|
/// @brief skipSome, skips some more items, semantic is as follows: not
|
||||||
/// more than atMost items may be skipped. The method tries to
|
/// more than atMost items may be skipped. The method tries to
|
||||||
|
@ -213,8 +164,6 @@ class ExecutionBlock {
|
||||||
|
|
||||||
RegisterId getNrOutputRegisters() const;
|
RegisterId getNrOutputRegisters() const;
|
||||||
|
|
||||||
virtual Type getType() const {return Type::_UNDEFINED;}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief request an AqlItemBlock from the memory manager
|
/// @brief request an AqlItemBlock from the memory manager
|
||||||
AqlItemBlock* requestBlock(size_t nrItems, RegisterId nrRegs);
|
AqlItemBlock* requestBlock(size_t nrItems, RegisterId nrRegs);
|
||||||
|
|
|
@ -51,16 +51,11 @@ void ExecutionStats::toVelocyPack(VPackBuilder& builder, bool reportFullCount) c
|
||||||
if (!nodes.empty()) {
|
if (!nodes.empty()) {
|
||||||
builder.add("nodes", VPackValue(VPackValueType::Array));
|
builder.add("nodes", VPackValue(VPackValueType::Array));
|
||||||
for (std::pair<size_t const, ExecutionStats::Node> const& pair : nodes) {
|
for (std::pair<size_t const, ExecutionStats::Node> const& pair : nodes) {
|
||||||
// the block type should always be set here
|
|
||||||
TRI_ASSERT(pair.second.type != ExecutionBlock::Type::_UNDEFINED);
|
|
||||||
|
|
||||||
builder.openObject();
|
builder.openObject();
|
||||||
builder.add("id", VPackValue(pair.first));
|
builder.add("id", VPackValue(pair.first));
|
||||||
builder.add("calls", VPackValue(pair.second.calls));
|
builder.add("calls", VPackValue(pair.second.calls));
|
||||||
builder.add("items", VPackValue(pair.second.items));
|
builder.add("items", VPackValue(pair.second.items));
|
||||||
builder.add("runtime", VPackValue(pair.second.runtime));
|
builder.add("runtime", VPackValue(pair.second.runtime));
|
||||||
builder.add("blockType",
|
|
||||||
VPackValue(ExecutionBlock::typeToString(pair.second.type)));
|
|
||||||
builder.close();
|
builder.close();
|
||||||
}
|
}
|
||||||
builder.close();
|
builder.close();
|
||||||
|
@ -140,8 +135,6 @@ ExecutionStats::ExecutionStats(VPackSlice const& slice)
|
||||||
node.calls = val.get("calls").getNumber<size_t>();
|
node.calls = val.get("calls").getNumber<size_t>();
|
||||||
node.items = val.get("items").getNumber<size_t>();
|
node.items = val.get("items").getNumber<size_t>();
|
||||||
node.runtime = val.get("runtime").getNumber<double>();
|
node.runtime = val.get("runtime").getNumber<double>();
|
||||||
node.type =
|
|
||||||
ExecutionBlock::typeFromString(val.get("blockType").copyString());
|
|
||||||
nodes.emplace(nid, node);
|
nodes.emplace(nid, node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,7 @@ struct ExecutionStats {
|
||||||
size_t calls = 0;
|
size_t calls = 0;
|
||||||
size_t items = 0;
|
size_t items = 0;
|
||||||
double runtime = 0;
|
double runtime = 0;
|
||||||
ExecutionBlock::Type type = ExecutionBlock::Type::_UNDEFINED;
|
|
||||||
ExecutionStats::Node& operator+=(ExecutionStats::Node const& other) {
|
ExecutionStats::Node& operator+=(ExecutionStats::Node const& other) {
|
||||||
// both operands should be the same block type
|
|
||||||
TRI_ASSERT(type == other.type);
|
|
||||||
calls += other.calls;
|
calls += other.calls;
|
||||||
items += other.items;
|
items += other.items;
|
||||||
runtime += other.runtime;
|
runtime += other.runtime;
|
||||||
|
|
|
@ -61,10 +61,6 @@ class IndexBlock final : public ExecutionBlock, public DocumentProducingBlock {
|
||||||
|
|
||||||
~IndexBlock();
|
~IndexBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::INDEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor, here we release our docs from this collection
|
/// @brief initializeCursor, here we release our docs from this collection
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
|
|
@ -109,10 +109,6 @@ class RemoveBlock : public ModificationBlock {
|
||||||
RemoveBlock(ExecutionEngine*, RemoveNode const*);
|
RemoveBlock(ExecutionEngine*, RemoveNode const*);
|
||||||
~RemoveBlock() = default;
|
~RemoveBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief the actual work horse for removing data
|
/// @brief the actual work horse for removing data
|
||||||
std::unique_ptr<AqlItemBlock> work() override final;
|
std::unique_ptr<AqlItemBlock> work() override final;
|
||||||
|
@ -123,10 +119,6 @@ class InsertBlock : public ModificationBlock {
|
||||||
InsertBlock(ExecutionEngine*, InsertNode const*);
|
InsertBlock(ExecutionEngine*, InsertNode const*);
|
||||||
~InsertBlock() = default;
|
~InsertBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::INSERT;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief the actual work horse for inserting data
|
/// @brief the actual work horse for inserting data
|
||||||
std::unique_ptr<AqlItemBlock> work() override final;
|
std::unique_ptr<AqlItemBlock> work() override final;
|
||||||
|
@ -137,10 +129,6 @@ class UpdateBlock : public ModificationBlock {
|
||||||
UpdateBlock(ExecutionEngine*, UpdateNode const*);
|
UpdateBlock(ExecutionEngine*, UpdateNode const*);
|
||||||
~UpdateBlock() = default;
|
~UpdateBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::UPDATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief the actual work horse for updating data
|
/// @brief the actual work horse for updating data
|
||||||
std::unique_ptr<AqlItemBlock> work() override final;
|
std::unique_ptr<AqlItemBlock> work() override final;
|
||||||
|
@ -151,10 +139,6 @@ class ReplaceBlock : public ModificationBlock {
|
||||||
ReplaceBlock(ExecutionEngine*, ReplaceNode const*);
|
ReplaceBlock(ExecutionEngine*, ReplaceNode const*);
|
||||||
~ReplaceBlock() = default;
|
~ReplaceBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::REPLACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief the actual work horse for replacing data
|
/// @brief the actual work horse for replacing data
|
||||||
std::unique_ptr<AqlItemBlock> work() override final;
|
std::unique_ptr<AqlItemBlock> work() override final;
|
||||||
|
@ -165,10 +149,6 @@ class UpsertBlock : public ModificationBlock {
|
||||||
UpsertBlock(ExecutionEngine*, UpsertNode const*);
|
UpsertBlock(ExecutionEngine*, UpsertNode const*);
|
||||||
~UpsertBlock() = default;
|
~UpsertBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::UPSERT;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @brief the actual work horse for updating data
|
/// @brief the actual work horse for updating data
|
||||||
std::unique_ptr<AqlItemBlock> work() override final;
|
std::unique_ptr<AqlItemBlock> work() override final;
|
||||||
|
|
|
@ -45,10 +45,6 @@ class ShortestPathBlock final : public ExecutionBlock {
|
||||||
public:
|
public:
|
||||||
ShortestPathBlock(ExecutionEngine* engine, ShortestPathNode const* ep);
|
ShortestPathBlock(ExecutionEngine* engine, ShortestPathNode const* ep);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SHORTEST_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,6 @@ class SortBlock final : public ExecutionBlock {
|
||||||
|
|
||||||
~SortBlock();
|
~SortBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor, could be called multiple times
|
/// @brief initializeCursor, could be called multiple times
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,6 @@ class SubqueryBlock final : public ExecutionBlock {
|
||||||
SubqueryBlock(ExecutionEngine*, SubqueryNode const*, ExecutionBlock*);
|
SubqueryBlock(ExecutionEngine*, SubqueryNode const*, ExecutionBlock*);
|
||||||
~SubqueryBlock() = default;
|
~SubqueryBlock() = default;
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::SUBQUERY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief getSome
|
/// @brief getSome
|
||||||
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> getSome(
|
std::pair<ExecutionState, std::unique_ptr<AqlItemBlock>> getSome(
|
||||||
size_t atMost) override final;
|
size_t atMost) override final;
|
||||||
|
|
|
@ -43,10 +43,6 @@ class TraversalBlock final : public ExecutionBlock {
|
||||||
|
|
||||||
~TraversalBlock();
|
~TraversalBlock();
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::TRAVERSAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief initializeCursor
|
/// @brief initializeCursor
|
||||||
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
std::pair<ExecutionState, Result> initializeCursor(AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
||||||
|
|
|
@ -263,11 +263,13 @@ IResearchViewBlockBase::getSome(size_t atMost) {
|
||||||
size_t const toFetch = (std::min)(DefaultBatchSize(), atMost);
|
size_t const toFetch = (std::min)(DefaultBatchSize(), atMost);
|
||||||
auto upstreamRes = ExecutionBlock::getBlock(toFetch);
|
auto upstreamRes = ExecutionBlock::getBlock(toFetch);
|
||||||
if (upstreamRes.first == ExecutionState::WAITING) {
|
if (upstreamRes.first == ExecutionState::WAITING) {
|
||||||
|
traceGetSomeEnd(nullptr, ExecutionState::WAITING);
|
||||||
return {upstreamRes.first, nullptr};
|
return {upstreamRes.first, nullptr};
|
||||||
}
|
}
|
||||||
_upstreamState = upstreamRes.first;
|
_upstreamState = upstreamRes.first;
|
||||||
if (!upstreamRes.second) {
|
if (!upstreamRes.second) {
|
||||||
_done = true;
|
_done = true;
|
||||||
|
traceGetSomeEnd(nullptr, ExecutionState::DONE);
|
||||||
return {ExecutionState::DONE, nullptr};
|
return {ExecutionState::DONE, nullptr};
|
||||||
}
|
}
|
||||||
_pos = 0; // this is in the first block
|
_pos = 0; // this is in the first block
|
||||||
|
|
|
@ -139,10 +139,6 @@ class IResearchViewUnorderedBlock : public IResearchViewBlockBase {
|
||||||
IResearchViewNode const& node
|
IResearchViewNode const& node
|
||||||
);
|
);
|
||||||
|
|
||||||
Type getType() const override {
|
|
||||||
return Type::IRESEARCH_VIEW_UNORDERED;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void reset() override final {
|
virtual void reset() override final {
|
||||||
IResearchViewBlockBase::reset();
|
IResearchViewBlockBase::reset();
|
||||||
|
@ -176,10 +172,6 @@ class IResearchViewBlock final : public IResearchViewUnorderedBlock {
|
||||||
IResearchViewNode const& node
|
IResearchViewNode const& node
|
||||||
);
|
);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::IRESEARCH_VIEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool next(
|
virtual bool next(
|
||||||
aql::AqlItemBlock& res,
|
aql::AqlItemBlock& res,
|
||||||
|
@ -208,10 +200,6 @@ class IResearchViewOrderedBlock final : public IResearchViewBlockBase {
|
||||||
IResearchViewNode const& node
|
IResearchViewNode const& node
|
||||||
);
|
);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::IRESEARCH_VIEW_ORDERED;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void reset() override {
|
virtual void reset() override {
|
||||||
IResearchViewBlockBase::reset();
|
IResearchViewBlockBase::reset();
|
||||||
|
|
|
@ -684,11 +684,11 @@ function processQuery (query, explain) {
|
||||||
maxCallsLen = String(n.calls).length;
|
maxCallsLen = String(n.calls).length;
|
||||||
}
|
}
|
||||||
if (String(n.items).length > maxItemsLen) {
|
if (String(n.items).length > maxItemsLen) {
|
||||||
maxCallsLen = String(n.items).length;
|
maxItemsLen = String(n.items).length;
|
||||||
}
|
}
|
||||||
let l = String(nodes[n.id].runtime.toFixed(3)).length;
|
let l = String(nodes[n.id].runtime.toFixed(3)).length;
|
||||||
if (l > maxRuntimeLen) {
|
if (l > maxRuntimeLen) {
|
||||||
maxCallsLen = l;
|
maxRuntimeLen = l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1424,15 +1424,13 @@ function processQuery (query, explain) {
|
||||||
return keyword('DISTRIBUTE');
|
return keyword('DISTRIBUTE');
|
||||||
case 'ScatterNode':
|
case 'ScatterNode':
|
||||||
return keyword('SCATTER');
|
return keyword('SCATTER');
|
||||||
case 'ScatterViewNode':
|
|
||||||
return keyword('SCATTER VIEW');
|
|
||||||
case 'GatherNode':
|
case 'GatherNode':
|
||||||
return keyword('GATHER') + ' ' + node.elements.map(function (node) {
|
return keyword('GATHER') + ' ' + node.elements.map(function (node) {
|
||||||
if (node.path && node.path.length) {
|
if (node.path && node.path.length) {
|
||||||
return variableName(node.inVariable) + node.path.map(function(n) { return '.' + attribute(n); }) + ' ' + keyword(node.ascending ? 'ASC' : 'DESC');
|
return variableName(node.inVariable) + node.path.map(function(n) { return '.' + attribute(n); }) + ' ' + keyword(node.ascending ? 'ASC' : 'DESC');
|
||||||
}
|
}
|
||||||
return variableName(node.inVariable) + ' ' + keyword(node.ascending ? 'ASC' : 'DESC');
|
return variableName(node.inVariable) + ' ' + keyword(node.ascending ? 'ASC' : 'DESC');
|
||||||
}).join(', ');
|
}).join(', ') + ' ' + annotation('/* sort mode: ' + node.sortmode + ' */');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'unhandled node type (' + node.type + ')';
|
return 'unhandled node type (' + node.type + ')';
|
||||||
|
|
|
@ -77,36 +77,36 @@ const nodeTypesList = [
|
||||||
SubqueryNode, TraversalNode, UpdateNode, UpsertNode
|
SubqueryNode, TraversalNode, UpdateNode, UpsertNode
|
||||||
];
|
];
|
||||||
|
|
||||||
const CalculationBlock = 'CalculationBlock';
|
const CalculationBlock = 'CalculationNode';
|
||||||
const CountCollectBlock = 'CountCollectBlock';
|
const CountCollectBlock = 'CountCollectNode';
|
||||||
const DistinctCollectBlock = 'DistinctCollectBlock';
|
const DistinctCollectBlock = 'DistinctCollectNode';
|
||||||
const EnumerateCollectionBlock = 'EnumerateCollectionBlock';
|
const EnumerateCollectionBlock = 'EnumerateCollectionNode';
|
||||||
const EnumerateListBlock = 'EnumerateListBlock';
|
const EnumerateListBlock = 'EnumerateListNode';
|
||||||
const FilterBlock = 'FilterBlock';
|
const FilterBlock = 'FilterNode';
|
||||||
const HashedCollectBlock = 'HashedCollectBlock';
|
const HashedCollectBlock = 'HashedCollectNode';
|
||||||
const IndexBlock = 'IndexBlock';
|
const IndexBlock = 'IndexNode';
|
||||||
const LimitBlock = 'LimitBlock';
|
const LimitBlock = 'LimitNode';
|
||||||
const NoResultsBlock = 'NoResultsBlock';
|
const NoResultsBlock = 'NoResultsNode';
|
||||||
const RemoteBlock = 'RemoteBlock';
|
const RemoteBlock = 'RemoteNode';
|
||||||
const ReturnBlock = 'ReturnBlock';
|
const ReturnBlock = 'ReturnNode';
|
||||||
const ShortestPathBlock = 'ShortestPathBlock';
|
const ShortestPathBlock = 'ShortestPathNode';
|
||||||
const SingletonBlock = 'SingletonBlock';
|
const SingletonBlock = 'SingletonNode';
|
||||||
const SortBlock = 'SortBlock';
|
const SortBlock = 'SortNode';
|
||||||
const SortedCollectBlock = 'SortedCollectBlock';
|
const SortedCollectBlock = 'SortedCollectNode';
|
||||||
const SortingGatherBlock = 'SortingGatherBlock';
|
const SortingGatherBlock = 'SortingGatherNode';
|
||||||
const SubqueryBlock = 'SubqueryBlock';
|
const SubqueryBlock = 'SubqueryNode';
|
||||||
const TraversalBlock = 'TraversalBlock';
|
const TraversalBlock = 'TraversalNode';
|
||||||
const UnsortingGatherBlock = 'UnsortingGatherBlock';
|
const UnsortingGatherBlock = 'UnsortingGatherNode';
|
||||||
const RemoveBlock = 'RemoveBlock';
|
const RemoveBlock = 'RemoveNode';
|
||||||
const InsertBlock = 'InsertBlock';
|
const InsertBlock = 'InsertNode';
|
||||||
const UpdateBlock = 'UpdateBlock';
|
const UpdateBlock = 'UpdateNode';
|
||||||
const ReplaceBlock = 'ReplaceBlock';
|
const ReplaceBlock = 'ReplaceNode';
|
||||||
const UpsertBlock = 'UpsertBlock';
|
const UpsertBlock = 'UpsertNode';
|
||||||
const ScatterBlock = 'ScatterBlock';
|
const ScatterBlock = 'ScatterNode';
|
||||||
const DistributeBlock = 'DistributeBlock';
|
const DistributeBlock = 'DistributeNode';
|
||||||
const IResearchViewUnorderedBlock = 'IResearchViewUnorderedBlock';
|
const IResearchViewUnorderedBlock = 'IResearchUnorderedViewNode';
|
||||||
const IResearchViewBlock = 'IResearchViewBlock';
|
const IResearchViewBlock = 'IResearchViewNode';
|
||||||
const IResearchViewOrderedBlock = 'IResearchViewOrderedBlock';
|
const IResearchViewOrderedBlock = 'IResearchOrderedViewNode';
|
||||||
|
|
||||||
const blockTypesList = [
|
const blockTypesList = [
|
||||||
CalculationBlock, CountCollectBlock, DistinctCollectBlock,
|
CalculationBlock, CountCollectBlock, DistinctCollectBlock,
|
||||||
|
@ -119,6 +119,33 @@ const blockTypesList = [
|
||||||
IResearchViewBlock, IResearchViewOrderedBlock
|
IResearchViewBlock, IResearchViewOrderedBlock
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let translateType = function(nodes, node) {
|
||||||
|
let types = {};
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
let type = node.type;
|
||||||
|
if (type === 'CollectNode') {
|
||||||
|
if (node.collectOptions.method === 'sorted') {
|
||||||
|
type = 'SortedCollectNode';
|
||||||
|
} else if (node.collectOptions.method === 'hash') {
|
||||||
|
type = 'HashedCollectNode';
|
||||||
|
} else if (node.collectOptions.method === 'distinct') {
|
||||||
|
type = 'DistinctCollectNode';
|
||||||
|
} else if (node.collectOptions.method === 'count') {
|
||||||
|
type = 'CountCollectNode';
|
||||||
|
}
|
||||||
|
} else if (node.type === 'GatherNode') {
|
||||||
|
if (node.sortmode === 'minelement' || node.sortmode === 'heap') {
|
||||||
|
type = 'SortingGatherNode';
|
||||||
|
} else {
|
||||||
|
type = 'UnsortingGatherNode';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types[node.id] = type;
|
||||||
|
});
|
||||||
|
|
||||||
|
return types[node.id];
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief check that numbers in actual are in the range specified by
|
/// @brief check that numbers in actual are in the range specified by
|
||||||
/// expected. Each element in expected may either be
|
/// expected. Each element in expected may either be
|
||||||
/// - a number, for an exact match;
|
/// - a number, for an exact match;
|
||||||
|
@ -165,7 +192,11 @@ function zipPlanNodesIntoStatsNodes (profile) {
|
||||||
// Note: We need to take the order plan.nodes here, not stats.nodes,
|
// Note: We need to take the order plan.nodes here, not stats.nodes,
|
||||||
// as stats.nodes is sorted by id.
|
// as stats.nodes is sorted by id.
|
||||||
return profile.plan.nodes.map(node => (
|
return profile.plan.nodes.map(node => (
|
||||||
{ id: node.id, fromStats: statsNodesById[node.id], fromPlan: node }
|
{
|
||||||
|
id: node.id,
|
||||||
|
type: translateType(profile.plan.nodes, node),
|
||||||
|
fromStats: statsNodesById[node.id], fromPlan: node
|
||||||
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +205,7 @@ function getCompactStatsNodes (profile) {
|
||||||
// of the plan, not from the stats (which is sorted by id).
|
// of the plan, not from the stats (which is sorted by id).
|
||||||
return zipPlanNodesIntoStatsNodes(profile).map(
|
return zipPlanNodesIntoStatsNodes(profile).map(
|
||||||
node => ({
|
node => ({
|
||||||
// type: node.fromPlan.type,
|
type: translateType(profile.plan.nodes, node),
|
||||||
type: node.fromStats.blockType,
|
|
||||||
calls: node.fromStats.calls,
|
calls: node.fromStats.calls,
|
||||||
items: node.fromStats.items,
|
items: node.fromStats.items,
|
||||||
})
|
})
|
||||||
|
@ -195,7 +225,7 @@ function getStatsNodesWithId (profile) {
|
||||||
return profile.stats.nodes.map(
|
return profile.stats.nodes.map(
|
||||||
node => ({
|
node => ({
|
||||||
id: node.id,
|
id: node.id,
|
||||||
blockType: node.blockType,
|
type: node.type,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -422,7 +452,6 @@ function assertStatsNodesMatchPlanNodes (profile) {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function assertNodesItemsAndCalls (expected, actual, details = {}) {
|
function assertNodesItemsAndCalls (expected, actual, details = {}) {
|
||||||
|
|
||||||
// assert node types first
|
// assert node types first
|
||||||
assert.assertEqual(
|
assert.assertEqual(
|
||||||
expected.map(node => node.type),
|
expected.map(node => node.type),
|
||||||
|
@ -528,8 +557,6 @@ function createBinaryTree (vertexCol, edgeCol, numVertices) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
exports.colName = colName;
|
exports.colName = colName;
|
||||||
exports.edgeColName = edgeColName;
|
exports.edgeColName = edgeColName;
|
||||||
exports.defaultBatchSize = defaultBatchSize;
|
exports.defaultBatchSize = defaultBatchSize;
|
||||||
|
|
|
@ -486,8 +486,7 @@ function ahuacatlProfilerTestSuite () {
|
||||||
node => (
|
node => (
|
||||||
node.fromStats ?
|
node.fromStats ?
|
||||||
{
|
{
|
||||||
// type: node.fromPlan.type,
|
type: node.type,
|
||||||
type: node.fromStats.blockType,
|
|
||||||
calls: node.fromStats.calls,
|
calls: node.fromStats.calls,
|
||||||
items: node.fromStats.items,
|
items: node.fromStats.items,
|
||||||
} : {})
|
} : {})
|
||||||
|
|
|
@ -86,10 +86,6 @@ class ExecutionBlockMock final : public arangodb::aql::ExecutionBlock {
|
||||||
arangodb::aql::ExecutionNode const& node
|
arangodb::aql::ExecutionNode const& node
|
||||||
);
|
);
|
||||||
|
|
||||||
Type getType() const override final {
|
|
||||||
return Type::_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we release our docs from this collection
|
// here we release our docs from this collection
|
||||||
std::pair<arangodb::aql::ExecutionState, arangodb::Result> initializeCursor(
|
std::pair<arangodb::aql::ExecutionState, arangodb::Result> initializeCursor(
|
||||||
arangodb::aql::AqlItemBlock* items, size_t pos) override;
|
arangodb::aql::AqlItemBlock* items, size_t pos) override;
|
||||||
|
|
Loading…
Reference in New Issue