Improve Bolt stack performance
Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1612
This commit is contained in:
parent
e67fc40743
commit
9980f899c9
src/communication/bolt
@ -140,7 +140,7 @@ class Client final {
|
||||
if (!decoder_.ReadValue(&record, Value::Type::List)) {
|
||||
throw ClientFatalException();
|
||||
}
|
||||
records.push_back(record.ValueList());
|
||||
records.emplace_back(std::move(record.ValueList()));
|
||||
} else if (signature == Signature::Success) {
|
||||
if (!decoder_.ReadValue(&metadata)) {
|
||||
throw ClientFatalException();
|
||||
@ -167,7 +167,7 @@ class Client final {
|
||||
throw ClientFatalException();
|
||||
}
|
||||
|
||||
QueryData ret{{}, records, metadata.ValueMap()};
|
||||
QueryData ret{{}, std::move(records), std::move(metadata.ValueMap())};
|
||||
|
||||
auto &header = fields.ValueMap();
|
||||
if (header.find("fields") == header.end()) {
|
||||
@ -182,7 +182,7 @@ class Client final {
|
||||
if (field_item.type() != Value::Type::String) {
|
||||
throw ClientFatalException();
|
||||
}
|
||||
ret.fields.push_back(field_item.ValueString());
|
||||
ret.fields.emplace_back(std::move(field_item.ValueString()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -285,13 +285,13 @@ class Decoder {
|
||||
if (size == -1) {
|
||||
return false;
|
||||
}
|
||||
std::vector<Value> ret(size);
|
||||
*data = Value(std::vector<Value>(size));
|
||||
auto &ret = data->ValueList();
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
if (!ReadValue(&ret[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*data = Value(ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -301,34 +301,30 @@ class Decoder {
|
||||
return false;
|
||||
}
|
||||
|
||||
Value dv;
|
||||
std::string str;
|
||||
std::map<std::string, Value> ret;
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
if (!ReadValue(&dv)) {
|
||||
return false;
|
||||
}
|
||||
if (dv.type() != Value::Type::String) {
|
||||
return false;
|
||||
}
|
||||
str = dv.ValueString();
|
||||
Value dv_key, dv_val;
|
||||
|
||||
if (!ReadValue(&dv)) {
|
||||
*data = Value(std::map<std::string, Value>());
|
||||
auto &ret = data->ValueMap();
|
||||
for (int64_t i = 0; i < size; ++i) {
|
||||
if (!ReadValue(&dv_key, Value::Type::String)) {
|
||||
return false;
|
||||
}
|
||||
ret.insert(std::make_pair(str, dv));
|
||||
if (!ReadValue(&dv_val)) {
|
||||
return false;
|
||||
}
|
||||
ret.emplace(std::move(dv_key.ValueString()), std::move(dv_val));
|
||||
}
|
||||
if (ret.size() != size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = Value(ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadVertex(Value *data) {
|
||||
Value dv;
|
||||
Vertex vertex;
|
||||
*data = Value(Vertex());
|
||||
auto &vertex = data->ValueVertex();
|
||||
|
||||
// read ID
|
||||
if (!ReadValue(&dv, Value::Type::Int)) {
|
||||
@ -341,21 +337,19 @@ class Decoder {
|
||||
return false;
|
||||
}
|
||||
auto &labels = dv.ValueList();
|
||||
vertex.labels.resize(labels.size());
|
||||
vertex.labels.reserve(labels.size());
|
||||
for (size_t i = 0; i < labels.size(); ++i) {
|
||||
if (labels[i].type() != Value::Type::String) {
|
||||
return false;
|
||||
}
|
||||
vertex.labels[i] = labels[i].ValueString();
|
||||
vertex.labels.emplace_back(std::move(labels[i].ValueString()));
|
||||
}
|
||||
|
||||
// read properties
|
||||
if (!ReadValue(&dv, Value::Type::Map)) {
|
||||
return false;
|
||||
}
|
||||
vertex.properties = dv.ValueMap();
|
||||
|
||||
*data = Value(vertex);
|
||||
vertex.properties = std::move(dv.ValueMap());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -363,7 +357,8 @@ class Decoder {
|
||||
bool ReadEdge(const Marker &marker, Value *data) {
|
||||
uint8_t value;
|
||||
Value dv;
|
||||
Edge edge;
|
||||
*data = Value(Edge());
|
||||
auto &edge = data->ValueEdge();
|
||||
|
||||
if (!buffer_.Read(&value, 1)) {
|
||||
return false;
|
||||
@ -399,22 +394,21 @@ class Decoder {
|
||||
if (!ReadValue(&dv, Value::Type::String)) {
|
||||
return false;
|
||||
}
|
||||
edge.type = dv.ValueString();
|
||||
edge.type = std::move(dv.ValueString());
|
||||
|
||||
// read properties
|
||||
if (!ReadValue(&dv, Value::Type::Map)) {
|
||||
return false;
|
||||
}
|
||||
edge.properties = dv.ValueMap();
|
||||
|
||||
*data = Value(edge);
|
||||
edge.properties = std::move(dv.ValueMap());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadUnboundedEdge(Value *data) {
|
||||
Value dv;
|
||||
UnboundedEdge edge;
|
||||
*data = Value(UnboundedEdge());
|
||||
auto &edge = data->ValueUnboundedEdge();
|
||||
|
||||
// read ID
|
||||
if (!ReadValue(&dv, Value::Type::Int)) {
|
||||
@ -426,22 +420,21 @@ class Decoder {
|
||||
if (!ReadValue(&dv, Value::Type::String)) {
|
||||
return false;
|
||||
}
|
||||
edge.type = dv.ValueString();
|
||||
edge.type = std::move(dv.ValueString());
|
||||
|
||||
// read properties
|
||||
if (!ReadValue(&dv, Value::Type::Map)) {
|
||||
return false;
|
||||
}
|
||||
edge.properties = dv.ValueMap();
|
||||
|
||||
*data = Value(edge);
|
||||
edge.properties = std::move(dv.ValueMap());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadPath(Value *data) {
|
||||
Value dv;
|
||||
Path path;
|
||||
*data = Value(Path());
|
||||
auto &path = data->ValuePath();
|
||||
|
||||
// vertices
|
||||
if (!ReadValue(&dv, Value::Type::List)) {
|
||||
@ -451,7 +444,7 @@ class Decoder {
|
||||
if (vertex.type() != Value::Type::Vertex) {
|
||||
return false;
|
||||
}
|
||||
path.vertices.emplace_back(vertex.ValueVertex());
|
||||
path.vertices.emplace_back(std::move(vertex.ValueVertex()));
|
||||
}
|
||||
|
||||
// edges
|
||||
@ -462,7 +455,7 @@ class Decoder {
|
||||
if (edge.type() != Value::Type::UnboundedEdge) {
|
||||
return false;
|
||||
}
|
||||
path.edges.emplace_back(edge.ValueUnboundedEdge());
|
||||
path.edges.emplace_back(std::move(edge.ValueUnboundedEdge()));
|
||||
}
|
||||
|
||||
// indices
|
||||
@ -476,8 +469,6 @@ class Decoder {
|
||||
path.indices.emplace_back(index.ValueInt());
|
||||
}
|
||||
|
||||
*data = Value(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "communication/bolt/v1/value.hpp"
|
||||
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "utils/algorithm.hpp"
|
||||
|
||||
namespace communication::bolt {
|
||||
@ -78,7 +76,6 @@ Value::Value(const Value &other) : type_(other.type_) {
|
||||
new (&path_v) Path(other.path_v);
|
||||
return;
|
||||
}
|
||||
LOG(FATAL) << "Unsupported Value::Type";
|
||||
}
|
||||
|
||||
Value &Value::operator=(const Value &other) {
|
||||
@ -121,7 +118,96 @@ Value &Value::operator=(const Value &other) {
|
||||
new (&path_v) Path(other.path_v);
|
||||
return *this;
|
||||
}
|
||||
LOG(FATAL) << "Unsupported Value::Type";
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Value::Value(Value &&other) : type_(other.type_) {
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
break;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
break;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<Value>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) std::map<std::string, Value>(std::move(other.map_v));
|
||||
break;
|
||||
case Type::Vertex:
|
||||
new (&vertex_v) Vertex(std::move(other.vertex_v));
|
||||
break;
|
||||
case Type::Edge:
|
||||
new (&edge_v) Edge(std::move(other.edge_v));
|
||||
break;
|
||||
case Type::UnboundedEdge:
|
||||
new (&unbounded_edge_v) UnboundedEdge(std::move(other.unbounded_edge_v));
|
||||
break;
|
||||
case Type::Path:
|
||||
new (&path_v) Path(std::move(other.path_v));
|
||||
break;
|
||||
}
|
||||
|
||||
// reset the type of other
|
||||
other.~Value();
|
||||
other.type_ = Type::Null;
|
||||
}
|
||||
|
||||
Value &Value::operator=(Value &&other) {
|
||||
if (this != &other) {
|
||||
this->~Value();
|
||||
// set the type of this
|
||||
type_ = other.type_;
|
||||
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
break;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
break;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<Value>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) std::map<std::string, Value>(std::move(other.map_v));
|
||||
break;
|
||||
case Type::Vertex:
|
||||
new (&vertex_v) Vertex(std::move(other.vertex_v));
|
||||
break;
|
||||
case Type::Edge:
|
||||
new (&edge_v) Edge(std::move(other.edge_v));
|
||||
break;
|
||||
case Type::UnboundedEdge:
|
||||
new (&unbounded_edge_v)
|
||||
UnboundedEdge(std::move(other.unbounded_edge_v));
|
||||
break;
|
||||
case Type::Path:
|
||||
new (&path_v) Path(std::move(other.path_v));
|
||||
break;
|
||||
}
|
||||
|
||||
// reset the type of other
|
||||
other.~Value();
|
||||
other.type_ = Type::Null;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -164,7 +250,6 @@ Value::~Value() {
|
||||
path_v.~Path();
|
||||
return;
|
||||
}
|
||||
LOG(FATAL) << "Unsupported Value::Type";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Vertex &vertex) {
|
||||
@ -201,7 +286,6 @@ std::ostream &operator<<(std::ostream &os, const UnboundedEdge &edge) {
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Path &path) {
|
||||
os << path.vertices[0];
|
||||
DCHECK(path.indices.size() % 2 == 0) << "Must have even number of indices";
|
||||
for (auto it = path.indices.begin(); it != path.indices.end();) {
|
||||
auto edge_ind = *it++;
|
||||
auto vertex_ind = *it++;
|
||||
@ -252,7 +336,6 @@ std::ostream &operator<<(std::ostream &os, const Value &value) {
|
||||
case Value::Type::Path:
|
||||
return os << value.ValuePath();
|
||||
}
|
||||
LOG(FATAL) << "Unsupported Value::Type";
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Value::Type type) {
|
||||
@ -280,6 +363,5 @@ std::ostream &operator<<(std::ostream &os, const Value::Type type) {
|
||||
case Value::Type::Path:
|
||||
return os << "path";
|
||||
}
|
||||
LOG(FATAL) << "Unsupported Value::Type";
|
||||
}
|
||||
}
|
||||
|
@ -165,8 +165,33 @@ class Value {
|
||||
}
|
||||
Value(const Path &value) : type_(Type::Path) { new (&path_v) Path(value); }
|
||||
|
||||
// move constructors for non-primitive values
|
||||
Value(std::string &&value) : type_(Type::String) {
|
||||
new (&string_v) std::string(std::move(value));
|
||||
}
|
||||
Value(std::vector<Value> &&value) : type_(Type::List) {
|
||||
new (&list_v) std::vector<Value>(std::move(value));
|
||||
}
|
||||
Value(std::map<std::string, Value> &&value) : type_(Type::Map) {
|
||||
new (&map_v) std::map<std::string, Value>(std::move(value));
|
||||
}
|
||||
Value(Vertex &&value) : type_(Type::Vertex) {
|
||||
new (&vertex_v) Vertex(std::move(value));
|
||||
}
|
||||
Value(Edge &&value) : type_(Type::Edge) {
|
||||
new (&edge_v) Edge(std::move(value));
|
||||
}
|
||||
Value(UnboundedEdge &&value) : type_(Type::UnboundedEdge) {
|
||||
new (&unbounded_edge_v) UnboundedEdge(std::move(value));
|
||||
}
|
||||
Value(Path &&value) : type_(Type::Path) {
|
||||
new (&path_v) Path(std::move(value));
|
||||
}
|
||||
|
||||
Value &operator=(const Value &other);
|
||||
Value &operator=(Value &&other);
|
||||
Value(const Value &other);
|
||||
Value(Value &&other);
|
||||
~Value();
|
||||
|
||||
Type type() const { return type_; }
|
||||
|
Loading…
Reference in New Issue
Block a user