mirror of https://gitee.com/bigwinds/arangodb
Implementation outline of MultiDependencySingleRowFetcher::skipSome for subqueryDepth > 0
This commit is contained in:
parent
1420519319
commit
8a37297424
|
@ -34,7 +34,7 @@ MultiDependencySingleRowFetcher::DependencyInfo::DependencyInfo()
|
||||||
|
|
||||||
MultiDependencySingleRowFetcher::MultiDependencySingleRowFetcher(
|
MultiDependencySingleRowFetcher::MultiDependencySingleRowFetcher(
|
||||||
DependencyProxy<BlockPassthrough::Disable>& executionBlock)
|
DependencyProxy<BlockPassthrough::Disable>& executionBlock)
|
||||||
: _dependencyProxy(&executionBlock) {}
|
: _dependencyProxy{&executionBlock}, _dependencyInfos{}, _nextSkipDependencyIndex{0} {}
|
||||||
|
|
||||||
std::pair<ExecutionState, SharedAqlItemBlockPtr> MultiDependencySingleRowFetcher::fetchBlockForDependency(
|
std::pair<ExecutionState, SharedAqlItemBlockPtr> MultiDependencySingleRowFetcher::fetchBlockForDependency(
|
||||||
size_t dependency, size_t atMost) {
|
size_t dependency, size_t atMost) {
|
||||||
|
@ -148,7 +148,7 @@ std::pair<ExecutionState, ShadowAqlItemRow> MultiDependencySingleRowFetcher::fet
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiDependencySingleRowFetcher::MultiDependencySingleRowFetcher()
|
MultiDependencySingleRowFetcher::MultiDependencySingleRowFetcher()
|
||||||
: _dependencyProxy(nullptr) {}
|
: _dependencyProxy{nullptr}, _dependencyInfos{}, _nextSkipDependencyIndex{0} {}
|
||||||
|
|
||||||
RegisterId MultiDependencySingleRowFetcher::getNrInputRegisters() const {
|
RegisterId MultiDependencySingleRowFetcher::getNrInputRegisters() const {
|
||||||
return _dependencyProxy->getNrInputRegisters();
|
return _dependencyProxy->getNrInputRegisters();
|
||||||
|
@ -229,7 +229,7 @@ std::pair<ExecutionState, InputAqlItemRow> MultiDependencySingleRowFetcher::fetc
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ExecutionState, size_t> MultiDependencySingleRowFetcher::skipRowsForDependency(
|
std::pair<ExecutionState, size_t> MultiDependencySingleRowFetcher::skipRowsForDependency(
|
||||||
size_t const dependency, size_t const atMost, size_t const subqueryDepth) {
|
size_t const dependency, size_t const atMost) {
|
||||||
TRI_ASSERT(dependency < _dependencyInfos.size());
|
TRI_ASSERT(dependency < _dependencyInfos.size());
|
||||||
auto& depInfo = _dependencyInfos[dependency];
|
auto& depInfo = _dependencyInfos[dependency];
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ std::pair<ExecutionState, size_t> MultiDependencySingleRowFetcher::skipRowsForDe
|
||||||
TRI_ASSERT(!indexIsValid(depInfo));
|
TRI_ASSERT(!indexIsValid(depInfo));
|
||||||
ExecutionState state;
|
ExecutionState state;
|
||||||
size_t skipped;
|
size_t skipped;
|
||||||
std::tie(state, skipped) = skipSomeForDependency(dependency, atMost, subqueryDepth);
|
std::tie(state, skipped) = skipSomeForDependency(dependency, atMost, 0);
|
||||||
if (state == ExecutionState::HASMORE && skipped < atMost) {
|
if (state == ExecutionState::HASMORE && skipped < atMost) {
|
||||||
state = ExecutionState::DONE;
|
state = ExecutionState::DONE;
|
||||||
}
|
}
|
||||||
|
@ -349,11 +349,50 @@ bool MultiDependencySingleRowFetcher::fetchBlockIfNecessary(size_t const depende
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ExecutionState, size_t> MultiDependencySingleRowFetcher::skipRows(
|
std::pair<ExecutionState, size_t> MultiDependencySingleRowFetcher::skipSome(size_t atMost,
|
||||||
size_t const atMost, size_t const subqueryDepth) {
|
size_t subqueryDepth) {
|
||||||
// Must not be called for the current level
|
// Must not be called for the subqueryDepth == 0. It does not make sense for
|
||||||
|
// this fetcher to use anything but skipRowsForDependency() for the current level!
|
||||||
TRI_ASSERT(subqueryDepth > 0);
|
TRI_ASSERT(subqueryDepth > 0);
|
||||||
// not yet implemented
|
|
||||||
TRI_ASSERT(false);
|
TRI_ASSERT(_nextSkipDependencyIndex < _dependencyInfos.size());
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
|
||||||
|
{ // Skip deps that are DONE
|
||||||
|
|
||||||
|
// TODO Think this through. Is this necessary, and is it correct? What to do with DONE dependencies?
|
||||||
|
while (_nextSkipDependencyIndex < _dependencyInfos.size() &&
|
||||||
|
_dependencyInfos[_nextSkipDependencyIndex]._upstreamState == ExecutionState::DONE) {
|
||||||
|
auto& depInfo = _dependencyInfos[_nextSkipDependencyIndex];
|
||||||
|
// TODO skip local shadow rows with depth >= subqueryDepth first
|
||||||
|
depInfo._currentBlock = nullptr;
|
||||||
|
depInfo._rowIndex = 0;
|
||||||
|
++_nextSkipDependencyIndex;
|
||||||
|
}
|
||||||
|
if (_nextSkipDependencyIndex >= _dependencyInfos.size()) {
|
||||||
|
_nextSkipDependencyIndex = 0;
|
||||||
|
return {ExecutionState::DONE, 0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_ASSERT(_nextSkipDependencyIndex < _dependencyInfos.size());
|
||||||
|
|
||||||
|
ExecutionState state{};
|
||||||
|
size_t skipped{};
|
||||||
|
while (_nextSkipDependencyIndex < _dependencyInfos.size()) {
|
||||||
|
auto& depInfo = _dependencyInfos[_nextSkipDependencyIndex];
|
||||||
|
|
||||||
|
// TODO skip local shadow rows with depth >= subqueryDepth first
|
||||||
|
std::tie(state, skipped) = _dependencyProxy->skipSome(atMost, subqueryDepth);
|
||||||
|
if (state == ExecutionState::WAITING) {
|
||||||
|
TRI_ASSERT(skipped = 0);
|
||||||
|
return {ExecutionState::WAITING, 0};
|
||||||
|
}
|
||||||
|
depInfo._currentBlock = nullptr;
|
||||||
|
depInfo._rowIndex = 0;
|
||||||
|
++_nextSkipDependencyIndex;
|
||||||
|
}
|
||||||
|
TRI_ASSERT(_nextSkipDependencyIndex == _dependencyInfos.size());
|
||||||
|
TRI_ASSERT(state != ExecutionState::WAITING);
|
||||||
|
|
||||||
|
return {state, skipped};
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,8 +126,7 @@ class MultiDependencySingleRowFetcher {
|
||||||
TEST_VIRTUAL std::pair<ExecutionState, InputAqlItemRow> fetchRowForDependency(
|
TEST_VIRTUAL std::pair<ExecutionState, InputAqlItemRow> fetchRowForDependency(
|
||||||
size_t dependency, size_t atMost = ExecutionBlock::DefaultBatchSize());
|
size_t dependency, size_t atMost = ExecutionBlock::DefaultBatchSize());
|
||||||
|
|
||||||
std::pair<ExecutionState, size_t> skipRowsForDependency(size_t dependency, size_t atMost,
|
std::pair<ExecutionState, size_t> skipRowsForDependency(size_t dependency, size_t atMost);
|
||||||
size_t subqueryDepth);
|
|
||||||
|
|
||||||
std::pair<ExecutionState, ShadowAqlItemRow> fetchShadowRow(
|
std::pair<ExecutionState, ShadowAqlItemRow> fetchShadowRow(
|
||||||
size_t atMost = ExecutionBlock::DefaultBatchSize());
|
size_t atMost = ExecutionBlock::DefaultBatchSize());
|
||||||
|
@ -138,7 +137,7 @@ class MultiDependencySingleRowFetcher {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ExecutionState, size_t> skipRows(size_t atMost, size_t subqueryDepth);
|
std::pair<ExecutionState, size_t> skipSome(size_t atMost, size_t subqueryDepth);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DependencyProxy<BlockPassthrough::Disable>* _dependencyProxy;
|
DependencyProxy<BlockPassthrough::Disable>* _dependencyProxy;
|
||||||
|
@ -148,6 +147,8 @@ class MultiDependencySingleRowFetcher {
|
||||||
*/
|
*/
|
||||||
std::vector<DependencyInfo> _dependencyInfos;
|
std::vector<DependencyInfo> _dependencyInfos;
|
||||||
|
|
||||||
|
size_t _nextSkipDependencyIndex;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Delegates to ExecutionBlock::fetchBlock()
|
* @brief Delegates to ExecutionBlock::fetchBlock()
|
||||||
|
|
|
@ -464,7 +464,7 @@ std::tuple<ExecutionState, SortingGatherExecutor::Stats, size_t> SortingGatherEx
|
||||||
while (state != ExecutionState::DONE && _skipped < atMost) {
|
while (state != ExecutionState::DONE && _skipped < atMost) {
|
||||||
std::size_t skippedNow;
|
std::size_t skippedNow;
|
||||||
std::tie(state, skippedNow) =
|
std::tie(state, skippedNow) =
|
||||||
_fetcher.skipRowsForDependency(_dependencyToFetch, 0, atMost - _skipped);
|
_fetcher.skipRowsForDependency(_dependencyToFetch, atMost - _skipped);
|
||||||
if (state == ExecutionState::WAITING) {
|
if (state == ExecutionState::WAITING) {
|
||||||
TRI_ASSERT(skippedNow == 0);
|
TRI_ASSERT(skippedNow == 0);
|
||||||
return {state, NoStats{}, 0};
|
return {state, NoStats{}, 0};
|
||||||
|
|
|
@ -62,7 +62,7 @@ void arangodb::tests::aql::runFetcher(arangodb::aql::MultiDependencySingleRowFet
|
||||||
void operator()(ConcreteFetcherIOPair<SkipRowsForDependency> const& iop) {
|
void operator()(ConcreteFetcherIOPair<SkipRowsForDependency> const& iop) {
|
||||||
auto const& args = iop.first;
|
auto const& args = iop.first;
|
||||||
auto const& expected = iop.second;
|
auto const& expected = iop.second;
|
||||||
auto actual = testee.skipRowsForDependency(args.dependency, args.atMost, 0);
|
auto actual = testee.skipRowsForDependency(args.dependency, args.atMost);
|
||||||
EXPECT_EQ(expected, actual) << "during step " << i;
|
EXPECT_EQ(expected, actual) << "during step " << i;
|
||||||
}
|
}
|
||||||
void operator()(ConcreteFetcherIOPair<FetchShadowRow> const& iop) {
|
void operator()(ConcreteFetcherIOPair<FetchShadowRow> const& iop) {
|
||||||
|
|
Loading…
Reference in New Issue