void operator()(VPackSlice const& v, std::vector<VPackSlice>& resEdges, std::vector<VPackSlice>& neighbors) { int res = TRI_ERROR_NO_ERROR; for (auto const& edgeCollection : _block->_collectionInfos) { VPackBuilder result; TRI_ASSERT(edgeCollection != nullptr); if (_isReverse) { res = edgeCollection->getReverseEdgesCoordinator(v, result); } else { res = edgeCollection->getEdgesCoordinator(v, result); } if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } VPackSlice edges = result.slice().get("edges"); for (auto const& edge : VPackArrayIterator(edges)) { 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 { resEdges.emplace_back(edge); neighbors.emplace_back(from); } } // Make sure the data Slices are pointing to is not running out of scope. // This is not thread-safe! _block->_coordinatorCache.emplace_back(result.steal()); } }
VPackMessageNoOwnBuffer VppResponse::prepareForNetwork() { // initalize builder with vpackbuffer. then we do not need to // steal the header and can avoid the shared pointer VPackBuilder builder; builder.openArray(); builder.add(VPackValue(int(1))); builder.add(VPackValue(int(2))); // 2 == response builder.add( VPackValue(static_cast<int>(meta::underlyingValue(_responseCode)))); builder.close(); _header = builder.steal(); if (_vpackPayloads.empty()) { if (_generateBody) { LOG_TOPIC(INFO, Logger::REQUESTS) << "Response should generate body but no Data available"; _generateBody = false; // no body availalbe } return VPackMessageNoOwnBuffer(VPackSlice(_header->data()), VPackSlice::noneSlice(), _messageId, _generateBody); } else { std::vector<VPackSlice> slices; for (auto const& buffer : _vpackPayloads) { slices.emplace_back(buffer.data()); } return VPackMessageNoOwnBuffer(VPackSlice(_header->data()), std::move(slices), _messageId, _generateBody); } }
void operator()(VPackSlice const& source, std::vector<ArangoDBPathFinder::Step*>& result) { int res = TRI_ERROR_NO_ERROR; for (auto const& edgeCollection : _block->_collectionInfos) { TRI_ASSERT(edgeCollection != nullptr); VPackBuilder edgesBuilder; if (_reverse) { res = edgeCollection->getReverseEdgesCoordinator(source, edgesBuilder); } else { res = edgeCollection->getEdgesCoordinator(source, edgesBuilder); } if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } std::unordered_map<VPackSlice, size_t> candidates; auto inserter = [&](VPackSlice const& s, VPackSlice const& t, double currentWeight, VPackSlice const& edge) { auto cand = candidates.find(t); if (cand == candidates.end()) { // Add weight auto step = std::make_unique<ArangoDBPathFinder::Step>( t, s, currentWeight, std::move(edge)); result.emplace_back(step.release()); candidates.emplace(t, result.size() - 1); } else { // Compare weight auto old = result[cand->second]; auto oldWeight = old->weight(); if (currentWeight < oldWeight) { old->setWeight(currentWeight); old->_predecessor = s; old->_edge = edge; } } }; VPackSlice edges = edgesBuilder.slice().get("edges"); for (auto const& edge : VPackArrayIterator(edges)) { VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge); VPackSlice to = arangodb::Transaction::extractToFromDocument(edge); double currentWeight = edgeCollection->weightEdge(edge); if (from == source) { inserter(from, to, currentWeight, edge); } else { inserter(to, from, currentWeight, edge); } } _block->_coordinatorCache.emplace_back(edgesBuilder.steal()); } }