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:
Matej Ferencevic 2018-09-25 16:01:58 +02:00
parent e67fc40743
commit 9980f899c9
4 changed files with 146 additions and 48 deletions
src/communication/bolt

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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";
}
}

View File

@ -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_; }