mirror of https://gitee.com/bigwinds/arangodb
Improve calculation executor performance (#8851)
* Avoid a copy in CalculationExecutor<CalculationType::Reference>::doEvaluation * Hack: fixed compilation * Removed accidentally committed broken assert * Replaced const_cast hack * Completed implementation of copyBlockInternalRegister * Simplified some assert code * Fixed maintainer compilation
This commit is contained in:
parent
c9fa5fba11
commit
83732bc369
|
@ -62,17 +62,17 @@ struct CalculationExecutorInfos : public ExecutorInfos {
|
|||
CalculationExecutorInfos(CalculationExecutorInfos const&) = delete;
|
||||
~CalculationExecutorInfos() = default;
|
||||
|
||||
RegisterId getOutputRegisterId() const { return _outputRegisterId; }
|
||||
RegisterId getOutputRegisterId() const noexcept { return _outputRegisterId; }
|
||||
|
||||
Query& getQuery() const { return _query; }
|
||||
Query& getQuery() const noexcept { return _query; }
|
||||
|
||||
Expression& getExpression() const { return _expression; }
|
||||
Expression& getExpression() const noexcept { return _expression; }
|
||||
|
||||
std::vector<Variable const*> const& getExpInVars() const {
|
||||
std::vector<Variable const*> const& getExpInVars() const noexcept {
|
||||
return _expInVars;
|
||||
}
|
||||
|
||||
std::vector<RegisterId> const& getExpInRegs() const { return _expInRegs; }
|
||||
std::vector<RegisterId> const& getExpInRegs() const noexcept { return _expInRegs; }
|
||||
|
||||
private:
|
||||
RegisterId _outputRegisterId;
|
||||
|
@ -184,7 +184,10 @@ inline void CalculationExecutor<CalculationType::Reference>::doEvaluation(
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG);
|
||||
}
|
||||
|
||||
output.cloneValueInto(_infos.getOutputRegisterId(), input, input.getValue(inRegs[0]));
|
||||
// We assume here that the output block (which must be the same as the input
|
||||
// block) is already responsible for this value.
|
||||
// Thus we do not want to clone it.
|
||||
output.copyBlockInternalRegister(input, inRegs[0], _infos.getOutputRegisterId());
|
||||
}
|
||||
|
||||
template <CalculationType calculationType>
|
||||
|
|
|
@ -72,7 +72,7 @@ class InputAqlItemRow {
|
|||
*
|
||||
* @return Reference to the AqlValue stored in that variable.
|
||||
*/
|
||||
inline const AqlValue& getValue(RegisterId registerId) const {
|
||||
inline AqlValue const& getValue(RegisterId registerId) const {
|
||||
TRI_ASSERT(isInitialized());
|
||||
TRI_ASSERT(registerId < getNrRegisters());
|
||||
return block().getValueReference(_baseIndex, registerId);
|
||||
|
|
|
@ -74,22 +74,11 @@ class OutputAqlItemRow {
|
|||
// responsibility of possibly referenced external memory.
|
||||
void moveValueInto(RegisterId registerId, InputAqlItemRow const& sourceRow,
|
||||
AqlValueGuard& guard) {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
if (!isOutputRegister(registerId)) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_WROTE_IN_WRONG_REGISTER);
|
||||
}
|
||||
TRI_ASSERT(isOutputRegister(registerId));
|
||||
// This is already implicitly asserted by isOutputRegister:
|
||||
TRI_ASSERT(registerId < getNrRegisters());
|
||||
if (_numValuesWritten >= numRegistersToWrite()) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_WROTE_TOO_MANY_OUTPUT_REGISTERS);
|
||||
}
|
||||
if (!block().getValueReference(_baseIndex, registerId).isNone()) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_WROTE_OUTPUT_REGISTER_TWICE);
|
||||
}
|
||||
#endif
|
||||
TRI_ASSERT(_numValuesWritten < numRegistersToWrite());
|
||||
TRI_ASSERT(block().getValueReference(_baseIndex, registerId).isNone());
|
||||
|
||||
block().setValue(_baseIndex, registerId, guard.value());
|
||||
guard.steal();
|
||||
|
@ -106,12 +95,7 @@ class OutputAqlItemRow {
|
|||
// If the reusing does not work this call will return `false` caller needs to
|
||||
// react accordingly.
|
||||
bool reuseLastStoredValue(RegisterId registerId, InputAqlItemRow const& sourceRow) {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
if (!isOutputRegister(registerId)) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_WROTE_IN_WRONG_REGISTER);
|
||||
}
|
||||
#endif
|
||||
TRI_ASSERT(isOutputRegister(registerId));
|
||||
if (_lastBaseIndex == _baseIndex) {
|
||||
return false;
|
||||
}
|
||||
|
@ -137,8 +121,8 @@ class OutputAqlItemRow {
|
|||
// This may only be set if the input block is the same as the output block,
|
||||
// because it is passed through.
|
||||
if (_doNotCopyInputRow) {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(sourceRow.isInitialized());
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(sourceRow.internalBlockIs(_block));
|
||||
#endif
|
||||
_inputRowCopied = true;
|
||||
|
@ -150,6 +134,30 @@ class OutputAqlItemRow {
|
|||
doCopyRow(sourceRow, ignoreMissing);
|
||||
}
|
||||
|
||||
void copyBlockInternalRegister(InputAqlItemRow const& sourceRow,
|
||||
RegisterId input, RegisterId output) {
|
||||
// This method is only allowed if the block of the input row is the same as
|
||||
// the block of the output row!
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(sourceRow.internalBlockIs(_block));
|
||||
#endif
|
||||
TRI_ASSERT(isOutputRegister(output));
|
||||
// This is already implicitly asserted by isOutputRegister:
|
||||
TRI_ASSERT(output < getNrRegisters());
|
||||
TRI_ASSERT(_numValuesWritten < numRegistersToWrite());
|
||||
TRI_ASSERT(block().getValueReference(_baseIndex, output).isNone());
|
||||
|
||||
AqlValue const& value = sourceRow.getValue(input);
|
||||
|
||||
block().setValue(_baseIndex, output, value);
|
||||
_numValuesWritten++;
|
||||
// allValuesWritten() must be called only *after* _numValuesWritten was
|
||||
// increased.
|
||||
if (allValuesWritten()) {
|
||||
copyRow(sourceRow);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t getNrRegisters() const { return block().getNrRegs(); }
|
||||
|
||||
/**
|
||||
|
@ -158,17 +166,9 @@ class OutputAqlItemRow {
|
|||
* been called.
|
||||
*/
|
||||
void advanceRow() {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
TRI_ASSERT(produced());
|
||||
if (!allValuesWritten()) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_WROTE_TOO_FEW_OUTPUT_REGISTERS);
|
||||
}
|
||||
if (!_inputRowCopied) {
|
||||
TRI_ASSERT(false);
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INPUT_REGISTERS_NOT_COPIED);
|
||||
}
|
||||
#endif
|
||||
TRI_ASSERT(allValuesWritten());
|
||||
TRI_ASSERT(_inputRowCopied);
|
||||
_lastBaseIndex = _baseIndex++;
|
||||
_inputRowCopied = false;
|
||||
_numValuesWritten = 0;
|
||||
|
|
Loading…
Reference in New Issue