diff --git a/LES-TODOS b/LES-TODOS index 447c90a444..7f30bd8518 100644 --- a/LES-TODOS +++ b/LES-TODOS @@ -117,3 +117,4 @@ OpenIssues Hacki * HashIndex Lookup into a still local buffer, could be replaced by callback as well. * SingleServerTraverser API does NOT takeover responsibility for slice data. getMore() hapes slices to not go away * This API can be improved if we make better use of those callbacks. +* ShortestPathBlock does assume that slices do not walk away. diff --git a/arangod/Aql/ShortestPathBlock.cpp b/arangod/Aql/ShortestPathBlock.cpp index 8d1a5cc2a8..149f5dc7b9 100644 --- a/arangod/Aql/ShortestPathBlock.cpp +++ b/arangod/Aql/ShortestPathBlock.cpp @@ -68,9 +68,6 @@ struct ConstDistanceExpanderLocal { /// @brief Defines if this expander follows the edges in reverse bool _isReverse; - /// @brief Local cursor vector - std::vector _cursor; - public: ConstDistanceExpanderLocal(ShortestPathBlock const* block, bool isReverse) @@ -88,31 +85,25 @@ struct ConstDistanceExpanderLocal { edgeCursor = edgeCollection->getEdges(v, mmdr); } - // Clear the local cursor before using the - // next edge cursor. - // While iterating over the edge cursor, _cursor - // has to stay intact. - _cursor.clear(); LogicalCollection* collection = edgeCursor->collection(); - while (edgeCursor->hasMore()) { - edgeCursor->getMoreTokens(_cursor, 1000); - for (auto const& element : _cursor) { - if (collection->readDocument(_block->transaction(), *mmdr, element)) { - VPackSlice edge(mmdr->vpack()); - VPackSlice from = - arangodb::Transaction::extractFromFromDocument(edge); - if (from == v) { - VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); - if (to != v) { - resEdges.emplace_back(edge); - neighbors.emplace_back(to); - } - } else { + auto cb = [&] (DocumentIdentifierToken const& element) { + if (collection->readDocument(_block->transaction(), *mmdr, element)) { + VPackSlice edge(mmdr->vpack()); + VPackSlice from = + arangodb::Transaction::extractFromFromDocument(edge); + if (from == v) { + VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); + if (to != v) { resEdges.emplace_back(edge); - neighbors.emplace_back(from); + neighbors.emplace_back(to); } + } else { + resEdges.emplace_back(edge); + neighbors.emplace_back(from); } } + }; + while (edgeCursor->getMore(cb, 1000)) { } } } @@ -218,7 +209,6 @@ struct EdgeWeightExpanderLocal { void operator()(VPackSlice const& source, std::vector& result) { ManagedDocumentResult* mmdr = _block->_mmdr.get(); - std::vector cursor; std::unique_ptr edgeCursor; std::unordered_map candidates; for (auto const& edgeCollection : _block->_collectionInfos) { @@ -231,28 +221,23 @@ struct EdgeWeightExpanderLocal { candidates.clear(); - // Clear the local cursor before using the - // next edge cursor. - // While iterating over the edge cursor, _cursor - // has to stay intact. - cursor.clear(); LogicalCollection* collection = edgeCursor->collection(); - while (edgeCursor->hasMore()) { - edgeCursor->getMoreTokens(cursor, 1000); - for (auto const& element : cursor) { - if (collection->readDocument(_block->transaction(), *mmdr, element)) { - VPackSlice edge(mmdr->vpack()); - VPackSlice from = - arangodb::Transaction::extractFromFromDocument(edge); - VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); - double currentWeight = edgeCollection->weightEdge(edge); - if (from == source) { - inserter(candidates, result, from, to, currentWeight, edge); - } else { - inserter(candidates, result, to, from, currentWeight, edge); - } + auto cb = [&] (DocumentIdentifierToken const& element) { + if (collection->readDocument(_block->transaction(), *mmdr, element)) { + VPackSlice edge(mmdr->vpack()); + VPackSlice from = + arangodb::Transaction::extractFromFromDocument(edge); + VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); + double currentWeight = edgeCollection->weightEdge(edge); + if (from == source) { + inserter(candidates, result, from, to, currentWeight, edge); + } else { + inserter(candidates, result, to, from, currentWeight, edge); } } + }; + + while (edgeCursor->getMore(cb, 1000)) { } } }