Refactor database::StateDelta

Summary:
Refactor in two ways. First, expose members without getters as we will
need most of them in distributed. And this was always the sensible thing
to do. Second, add storage type values to deltas. This is also a
sensible thing to do, and it will be very beneficial in distributed. We
didn't do it before because name<->value type mappings aren't guaranteed
to be the same after recovery. A task has been added to address this
(preserve mappings in durability).

Reviewers: dgleich, buda

Reviewed By: dgleich

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1167
This commit is contained in:
florijan 2018-02-02 10:34:09 +01:00
parent 583f6f1794
commit 1d5d67aeac
9 changed files with 220 additions and 182 deletions

View File

@ -219,9 +219,9 @@ void GraphDbAccessor::EnableIndex(const LabelPropertyIndex::Key &key) {
// built at this point even if this DBA's transaction aborts for some
// reason.
auto wal_build_index_tx_id = transaction_id();
wal().Emplace(database::StateDelta::BuildIndex(wal_build_index_tx_id,
LabelName(key.label_),
PropertyName(key.property_)));
wal().Emplace(database::StateDelta::BuildIndex(
wal_build_index_tx_id, key.label_, LabelName(key.label_), key.property_,
PropertyName(key.property_)));
// After these two operations we are certain that everything is contained in
// the index under the assumption that the original index creation transaction
@ -419,7 +419,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
// outcomes are success or error (serialization, timeout).
}
wal().Emplace(database::StateDelta::CreateEdge(
transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(),
transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type,
EdgeTypeName(edge_type)));
return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
edge_type);

View File

@ -6,12 +6,6 @@
namespace database {
std::pair<std::string, std::string> StateDelta::IndexName() const {
CHECK(StateDelta::type() == StateDelta::Type::BUILD_INDEX)
<< "Invalid operation type to try to get index name";
return std::make_pair(label_, property_);
}
StateDelta StateDelta::TxBegin(tx::transaction_id_t tx_id) {
return {StateDelta::Type::TRANSACTION_BEGIN, tx_id};
}
@ -27,128 +21,147 @@ StateDelta StateDelta::TxAbort(tx::transaction_id_t tx_id) {
StateDelta StateDelta::CreateVertex(tx::transaction_id_t tx_id,
gid::Gid vertex_id) {
StateDelta op(StateDelta::Type::CREATE_VERTEX, tx_id);
op.vertex_id_ = vertex_id;
op.vertex_id = vertex_id;
return op;
}
StateDelta StateDelta::CreateEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
gid::Gid vertex_from_id,
gid::Gid vertex_to_id,
const std::string &edge_type) {
storage::EdgeType edge_type,
const std::string &edge_type_name) {
StateDelta op(StateDelta::Type::CREATE_EDGE, tx_id);
op.edge_id_ = edge_id;
op.vertex_from_id_ = vertex_from_id;
op.vertex_to_id_ = vertex_to_id;
op.edge_type_ = edge_type;
op.edge_id = edge_id;
op.vertex_from_id = vertex_from_id;
op.vertex_to_id = vertex_to_id;
op.edge_type = edge_type;
op.edge_type_name = edge_type_name;
return op;
}
StateDelta StateDelta::PropsSetVertex(tx::transaction_id_t tx_id,
gid::Gid vertex_id,
const std::string &property,
storage::Property property,
const std::string &property_name,
const PropertyValue &value) {
StateDelta op(StateDelta::Type::SET_PROPERTY_VERTEX, tx_id);
op.vertex_id_ = vertex_id;
op.property_ = property;
op.value_ = value;
op.vertex_id = vertex_id;
op.property = property;
op.property_name = property_name;
op.value = value;
return op;
}
StateDelta StateDelta::PropsSetEdge(tx::transaction_id_t tx_id,
gid::Gid edge_id,
const std::string &property,
storage::Property property,
const std::string &property_name,
const PropertyValue &value) {
StateDelta op(StateDelta::Type::SET_PROPERTY_EDGE, tx_id);
op.edge_id_ = edge_id;
op.property_ = property;
op.value_ = value;
op.edge_id = edge_id;
op.property = property;
op.property_name = property_name;
op.value = value;
return op;
}
StateDelta StateDelta::AddLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
const std::string &label) {
storage::Label label,
const std::string &label_name) {
StateDelta op(StateDelta::Type::ADD_LABEL, tx_id);
op.vertex_id_ = vertex_id;
op.label_ = label;
op.vertex_id = vertex_id;
op.label = label;
op.label_name = label_name;
return op;
}
StateDelta StateDelta::RemoveLabel(tx::transaction_id_t tx_id,
gid::Gid vertex_id,
const std::string &label) {
gid::Gid vertex_id, storage::Label label,
const std::string &label_name) {
StateDelta op(StateDelta::Type::REMOVE_LABEL, tx_id);
op.vertex_id_ = vertex_id;
op.label_ = label;
op.vertex_id = vertex_id;
op.label = label;
op.label_name = label_name;
return op;
}
StateDelta StateDelta::RemoveVertex(tx::transaction_id_t tx_id,
gid::Gid vertex_id) {
StateDelta op(StateDelta::Type::REMOVE_VERTEX, tx_id);
op.vertex_id_ = vertex_id;
op.vertex_id = vertex_id;
return op;
}
StateDelta StateDelta::RemoveEdge(tx::transaction_id_t tx_id,
gid::Gid edge_id) {
StateDelta op(StateDelta::Type::REMOVE_EDGE, tx_id);
op.edge_id_ = edge_id;
op.edge_id = edge_id;
return op;
}
StateDelta StateDelta::BuildIndex(tx::transaction_id_t tx_id,
const std::string &label,
const std::string &property) {
storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name) {
StateDelta op(StateDelta::Type::BUILD_INDEX, tx_id);
op.label_ = label;
op.property_ = property;
op.label = label;
op.label_name = label_name;
op.property = property;
op.property_name = property_name;
return op;
}
void StateDelta::Encode(
HashedFileWriter &writer,
communication::bolt::PrimitiveEncoder<HashedFileWriter> &encoder) const {
encoder.WriteInt(static_cast<int64_t>(type_));
encoder.WriteInt(static_cast<int64_t>(transaction_id_));
encoder.WriteInt(static_cast<int64_t>(type));
encoder.WriteInt(static_cast<int64_t>(transaction_id));
switch (type_) {
switch (type) {
case Type::TRANSACTION_BEGIN:
case Type::TRANSACTION_COMMIT:
case Type::TRANSACTION_ABORT:
break;
case Type::CREATE_VERTEX:
encoder.WriteInt(vertex_id_);
encoder.WriteInt(vertex_id);
break;
case Type::CREATE_EDGE:
encoder.WriteInt(edge_id_);
encoder.WriteInt(vertex_from_id_);
encoder.WriteInt(vertex_to_id_);
encoder.WriteString(edge_type_);
encoder.WriteInt(edge_id);
encoder.WriteInt(vertex_from_id);
encoder.WriteInt(vertex_to_id);
encoder.WriteInt(edge_type.storage());
encoder.WriteString(edge_type_name);
break;
case Type::SET_PROPERTY_VERTEX:
encoder.WriteInt(vertex_id_);
encoder.WriteString(property_);
encoder.WritePropertyValue(value_);
encoder.WriteInt(vertex_id);
encoder.WriteInt(property.storage());
encoder.WriteString(property_name);
encoder.WritePropertyValue(value);
break;
case Type::SET_PROPERTY_EDGE:
encoder.WriteInt(edge_id_);
encoder.WriteString(property_);
encoder.WritePropertyValue(value_);
encoder.WriteInt(edge_id);
encoder.WriteInt(property.storage());
encoder.WriteString(property_name);
encoder.WritePropertyValue(value);
break;
case Type::ADD_LABEL:
case Type::REMOVE_LABEL:
encoder.WriteInt(vertex_id_);
encoder.WriteString(label_);
encoder.WriteInt(vertex_id);
encoder.WriteInt(label.storage());
encoder.WriteString(label_name);
break;
case Type::REMOVE_VERTEX:
encoder.WriteInt(vertex_id_);
encoder.WriteInt(vertex_id);
break;
case Type::REMOVE_EDGE:
encoder.WriteInt(edge_id_);
encoder.WriteInt(edge_id);
break;
case Type::BUILD_INDEX:
encoder.WriteString(label_);
encoder.WriteString(property_);
encoder.WriteInt(label.storage());
encoder.WriteString(label_name);
encoder.WriteInt(property.storage());
encoder.WriteString(property_name);
break;
}
@ -159,6 +172,10 @@ void StateDelta::Encode(
if (!decoder.ReadValue(&dv)) return nullopt; \
r_val.member = dv.value_f();
#define DECODE_MEMBER_CAST(member, value_f, type) \
if (!decoder.ReadValue(&dv)) return nullopt; \
r_val.member = static_cast<type>(dv.value_f());
std::experimental::optional<StateDelta> StateDelta::Decode(
HashedFileReader &reader,
communication::bolt::Decoder<HashedFileReader> &decoder) {
@ -170,49 +187,55 @@ std::experimental::optional<StateDelta> StateDelta::Decode(
try {
if (!decoder.ReadValue(&dv)) return nullopt;
r_val.type_ = static_cast<enum StateDelta::Type>(dv.ValueInt());
DECODE_MEMBER(transaction_id_, ValueInt)
r_val.type = static_cast<enum StateDelta::Type>(dv.ValueInt());
DECODE_MEMBER(transaction_id, ValueInt)
switch (r_val.type_) {
switch (r_val.type) {
case Type::TRANSACTION_BEGIN:
case Type::TRANSACTION_COMMIT:
case Type::TRANSACTION_ABORT:
break;
case Type::CREATE_VERTEX:
DECODE_MEMBER(vertex_id_, ValueInt)
DECODE_MEMBER(vertex_id, ValueInt)
break;
case Type::CREATE_EDGE:
DECODE_MEMBER(edge_id_, ValueInt)
DECODE_MEMBER(vertex_from_id_, ValueInt)
DECODE_MEMBER(vertex_to_id_, ValueInt)
DECODE_MEMBER(edge_type_, ValueString)
DECODE_MEMBER(edge_id, ValueInt)
DECODE_MEMBER(vertex_from_id, ValueInt)
DECODE_MEMBER(vertex_to_id, ValueInt)
DECODE_MEMBER_CAST(edge_type, ValueInt, storage::EdgeType)
DECODE_MEMBER(edge_type_name, ValueString)
break;
case Type::SET_PROPERTY_VERTEX:
DECODE_MEMBER(vertex_id_, ValueInt)
DECODE_MEMBER(property_, ValueString)
DECODE_MEMBER(vertex_id, ValueInt)
DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
DECODE_MEMBER(property_name, ValueString)
if (!decoder.ReadValue(&dv)) return nullopt;
r_val.value_ = static_cast<PropertyValue>(dv);
r_val.value = static_cast<PropertyValue>(dv);
break;
case Type::SET_PROPERTY_EDGE:
DECODE_MEMBER(edge_id_, ValueInt)
DECODE_MEMBER(property_, ValueString)
DECODE_MEMBER(edge_id, ValueInt)
DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
DECODE_MEMBER(property_name, ValueString)
if (!decoder.ReadValue(&dv)) return nullopt;
r_val.value_ = static_cast<PropertyValue>(dv);
r_val.value = static_cast<PropertyValue>(dv);
break;
case Type::ADD_LABEL:
case Type::REMOVE_LABEL:
DECODE_MEMBER(vertex_id_, ValueInt)
DECODE_MEMBER(label_, ValueString)
DECODE_MEMBER(vertex_id, ValueInt)
DECODE_MEMBER_CAST(label, ValueInt, storage::Label)
DECODE_MEMBER(label_name, ValueString)
break;
case Type::REMOVE_VERTEX:
DECODE_MEMBER(vertex_id_, ValueInt)
DECODE_MEMBER(vertex_id, ValueInt)
break;
case Type::REMOVE_EDGE:
DECODE_MEMBER(edge_id_, ValueInt)
DECODE_MEMBER(edge_id, ValueInt)
break;
case Type::BUILD_INDEX:
DECODE_MEMBER(label_, ValueString)
DECODE_MEMBER(property_, ValueString)
DECODE_MEMBER_CAST(label, ValueInt, storage::Label)
DECODE_MEMBER(label_name, ValueString)
DECODE_MEMBER_CAST(property, ValueInt, storage::Property)
DECODE_MEMBER(property_name, ValueString)
break;
}
@ -232,7 +255,7 @@ std::experimental::optional<StateDelta> StateDelta::Decode(
#undef DECODE_MEMBER
void StateDelta::Apply(GraphDbAccessor &dba) const {
switch (type_) {
switch (type) {
// Transactional state is not recovered.
case Type::TRANSACTION_BEGIN:
case Type::TRANSACTION_COMMIT:
@ -240,48 +263,48 @@ void StateDelta::Apply(GraphDbAccessor &dba) const {
LOG(FATAL) << "Transaction handling not handled in Apply";
break;
case Type::CREATE_VERTEX:
dba.InsertVertex(vertex_id_);
dba.InsertVertex(vertex_id);
break;
case Type::CREATE_EDGE: {
auto from = dba.FindVertex(vertex_from_id_, true);
auto to = dba.FindVertex(vertex_to_id_, true);
auto from = dba.FindVertex(vertex_from_id, true);
auto to = dba.FindVertex(vertex_to_id, true);
DCHECK(from) << "Failed to find vertex.";
DCHECK(to) << "Failed to find vertex.";
dba.InsertEdge(*from, *to, dba.EdgeType(edge_type_), edge_id_);
dba.InsertEdge(*from, *to, dba.EdgeType(edge_type_name), edge_id);
break;
}
case Type::SET_PROPERTY_VERTEX: {
auto vertex = dba.FindVertex(vertex_id_, true);
auto vertex = dba.FindVertex(vertex_id, true);
DCHECK(vertex) << "Failed to find vertex.";
vertex->PropsSet(dba.Property(property_), value_);
vertex->PropsSet(dba.Property(property_name), value);
break;
}
case Type::SET_PROPERTY_EDGE: {
auto edge = dba.FindEdge(edge_id_, true);
auto edge = dba.FindEdge(edge_id, true);
DCHECK(edge) << "Failed to find edge.";
edge->PropsSet(dba.Property(property_), value_);
edge->PropsSet(dba.Property(property_name), value);
break;
}
case Type::ADD_LABEL: {
auto vertex = dba.FindVertex(vertex_id_, true);
auto vertex = dba.FindVertex(vertex_id, true);
DCHECK(vertex) << "Failed to find vertex.";
vertex->add_label(dba.Label(label_));
vertex->add_label(dba.Label(label_name));
break;
}
case Type::REMOVE_LABEL: {
auto vertex = dba.FindVertex(vertex_id_, true);
auto vertex = dba.FindVertex(vertex_id, true);
DCHECK(vertex) << "Failed to find vertex.";
vertex->remove_label(dba.Label(label_));
vertex->remove_label(dba.Label(label_name));
break;
}
case Type::REMOVE_VERTEX: {
auto vertex = dba.FindVertex(vertex_id_, true);
auto vertex = dba.FindVertex(vertex_id, true);
DCHECK(vertex) << "Failed to find vertex.";
dba.DetachRemoveVertex(*vertex);
break;
}
case Type::REMOVE_EDGE: {
auto edge = dba.FindEdge(edge_id_, true);
auto edge = dba.FindEdge(edge_id, true);
DCHECK(edge) << "Failed to find edge.";
dba.RemoveEdge(*edge);
break;

View File

@ -10,9 +10,16 @@
namespace database {
/** Describes single change to the database state. Used for durability (WAL) and
* state communication over network in HA and for distributed remote storage
* changes*/
class StateDelta {
public:
* changes.
*
* Labels, Properties and EdgeTypes are stored both as values (integers) and
* strings (their names). The values are used when applying deltas in a running
* database. Names are used when recovering the database as it's not guaranteed
* that after recovery the old name<->value mapping will be preserved.
*
* TODO: ensure the mapping is preserved after recovery and don't save strings
* in StateDeltas. */
struct StateDelta {
/** Defines StateDelta type. For each type the comment indicates which values
* need to be stored. All deltas have the transaction_id member, so that's
* omitted in the comment. */
@ -21,20 +28,21 @@ class StateDelta {
TRANSACTION_COMMIT,
TRANSACTION_ABORT,
CREATE_VERTEX, // vertex_id
CREATE_EDGE, // edge_id, from_vertex_id, to_vertex_id, edge_type
SET_PROPERTY_VERTEX, // vertex_id, property, property_value
SET_PROPERTY_EDGE, // edge_id, property, property_value
CREATE_EDGE, // edge_id, from_vertex_id, to_vertex_id, edge_type,
// edge_type_name
SET_PROPERTY_VERTEX, // vertex_id, property, property_name, property_value
SET_PROPERTY_EDGE, // edge_id, property, property_name, property_value
// remove property is done by setting a PropertyValue::Null
ADD_LABEL, // vertex_id, label
REMOVE_LABEL, // vertex_id, label
ADD_LABEL, // vertex_id, label, label_name
REMOVE_LABEL, // vertex_id, label, label_name
REMOVE_VERTEX, // vertex_id
REMOVE_EDGE, // edge_id
BUILD_INDEX // label, property
BUILD_INDEX // label, label_name, property, property_name
};
StateDelta() = default;
StateDelta(const enum Type &type, tx::transaction_id_t tx_id)
: type_(type), transaction_id_(tx_id) {}
: type(type), transaction_id(tx_id) {}
/** Attempts to decode a StateDelta from the given decoder. Returns the
* decoded value if successful, otherwise returns nullopt. */
@ -48,9 +56,6 @@ class StateDelta {
HashedFileWriter &writer,
communication::bolt::PrimitiveEncoder<HashedFileWriter> &encoder) const;
tx::transaction_id_t transaction_id() const { return transaction_id_; }
Type type() const { return type_; }
static StateDelta TxBegin(tx::transaction_id_t tx_id);
static StateDelta TxCommit(tx::transaction_id_t tx_id);
static StateDelta TxAbort(tx::transaction_id_t tx_id);
@ -58,43 +63,49 @@ class StateDelta {
gid::Gid vertex_id);
static StateDelta CreateEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
gid::Gid vertex_from_id, gid::Gid vertex_to_id,
const std::string &edge_type);
storage::EdgeType edge_type,
const std::string &edge_type_name);
static StateDelta PropsSetVertex(tx::transaction_id_t tx_id,
gid::Gid vertex_id,
const std::string &property,
storage::Property property,
const std::string &property_name,
const PropertyValue &value);
static StateDelta PropsSetEdge(tx::transaction_id_t tx_id, gid::Gid edge_id,
const std::string &property,
storage::Property property,
const std::string &property_name,
const PropertyValue &value);
static StateDelta AddLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
const std::string &label);
storage::Label label,
const std::string &label_name);
static StateDelta RemoveLabel(tx::transaction_id_t tx_id, gid::Gid vertex_id,
const std::string &label);
storage::Label label,
const std::string &label_name);
static StateDelta RemoveVertex(tx::transaction_id_t tx_id,
gid::Gid vertex_id);
static StateDelta RemoveEdge(tx::transaction_id_t tx_id, gid::Gid edge_id);
static StateDelta BuildIndex(tx::transaction_id_t tx_id,
const std::string &label,
const std::string &property);
std::pair<std::string, std::string> IndexName() const;
static StateDelta BuildIndex(tx::transaction_id_t tx_id, storage::Label label,
const std::string &label_name,
storage::Property property,
const std::string &property_name);
/// Applies CRUD delta to database accessor. Fails on other types of deltas
void Apply(GraphDbAccessor &dba) const;
private:
// Members valid for every delta.
enum Type type_;
tx::transaction_id_t transaction_id_;
enum Type type;
tx::transaction_id_t transaction_id;
// Members valid only for some deltas, see StateDelta::Type comments above.
gid::Gid vertex_id_;
gid::Gid edge_id_;
gid::Gid vertex_from_id_;
gid::Gid vertex_to_id_;
std::string edge_type_;
std::string property_;
PropertyValue value_ = PropertyValue::Null;
std::string label_;
gid::Gid vertex_id;
gid::Gid edge_id;
gid::Gid vertex_from_id;
gid::Gid vertex_to_id;
storage::EdgeType edge_type;
std::string edge_type_name;
storage::Property property;
std::string property_name;
PropertyValue value = PropertyValue::Null;
storage::Label label;
std::string label_name;
};
} // namespace database

View File

@ -272,27 +272,28 @@ bool RecoverWal(const fs::path &wal_dir, database::GraphDb &db,
while (true) {
auto delta = database::StateDelta::Decode(wal_reader, decoder);
if (!delta) break;
if (should_skip(delta->transaction_id())) continue;
switch (delta->type()) {
if (should_skip(delta->transaction_id)) continue;
switch (delta->type) {
case database::StateDelta::Type::TRANSACTION_BEGIN:
DCHECK(accessors.find(delta->transaction_id()) == accessors.end())
DCHECK(accessors.find(delta->transaction_id) == accessors.end())
<< "Double transaction start";
accessors.emplace(delta->transaction_id(), db);
accessors.emplace(delta->transaction_id, db);
break;
case database::StateDelta::Type::TRANSACTION_ABORT:
get_accessor(delta->transaction_id()).Abort();
accessors.erase(accessors.find(delta->transaction_id()));
get_accessor(delta->transaction_id).Abort();
accessors.erase(accessors.find(delta->transaction_id));
break;
case database::StateDelta::Type::TRANSACTION_COMMIT:
get_accessor(delta->transaction_id()).Commit();
accessors.erase(accessors.find(delta->transaction_id()));
get_accessor(delta->transaction_id).Commit();
accessors.erase(accessors.find(delta->transaction_id));
break;
case database::StateDelta::Type::BUILD_INDEX:
// TODO index building might still be problematic in HA
recovery_data.indexes.emplace_back(delta->IndexName());
recovery_data.indexes.emplace_back(delta->label_name,
delta->property_name);
break;
default:
delta->Apply(get_accessor(delta->transaction_id()));
delta->Apply(get_accessor(delta->transaction_id));
}
} // reading all deltas in a single wal file
} // reading all wal files

View File

@ -74,7 +74,7 @@ void WriteAheadLog::WalFile::Flush(RingBuffer<database::StateDelta> &buffer) {
while (true) {
auto delta = buffer.pop();
if (!delta) break;
latest_tx_ = std::max(latest_tx_, delta->transaction_id());
latest_tx_ = std::max(latest_tx_, delta->transaction_id);
delta->Encode(writer_, encoder_);
if (++current_wal_file_delta_count_ >= FLAGS_wal_rotate_deltas_count)
RotateFile();

View File

@ -25,7 +25,7 @@ void RecordAccessor<Vertex>::PropsSet(storage::Property key,
vertex.properties_.set(key, value);
auto &dba = db_accessor();
// TODO use the delta for handling.
dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(),
dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
dba.PropertyName(key), value));
if (is_local()) {
db_accessor().UpdatePropertyIndex(key, *this, &vertex);
@ -38,7 +38,7 @@ void RecordAccessor<Edge>::PropsSet(storage::Property key,
update().properties_.set(key, value);
auto &dba = db_accessor();
// TODO use the delta for handling.
dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(),
dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(), key,
dba.PropertyName(key), value));
}
@ -46,8 +46,9 @@ template <>
size_t RecordAccessor<Vertex>::PropsErase(storage::Property key) {
auto &dba = db_accessor();
// TODO use the delta for handling.
dba.wal().Emplace(StateDelta::PropsSetVertex(
dba.transaction_id(), gid(), dba.PropertyName(key), PropertyValue::Null));
dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
dba.PropertyName(key),
PropertyValue::Null));
return update().properties_.erase(key);
}
@ -55,8 +56,9 @@ template <>
size_t RecordAccessor<Edge>::PropsErase(storage::Property key) {
auto &dba = db_accessor();
// TODO use the delta for handling.
dba.wal().Emplace(StateDelta::PropsSetEdge(
dba.transaction_id(), gid(), dba.PropertyName(key), PropertyValue::Null));
dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(), key,
dba.PropertyName(key),
PropertyValue::Null));
return update().properties_.erase(key);
}
@ -66,9 +68,9 @@ void RecordAccessor<Vertex>::PropsClear() {
// TODO use the delta for handling.
auto &dba = db_accessor();
for (const auto &kv : updated.properties_)
dba.wal().Emplace(StateDelta::PropsSetVertex(dba.transaction_id(), gid(),
dba.PropertyName(kv.first),
PropertyValue::Null));
dba.wal().Emplace(StateDelta::PropsSetVertex(
dba.transaction_id(), gid(), kv.first, dba.PropertyName(kv.first),
PropertyValue::Null));
updated.properties_.clear();
}
@ -78,9 +80,9 @@ void RecordAccessor<Edge>::PropsClear() {
auto &dba = db_accessor();
// TODO use the delta for handling.
for (const auto &kv : updated.properties_)
dba.wal().Emplace(StateDelta::PropsSetEdge(dba.transaction_id(), gid(),
dba.PropertyName(kv.first),
PropertyValue::Null));
dba.wal().Emplace(StateDelta::PropsSetEdge(
dba.transaction_id(), gid(), kv.first, dba.PropertyName(kv.first),
PropertyValue::Null));
updated.properties_.clear();
}

View File

@ -20,8 +20,8 @@ bool VertexAccessor::add_label(storage::Label label) {
auto &dba = db_accessor();
dba.UpdateLabelIndices(label, *this, &vertex);
// TODO support distributed.
dba.wal().Emplace(database::StateDelta::AddLabel(dba.transaction_id(), gid(),
dba.LabelName(label)));
dba.wal().Emplace(database::StateDelta::AddLabel(
dba.transaction_id(), gid(), label, dba.LabelName(label)));
return true;
}
@ -35,7 +35,7 @@ size_t VertexAccessor::remove_label(storage::Label label) {
auto &dba = db_accessor();
// TODO support distributed.
dba.wal().Emplace(database::StateDelta::RemoveLabel(
dba.transaction_id(), gid(), dba.LabelName(label)));
dba.transaction_id(), gid(), label, dba.LabelName(label)));
return 1;
}

View File

@ -357,29 +357,28 @@ TEST_F(Durability, WalEncoding) {
ASSERT_EQ(deltas.size(), 11);
using Type = enum database::StateDelta::Type;
EXPECT_EQ(deltas[0].type(), Type::TRANSACTION_BEGIN);
EXPECT_EQ(deltas[0].transaction_id(), 1);
EXPECT_EQ(deltas[1].type(), Type::CREATE_VERTEX);
EXPECT_EQ(deltas[1].transaction_id(), 1);
EXPECT_EQ(deltas[2].type(), Type::ADD_LABEL);
EXPECT_EQ(deltas[2].transaction_id(), 1);
EXPECT_EQ(deltas[3].type(), Type::SET_PROPERTY_VERTEX);
EXPECT_EQ(deltas[3].transaction_id(), 1);
EXPECT_EQ(deltas[4].type(), Type::CREATE_VERTEX);
EXPECT_EQ(deltas[4].transaction_id(), 1);
EXPECT_EQ(deltas[5].type(), Type::CREATE_EDGE);
EXPECT_EQ(deltas[5].transaction_id(), 1);
EXPECT_EQ(deltas[6].type(), Type::SET_PROPERTY_EDGE);
EXPECT_EQ(deltas[6].transaction_id(), 1);
EXPECT_EQ(deltas[0].type, Type::TRANSACTION_BEGIN);
EXPECT_EQ(deltas[0].transaction_id, 1);
EXPECT_EQ(deltas[1].type, Type::CREATE_VERTEX);
EXPECT_EQ(deltas[1].transaction_id, 1);
EXPECT_EQ(deltas[2].type, Type::ADD_LABEL);
EXPECT_EQ(deltas[2].transaction_id, 1);
EXPECT_EQ(deltas[3].type, Type::SET_PROPERTY_VERTEX);
EXPECT_EQ(deltas[3].transaction_id, 1);
EXPECT_EQ(deltas[4].type, Type::CREATE_VERTEX);
EXPECT_EQ(deltas[4].transaction_id, 1);
EXPECT_EQ(deltas[5].type, Type::CREATE_EDGE);
EXPECT_EQ(deltas[5].transaction_id, 1);
EXPECT_EQ(deltas[6].type, Type::SET_PROPERTY_EDGE);
EXPECT_EQ(deltas[6].transaction_id, 1);
// The next two deltas are the BuildIndex internal transactions.
EXPECT_EQ(deltas[7].type(), Type::TRANSACTION_BEGIN);
EXPECT_EQ(deltas[8].type(), Type::BUILD_INDEX);
auto index_name = deltas[8].IndexName();
EXPECT_EQ(index_name.first, "l1");
EXPECT_EQ(index_name.second, "p1");
EXPECT_EQ(deltas[9].type(), Type::TRANSACTION_COMMIT);
EXPECT_EQ(deltas[10].type(), Type::TRANSACTION_COMMIT);
EXPECT_EQ(deltas[10].transaction_id(), 1);
EXPECT_EQ(deltas[7].type, Type::TRANSACTION_BEGIN);
EXPECT_EQ(deltas[8].type, Type::BUILD_INDEX);
EXPECT_EQ(deltas[8].label_name, "l1");
EXPECT_EQ(deltas[8].property_name, "p1");
EXPECT_EQ(deltas[9].type, Type::TRANSACTION_COMMIT);
EXPECT_EQ(deltas[10].type, Type::TRANSACTION_COMMIT);
EXPECT_EQ(deltas[10].transaction_id, 1);
}
TEST_F(Durability, SnapshotEncoding) {

View File

@ -57,8 +57,8 @@ TEST(StateDelta, CreateEdge) {
}
{
database::GraphDbAccessor dba(db);
auto delta = database::StateDelta::CreateEdge(dba.transaction_id(), gid2,
gid0, gid1, "edge");
auto delta = database::StateDelta::CreateEdge(
dba.transaction_id(), gid2, gid0, gid1, dba.EdgeType("edge"), "edge");
delta.Apply(dba);
dba.Commit();
}
@ -106,8 +106,8 @@ TEST(StateDelta, AddLabel) {
}
{
database::GraphDbAccessor dba(db);
auto delta =
database::StateDelta::AddLabel(dba.transaction_id(), gid0, "label");
auto delta = database::StateDelta::AddLabel(dba.transaction_id(), gid0,
dba.Label("label"), "label");
delta.Apply(dba);
dba.Commit();
}
@ -133,8 +133,8 @@ TEST(StateDelta, RemoveLabel) {
}
{
database::GraphDbAccessor dba(db);
auto delta =
database::StateDelta::RemoveLabel(dba.transaction_id(), gid0, "label");
auto delta = database::StateDelta::RemoveLabel(dba.transaction_id(), gid0,
dba.Label("label"), "label");
delta.Apply(dba);
dba.Commit();
}
@ -159,7 +159,8 @@ TEST(StateDelta, SetPropertyVertex) {
{
database::GraphDbAccessor dba(db);
auto delta = database::StateDelta::PropsSetVertex(
dba.transaction_id(), gid0, "property", PropertyValue(2212));
dba.transaction_id(), gid0, dba.Property("property"), "property",
PropertyValue(2212));
delta.Apply(dba);
dba.Commit();
}
@ -188,7 +189,8 @@ TEST(StateDelta, SetPropertyEdge) {
{
database::GraphDbAccessor dba(db);
auto delta = database::StateDelta::PropsSetEdge(
dba.transaction_id(), gid2, "property", PropertyValue(2212));
dba.transaction_id(), gid2, dba.Property("property"), "property",
PropertyValue(2212));
delta.Apply(dba);
dba.Commit();
}