8000 De-inline in AQL (#10025) · archerli/arangodb@82b0a5e · GitHub
[go: up one dir, main page]

Skip to content

Commit 82b0a5e

Browse files
goedderzmchacki
authored andcommitted
De-inline in AQL (arangodb#10025)
* Enable IPO (LTO) via CMake * Use separate IPO_ENABLED variable * Enabled IPO for more binaries * Enabled IPO for arangobackup * Suppress an MSVC warning (though it is not unjustified...) * Fix static builds, broken due to Policy CMP0060 introduced in cmake 3.3 * Removed policies superseded by minimum cmake version * Disable IPO with google tests due to a g++ bug * Disable IPO with google tests only on AUTO * Disable warning for correct line * Begin de-inlining Aql * de-inlining Aql: 2nd batch * de-inlining Aql: 3rd batch * de-inlining Aql: 4th batch * Moved code out of ifdef * Enabled IPO for additional libs * Fixed some problems found with IPO enabled - Fixed ODR violation in Pregel - Removed unused code in ClusterMethods - Avoid possible uninitialized variable usage * Set IPO globally, except for 3rdParty libs * De-inlined AstHelper again (was undone due to a previous merge conflict) * Added missing .cpp file * Fixed compilation with MSVC * Removed superfluous includes from deinlined AQL header files * Added includes for size_t * Deleted outdated files * De-inlined files that were undone during the merge * Removed includes from files that were undone during merge * Fixed merge conflicts
1 parent 41c0710 commit 82b0a5e

File tree

210 files changed

+5705
-5081
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

210 files changed

+5705
-5081
lines changed

arangod/Aql/Aggregator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
////////////////////////////////////////////////////////////////////////////////
2323

2424
#include "Aggregator.h"
25+
26+
#include "Aql/AqlValue.h"
2527
#include "Basics/VelocyPackHelper.h"
2628
#include "Transaction/Context.h"
2729
#include "Transaction/Helpers.h"

arangod/Aql/Aggregator.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,22 @@
2424
#ifndef ARANGOD_AQL_AGGREGATOR_H
2525
#define ARANGOD_AQL_AGGREGATOR_H 1
2626

27-
#include "Aql/AqlValue.h"
28-
#include "Basics/Common.h"
29-
30-
#include <velocypack/Slice.h>
27+
#include <functional>
28+
#include <memory>
29+
#include <string>
3130

3231
namespace arangodb {
3332
namespace transaction {
3433
class Methods;
3534
}
35+
namespace velocypack {
36+
class Slice;
37+
}
3638

3739
namespace aql {
3840

41+
struct AqlValue;
42+
3943
struct Aggregator {
4044
Aggregator() = delete;
4145
Aggregator(Aggregator const&) = delete;

arangod/Aql/AllRowsFetcher.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
#include "AllRowsFetcher.h"
2424

2525
#include "Aql/AqlItemBlock.h"
26+
#include "Aql/AqlItemMatrix.h"
2627
#include "Aql/DependencyProxy.h"
2728
#include "Aql/InputAqlItemRow.h"
28-
#include "Aql/SortExecutor.h"
2929

3030
using namespace arangodb;
3131
using namespace arangodb::aql;
@@ -131,3 +131,8 @@ ExecutionState AllRowsFetcher::upstreamState() {
131131
}
132132
return ExecutionState::HASMORE;
133133
}
134+
135+
std::pair<ExecutionState, SharedAqlItemBlockPtr> AllRowsFetcher::fetchBlockForPassthrough(size_t) {
136+
TRI_ASSERT(false);
137+
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
138+
}

arangod/Aql/AllRowsFetcher.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@
2323
#ifndef ARANGOD_AQL_ALL_ROWS_FETCHER_H
2424
#define ARANGOD_AQL_ALL_ROWS_FETCHER_H
2525

26-
#include "Aql/AqlItemMatrix.h"
27-
#include "Aql/ExecutionState.h"
26+
#include "Aql/types.h"
2827

28+
#include <Basics/Common.h>
2929
#include <Basics/Exceptions.h>
3030

31+
#include <cstddef>
3132
#include <memory>
3233

3334
namespace arangodb {
3435
namespace aql {
3536

3637
class AqlItemBlock;
38+
class AqlItemMatrix;
39+
class SharedAqlItemBlockPtr;
40+
enum class ExecutionState;
3741
template <bool>
3842
class DependencyProxy;
3943

@@ -74,10 +78,7 @@ class AllRowsFetcher {
7478
// AllRowsFetcher cannot pass through. Could be implemented, but currently
7579
// there are no executors that could use this and not better use
7680
// SingleRowFetcher instead.
77-
std::pair<ExecutionState, SharedAqlItemBlockPtr> fetchBlockForPassthrough(size_t) {
78-
TRI_ASSERT(false);
79-
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
80-
};
81+
std::pair<ExecutionState, SharedAqlItemBlockPtr> fetchBlockForPassthrough(size_t);
8182

8283
/**
8384
* @brief Prefetch the number of rows that will be returned from upstream.

arangod/Aql/AqlFunctionFeature.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
////////////////////////////////////////////////////////////////////////////////
2222

2323
#include "AqlFunctionFeature.h"
24+
2425
#include "Aql/AstNode.h"
26+
#include "Aql/Function.h"
2527
#include "Cluster/ServerState.h"
2628
#include "StorageEngine/EngineSelectorFeature.h"
2729
#include "StorageEngine/StorageEngine.h"

arangod/Aql/AqlFunctionFeature.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#define ARANGOD_AQL_AQL_FUNCTION_FEATURE_H 1
2525

2626
#include "ApplicationFeatures/ApplicationFeature.h"
27-
#include "Aql/AstNode.h"
2827
#include "Aql/Function.h"
2928

3029
namespace arangodb {
@@ -71,7 +70,6 @@ class AqlFunctionFeature final : public application_features::ApplicationFeature
7170
void addGeometryConstructors();
7271
void addDateFunctions();
7372
void addMiscFunctions();
74-
void addStorageEngineFunctions();
7573

7674
/// @brief AQL user-callable function names
7775
std::unordered_map<std::string, Function const> _functionNames;

arangod/Aql/AqlItemBlock.cpp

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "Aql/BlockCollector.h"
2929
#include "Aql/ExecutionBlock.h"
3030
#include "Aql/ExecutionNode.h"
31+
#include "Aql/Range.h"
32+
#include "Aql/RegisterPlan.h"
3133
#include "Aql/SharedAqlItemBlockPtr.h"
3234
#include "Basics/VelocyPackHelper.h"
3335

@@ -711,3 +713,206 @@ void AqlItemBlock::copySubQueryDepthToOtherBlock(SharedAqlItemBlockPtr& target,
711713
TRI_ASSERT(false);
712714
}
713715
}
716+
717+
AqlItemBlock::~AqlItemBlock() {
718+
TRI_ASSERT(_refCount == 0);
719+
destroy();
720+
decreaseMemoryUsage(sizeof(AqlValue) * _nrItems * internalNrRegs());
721+
}
722+
723+
void AqlItemBlock::increaseMemoryUsage(size_t value) {
724+
resourceMonitor().increaseMemoryUsage(value);
725+
}
726+
727+
void AqlItemBlock::decreaseMemoryUsage(size_t value) noexcept {
728+
resourceMonitor().decreaseMemoryUsage(value);
729+
}
730+
731+
AqlValue AqlItemBlock::getValue(size_t index, RegisterId varNr) const {
732+
return _data[getAddress(index, varNr)];
733+
}
734+
735+
AqlValue const& AqlItemBlock::getValueReference(size_t index, RegisterId varNr) const {
736+
return _data[getAddress(index, varNr)];
737+
}
738+
739+
void AqlItemBlock::setValue(size_t index, RegisterId varNr, AqlValue const& value) {
740+
TRI_ASSERT(_data[getAddress(index, varNr)].isEmpty());
741+
742+
// First update the reference count, if this fails, the value is empty
743+
if (value.requiresDestruction()) {
744+
if (++_valueCount[value] == 1) {
745+
size_t mem = value.memoryUsage();
746+
increaseMemoryUsage(mem);
747+
}
748+
}
749+
750+
_data[getAddress(index, varNr)] = value;
751+
}
752+
753+
void AqlItemBlock::destroyValue(size_t index, RegisterId varNr) {
754+
auto& element = _data[getAddress(index, varNr)];
755+
756+
if (element.requiresDestruction()) {
757+
auto it = _valueCount.find(element);
758+
759+
if (it != _valueCount.end()) {
760+
if (--(it->second) == 0) {
761+
decreaseMemoryUsage(element.memoryUsage());
762+
_valueCount.erase(it);
763+
element.destroy();
764+
return; // no need for an extra element.erase() in this case
765+
}
766+
}
767+
}
768+
769+
element.erase();
770+
}
771+
772+
void AqlItemBlock::eraseValue(size_t index, RegisterId varNr) {
773+
auto& element = _data[getAddress(index, varNr)];
774+
775+
if (element.requiresDestruction()) {
776+
auto it = _valueCount.find(element);
777+
778+
if (it != _valueCount.end()) {
779+
if (--(it->second) == 0) {
780+
decreaseMemoryUsage(element.memoryUsage());
781+
try {
782+
_valueCount.erase(it);
783+
} catch (...) {
784+
}
785+
}
786+
}
787+
}
788+
789+
element.erase();
790+
}
791+
792+
void AqlItemBlock::eraseAll() {
793+
for (size_t i = 0; i < numEntries(); i++) {
794+
auto& it = _data[i];
795+
if (!it.isEmpty()) {
796+
it.erase();
797+
}
798+
}
799+
800+
for (auto const& it : _valueCount) {
801+
if (it.second > 0) {
802+
decreaseMemoryUsage(it.first.memoryUsage());
803+
}
804+
}
805+
_valueCount.clear();
806+
}
807+
808+
void AqlItemBlock::copyValuesFromRow(size_t currentRow, RegisterId curRegs, size_t fromRow) {
809+
TRI_ASSERT(currentRow != fromRow);
810+
811+
for (RegisterId i = 0; i < curRegs; i++) {
812+
auto currentAddress = getAddress(currentRow, i);
813+
auto fromAddress = getAddress(fromRow, i);
814+
if (_data[currentAddress].isEmpty()) {
815+
// First update the reference count, if this fails, the value is empty
816+
if (_data[fromAddress].requiresDestruction()) {
817+
++_valueCount[_data[fromAddress]];
818+
}
819+
TRI_ASSERT(_data[currentAddress].isEmpty());
820+
_data[currentAddress] = _data[fromAddress];
821+
}
822+
}
823+
// Copy over subqueryDepth
824+
copySubqueryDepth(currentRow, fromRow);
825+
}
826+
827+
void AqlItemBlock::copyValuesFromRow(size_t currentRow,
828+
std::unordered_set<RegisterId> const& regs,
829+
size_t fromRow) {
830+
TRI_ASSERT(currentRow != fromRow);
831+
832+
for (auto const reg : regs) {
833+
TRI_ASSERT(reg < getNrRegs());
834+
if (getValueReference(currentRow, reg).isEmpty()) {
835+
// First update the reference count, if this fails, the value is empty
836+
if (getValueReference(fromRow, reg).requiresDestruction()) {
837+
++_valueCount[getValueReference(fromRow, reg)];
838+
}
839+
_data[getAddress(currentRow, reg)] = getValueReference(fromRow, reg);
840+
}
841+
}
842+
// Copy over subqueryDepth
843+
copySubqueryDepth(currentRow, fromRow);
844+
}
845+
846+
void AqlItemBlock::steal(AqlValue const& value) {
847+
if (value.requiresDestruction()) {
848+
if (_valueCount.erase(value)) {
849+
decreaseMemoryUsage(value.memoryUsage());
850+
}
851+
}
852+
}
853+
854+
RegisterId AqlItemBlock::getNrRegs() const noexcept { return _nrRegs; }
855+
856+
size_t AqlItemBlock::size() const noexcept { return _nrItems; }
857+
858+
size_t AqlItemBlock::numEntries() const { return internalNrRegs() * _nrItems; }
859+
860+
size_t AqlItemBlock::capacity() const noexcept { return _data.capacity(); }
861+
862+
bool AqlItemBlock::isShadowRow(size_t row) const {
863+
/// This value is only filled for shadowRows.
864+
/// And it is guaranteed to be only filled by numbers this way.
865+
return _data[getSubqueryDepthAddress(row)].isNumber();
866+
}
867+
868+
AqlValue const& AqlItemBlock::getShadowRowDepth(size_t row) const {
869+
TRI_ASSERT(isShadowRow(row));
870+
return _data[getSubqueryDepthAddress(row)];
871+
}
872+
873+
void AqlItemBlock::setShadowRowDepth(size_t row, AqlValue const& other) {
874+
TRI_ASSERT(other.isNumber());
875+
_data[getSubqueryDepthAddress(row)] = other;
876+
TRI_ASSERT(isShadowRow(row));
877+
}
878+
879+
void AqlItemBlock::makeShadowRow(size_t row) {
880+
TRI_ASSERT(!isShadowRow(row));
881+
_data[getSubqueryDepthAddress(row)] = AqlValue{VPackSlice::zeroSlice()};
882+
}
883+
884+
void AqlItemBlock::makeDataRow(size_t row) {
885+
TRI_ASSERT(isShadowRow(row));
886+
_data[getSubqueryDepthAddress(row)] = AqlValue{VPackSlice::noneSlice()};
887+
}
888+
889+
AqlItemBlockManager& AqlItemBlock::aqlItemBlockManager() noexcept { return _manager; }
890+
891+
size_t AqlItemBlock::getRefCount() const noexcept { return _refCount; }
892+
893+
void AqlItemBlock::incrRefCount() const noexcept { ++_refCount; }
894+
895+
void AqlItemBlock::decrRefCount() const noexcept {
896+
TRI_ASSERT(_refCount > 0);
897+
--_refCount;
898+
}
899+
900+
RegisterCount AqlItemBlock::internalNrRegs() const noexcept { return _nrRegs + 1; }
901+
size_t AqlItemBlock::getAddress(size_t index, RegisterId varNr) const noexcept {
902+
TRI_ASSERT(index < _nrItems);
903+
TRI_ASSERT(varNr < _nrRegs);
904+
return index * internalNrRegs() + varNr + 1;
905+
}
906+
907+
size_t AqlItemBlock::getSubqueryDepthAddress(size_t index) const noexcept {
908+
TRI_ASSERT(index < _nrItems);
909+
return index * internalNrRegs();
910+
}
911+
912+
void AqlItemBlock::copySubqueryDepth(size_t currentRow, size_t fromRow) {
913+
auto currentAddress = getSubqueryDepthAddress(currentRow);
914+
auto fromAddress = getSubqueryDepthAddress(fromRow);
915+
if (!_data[fromAddress].isEmpty() && _data[currentAddress].isEmpty()) {
916+
_data[currentAddress] = _data[fromAddress];
917+
}
918+
}

0 commit comments

Comments
 (0)
0