diff --git a/arangod/Cluster/ClusterMethods.cpp b/arangod/Cluster/ClusterMethods.cpp index a9d63424d8..d717090b48 100644 --- a/arangod/Cluster/ClusterMethods.cpp +++ b/arangod/Cluster/ClusterMethods.cpp @@ -23,8 +23,6 @@ #include "ClusterMethods.h" #include "Basics/conversions.h" -#include "Basics/json.h" -#include "Basics/json-utilities.h" #include "Basics/StringUtils.h" #include "Basics/tri-strings.h" #include "Basics/VelocyPackHelper.h" @@ -1421,12 +1419,14 @@ static void insertIntoShardMap( std::string collid = StringUtils::itoa(collinfo->id()); if (collinfo->usesDefaultShardKeys()) { // We only need add one resp. shard - arangodb::basics::Json partial(arangodb::basics::Json::Object, 1); - partial.set("_key", arangodb::basics::Json(splitId[1])); + VPackBuilder partial; + partial.openObject(); + partial.add(TRI_VOC_ATTRIBUTE_KEY, VPackValue(splitId[1])); + partial.close(); bool usesDefaultShardingAttributes; ShardID shardID; - int error = ci->getResponsibleShard(collid, partial.json(), true, shardID, + int error = ci->getResponsibleShard(collid, partial.slice(), true, shardID, usesDefaultShardingAttributes); if (error != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(error); @@ -1569,9 +1569,8 @@ int getFilteredEdgesOnCoordinator( std::string const& vertex, TRI_edge_direction_e const& direction, std::vector const& expressions, arangodb::GeneralResponse::ResponseCode& responseCode, - std::string& contentType, arangodb::basics::Json& result) { - TRI_ASSERT(result.isObject()); - TRI_ASSERT(result.members() == 0); + std::string& contentType, VPackBuilder& result) { + TRI_ASSERT(result.isOpenObject()); // Set a few variables needed for our work: ClusterInfo* ci = ClusterInfo::instance(); @@ -1594,13 +1593,13 @@ int getFilteredEdgesOnCoordinator( } auto reqBodyString = std::make_shared(); if (!expressions.empty()) { - arangodb::basics::Json body(Json::Array, expressions.size()); + VPackBuilder bodyBuilder; + bodyBuilder.openArray(); for (auto& e : expressions) { - arangodb::basics::Json tmp(Json::Object); - e->toJson(tmp, TRI_UNKNOWN_MEM_ZONE); - body.add(tmp.steal()); + e->toVelocyPack(bodyBuilder); } - reqBodyString->append(body.toString()); + bodyBuilder.close(); + reqBodyString->append(bodyBuilder.toJson()); } for (auto const& p : *shards) { std::unique_ptr> headers( @@ -1618,7 +1617,7 @@ int getFilteredEdgesOnCoordinator( size_t filtered = 0; size_t scannedIndex = 0; - arangodb::basics::Json documents(arangodb::basics::Json::Array); + result.add("edges", VPackValue(VPackValueType::Array)); for (count = (int)shards->size(); count > 0; count--) { auto res = cc->wait("", coordTransactionID, 0, "", 0.0); @@ -1631,59 +1630,51 @@ int getFilteredEdgesOnCoordinator( cc->drop("", coordTransactionID, 0, ""); return TRI_ERROR_INTERNAL; } + std::shared_ptr shardResult = res.answer->toVelocyPack(&VPackOptions::Defaults); - std::unique_ptr shardResult( - TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, res.answer->body().c_str())); - - if (shardResult == nullptr || !TRI_IsObjectJson(shardResult.get())) { + if (shardResult == nullptr) { return TRI_ERROR_INTERNAL; } - bool const isError = arangodb::basics::JsonHelper::checkAndGetBooleanValue( - shardResult.get(), "error"); + VPackSlice shardSlice = shardResult->slice(); + if (!shardSlice.isObject()) { + return TRI_ERROR_INTERNAL; + } + + bool const isError = arangodb::basics::VelocyPackHelper::getBooleanValue( + shardSlice, "error", false); if (isError) { - // shared returned an error - return arangodb::basics::JsonHelper::getNumericValue( - shardResult.get(), "errorNum", TRI_ERROR_INTERNAL); + // shard returned an error + return arangodb::basics::VelocyPackHelper::getNumericValue( + shardSlice, "errorNum", TRI_ERROR_INTERNAL); } - auto docs = TRI_LookupObjectJson(shardResult.get(), "edges"); + VPackSlice docs = shardSlice.get("edges"); - if (!TRI_IsArrayJson(docs)) { + if (!docs.isArray()) { return TRI_ERROR_INTERNAL; } - size_t const n = TRI_LengthArrayJson(docs); - documents.reserve(n); - - for (size_t j = 0; j < n; ++j) { - auto doc = - static_cast(TRI_AtVector(&docs->_value._objects, j)); - - // this will transfer the ownership for the JSON into "documents" - documents.transfer(doc); + for (auto const& doc : VPackArrayIterator(docs)) { + result.add(doc); } - TRI_json_t* stats = arangodb::basics::JsonHelper::getObjectElement( - shardResult.get(), "stats"); - // We do not own stats, do not delete it. - - if (stats != nullptr) { - filtered += arangodb::basics::JsonHelper::getNumericValue( + VPackSlice stats = shardSlice.get("stats"); + if (stats.isObject()) { + filtered += arangodb::basics::VelocyPackHelper::getNumericValue( stats, "filtered", 0); - scannedIndex += arangodb::basics::JsonHelper::getNumericValue( + scannedIndex += arangodb::basics::VelocyPackHelper::getNumericValue( stats, "scannedIndex", 0); } } + result.close(); // edges - result("edges", documents); - - arangodb::basics::Json stats(arangodb::basics::Json::Object, 2); - stats("scannedIndex", - arangodb::basics::Json(static_cast(scannedIndex))); - stats("filtered", arangodb::basics::Json(static_cast(filtered))); - result("stats", stats); + result.add("stats", VPackValue(VPackValueType::Object)); + result.add("scannedIndex", VPackValue(scannedIndex)); + result.add("filtered", VPackValue(filtered)); + result.close(); // stats + // Leave outer Object open return TRI_ERROR_NO_ERROR; } diff --git a/arangod/Cluster/ClusterMethods.h b/arangod/Cluster/ClusterMethods.h index 91260d3db6..b92211ee09 100644 --- a/arangod/Cluster/ClusterMethods.h +++ b/arangod/Cluster/ClusterMethods.h @@ -143,7 +143,7 @@ int getFilteredDocumentsOnCoordinator( //////////////////////////////////////////////////////////////////////////////// /// @brief get a filtered set of edges on Coordinator. -/// Also returns the result in Json +/// Also returns the result in VelcoyPack //////////////////////////////////////////////////////////////////////////////// int getFilteredEdgesOnCoordinator( @@ -151,7 +151,7 @@ int getFilteredEdgesOnCoordinator( std::string const& vertex, TRI_edge_direction_e const& direction, std::vector const& expressions, arangodb::GeneralResponse::ResponseCode& responseCode, - std::string& contentType, arangodb::basics::Json& resultJson); + std::string& contentType, arangodb::velocypack::Builder& result); //////////////////////////////////////////////////////////////////////////////// /// @brief modify a document in a coordinator diff --git a/arangod/Cluster/ClusterTraverser.cpp b/arangod/Cluster/ClusterTraverser.cpp index c15927f8c6..b84e7101d6 100644 --- a/arangod/Cluster/ClusterTraverser.cpp +++ b/arangod/Cluster/ClusterTraverser.cpp @@ -22,8 +22,12 @@ //////////////////////////////////////////////////////////////////////////////// #include "ClusterTraverser.h" +#include "Basics/VelocyPackHelper.h" #include "Cluster/ClusterMethods.h" +#include +#include + using namespace arangodb; using ClusterTraversalPath = arangodb::traverser::ClusterTraversalPath; @@ -113,7 +117,6 @@ void ClusterTraverser::EdgeGetter::operator()(std::string const& startVertex, size_t depth = result.size(); TRI_ASSERT(_traverser->_iteratorCache.size() == result.size()); // We have to request the next level - arangodb::basics::Json resultEdges(arangodb::basics::Json::Object); arangodb::GeneralResponse::ResponseCode responseCode; std::string contentType; std::vector expEdges; @@ -122,23 +125,27 @@ void ClusterTraverser::EdgeGetter::operator()(std::string const& startVertex, expEdges = found->second; } + VPackBuilder resultEdges; + resultEdges.openObject(); int res = getFilteredEdgesOnCoordinator( _traverser->_dbname, collName, startVertex, dir, expEdges, responseCode, contentType, resultEdges); if (res != TRI_ERROR_NO_ERROR) { THROW_ARANGO_EXCEPTION(res); } - arangodb::basics::Json edgesJson = resultEdges.get("edges"); + resultEdges.close(); + VPackSlice resSlice = resultEdges.slice(); + VPackSlice edgesSlice = resSlice.get("edges"); + VPackSlice statsSlice = resSlice.get("stats"); - arangodb::basics::Json statsJson = resultEdges.get("stats"); - size_t read = arangodb::basics::JsonHelper::getNumericValue( - statsJson.json(), "scannedIndex", 0); - size_t filter = arangodb::basics::JsonHelper::getNumericValue( - statsJson.json(), "filtered", 0); + size_t read = arangodb::basics::VelocyPackHelper::getNumericValue( + statsSlice, "scannedIndex", 0); + size_t filter = arangodb::basics::VelocyPackHelper::getNumericValue( + statsSlice, "filtered", 0); _traverser->_readDocuments += read; _traverser->_filteredPaths += filter; - size_t count = edgesJson.size(); + size_t count = static_cast(resSlice.length()); if (count == 0) { last = nullptr; eColIdx++; @@ -147,25 +154,23 @@ void ClusterTraverser::EdgeGetter::operator()(std::string const& startVertex, } std::stack stack; std::unordered_set verticesToFetch; - for (size_t i = 0; i < edgesJson.size(); ++i) { - arangodb::basics::Json edge = edgesJson.at(i); + for (auto const& edge : VPackArrayIterator(edgesSlice)) { std::string edgeId = - arangodb::basics::JsonHelper::getStringValue(edge.json(), "_id", ""); - stack.push(edgeId); - std::string fromId = arangodb::basics::JsonHelper::getStringValue( - edge.json(), "_from", ""); + arangodb::basics::VelocyPackHelper::getStringValue(edge, "_id", ""); + stack.push(std::move(edgeId)); + std::string fromId = arangodb::basics::VelocyPackHelper::getStringValue( + edge, "_from", ""); if (_traverser->_vertices.find(fromId) == _traverser->_vertices.end()) { - verticesToFetch.emplace(fromId); + verticesToFetch.emplace(std::move(fromId)); } std::string toId = - arangodb::basics::JsonHelper::getStringValue(edge.json(), "_to", ""); + arangodb::basics::VelocyPackHelper::getStringValue(edge, "_to", ""); if (_traverser->_vertices.find(toId) == _traverser->_vertices.end()) { - verticesToFetch.emplace(toId); - } - auto tmpBuilder = basics::JsonHelper::toVelocyPack(edge.json()); - if (tmpBuilder != nullptr) { - _traverser->_edges.emplace(edgeId, tmpBuilder->steal()); + verticesToFetch.emplace(std::move(toId)); } + VPackBuilder tmpBuilder; + tmpBuilder.add(edge); + _traverser->_edges.emplace(edgeId, tmpBuilder.steal()); } _traverser->fetchVertices(verticesToFetch, depth + 1); diff --git a/arangod/RestHandler/RestEdgesHandler.cpp b/arangod/RestHandler/RestEdgesHandler.cpp index 2c82e18745..abf043dcd6 100644 --- a/arangod/RestHandler/RestEdgesHandler.cpp +++ b/arangod/RestHandler/RestEdgesHandler.cpp @@ -22,7 +22,6 @@ //////////////////////////////////////////////////////////////////////////////// #include "RestEdgesHandler.h" -#include "Basics/JsonHelper.h" #include "Basics/ScopeGuard.h" #include "Cluster/ClusterMethods.h" #include "Indexes/EdgeIndex.h" @@ -251,7 +250,8 @@ bool RestEdgesHandler::readEdges( std::string vertexString(startVertex); GeneralResponse::ResponseCode responseCode; std::string contentType; - arangodb::basics::Json resultDocument(arangodb::basics::Json::Object, 3); + VPackBuilder resultDocument; + resultDocument.openObject(); int res = getFilteredEdgesOnCoordinator( _vocbase->_name, collectionName, vertexString, direction, expressions, @@ -261,12 +261,11 @@ bool RestEdgesHandler::readEdges( return false; } - resultDocument.set("error", arangodb::basics::Json(false)); - resultDocument.set("code", arangodb::basics::Json(200)); + resultDocument.add("error", VPackValue(false)); + resultDocument.add("code", VPackValue(200)); + resultDocument.close(); - VPackBuilder tmp; - arangodb::basics::JsonHelper::toVelocyPack(resultDocument.json(), tmp); - generateResult(GeneralResponse::ResponseCode::OK, tmp.slice()); + generateResult(GeneralResponse::ResponseCode::OK, resultDocument.slice()); return true; } @@ -403,8 +402,10 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() { if (ServerState::instance()->isCoordinator()) { GeneralResponse::ResponseCode responseCode; std::string contentType; - arangodb::basics::Json resultDocument(arangodb::basics::Json::Object, 3); + VPackBuilder resultDocument; + resultDocument.openObject(); +#warning Proper babies implementation required here for (auto const& it : VPackArrayIterator(body)) { if (it.isString()) { std::string vertexString(it.copyString()); @@ -418,14 +419,11 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() { } } } - - resultDocument.set("error", arangodb::basics::Json(false)); - resultDocument.set("code", arangodb::basics::Json(200)); - - VPackBuilder tmp; - arangodb::basics::JsonHelper::toVelocyPack(resultDocument.json(), tmp); - generateResult(GeneralResponse::ResponseCode::OK, tmp.slice()); + resultDocument.add("error", VPackValue(false)); + resultDocument.add("code", VPackValue(200)); + resultDocument.close(); + generateResult(GeneralResponse::ResponseCode::OK, resultDocument.slice()); return true; }