Serialize storage and durability via SLK
Reviewers: mferencevic, msantl, ipaljak Reviewed By: mferencevic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1759
This commit is contained in:
parent
e70ac03607
commit
f5b39cfc41
@ -152,6 +152,7 @@ set(mg_distributed_sources
|
||||
storage/common/locking/record_lock.cpp
|
||||
storage/common/types/property_value.cpp
|
||||
storage/common/types/property_value_store.cpp
|
||||
storage/common/types/slk.cpp
|
||||
storage/distributed/edge_accessor.cpp
|
||||
storage/distributed/record_accessor.cpp
|
||||
storage/distributed/rpc/serialization.cpp
|
||||
@ -275,6 +276,7 @@ set(mg_single_node_ha_sources
|
||||
query/repl.cpp
|
||||
query/typed_value.cpp
|
||||
storage/common/types/property_value.cpp
|
||||
storage/common/types/slk.cpp
|
||||
storage/common/types/property_value_store.cpp
|
||||
storage/common/locking/record_lock.cpp
|
||||
storage/single_node_ha/edge_accessor.cpp
|
||||
|
@ -171,6 +171,6 @@ omitted in the comment.")
|
||||
/// Applies CRUD delta to database accessor. Fails on other types of deltas
|
||||
void Apply(GraphDbAccessor &dba) const;
|
||||
cpp<#)
|
||||
(:serialize (:capnp)))
|
||||
(:serialize (:slk) (:capnp)))
|
||||
|
||||
(lcp:pop-namespace) ;; database
|
||||
|
@ -153,6 +153,6 @@ omitted in the comment.")
|
||||
/// Applies CRUD delta to database accessor. Fails on other types of deltas
|
||||
void Apply(GraphDbAccessor &dba) const;
|
||||
cpp<#)
|
||||
(:serialize (:capnp)))
|
||||
(:serialize (:slk) (:capnp)))
|
||||
|
||||
(lcp:pop-namespace) ;; database
|
||||
|
@ -14,6 +14,6 @@ cpp<#
|
||||
|
||||
(lcp:define-struct log-entry ()
|
||||
((deltas "std::vector<database::StateDelta>" :capnp-type "List(Database.StateDelta)"))
|
||||
(:serialize (:capnp)))
|
||||
(:serialize (:slk) (:capnp)))
|
||||
|
||||
(lcp:pop-namespace) ;; raft
|
||||
|
@ -1,109 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/rpc/serialization.hpp"
|
||||
#include "communication/rpc/streams.hpp"
|
||||
#include "storage/common/types/property_value.hpp"
|
||||
|
||||
namespace slk {
|
||||
inline void Save(const PropertyValue &obj, Builder *builder) {
|
||||
switch (obj.type()) {
|
||||
case PropertyValue::Type::Null: {
|
||||
uint8_t type = 0;
|
||||
Save(type, builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::Bool: {
|
||||
uint8_t type = 1;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<bool>(), builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::Int: {
|
||||
uint8_t type = 2;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<int64_t>(), builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::Double: {
|
||||
uint8_t type = 3;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<double>(), builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::String: {
|
||||
uint8_t type = 4;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<std::string>(), builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::List: {
|
||||
uint8_t type = 5;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<std::vector<PropertyValue>>(), builder);
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::Map: {
|
||||
uint8_t type = 6;
|
||||
Save(type, builder);
|
||||
Save(obj.Value<std::map<std::string, PropertyValue>>(), builder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Load(PropertyValue *obj, Reader *reader) {
|
||||
uint8_t type = 0;
|
||||
Load(&type, reader);
|
||||
switch (type) {
|
||||
// Null
|
||||
case 0: {
|
||||
*obj = PropertyValue();
|
||||
return;
|
||||
}
|
||||
// Bool
|
||||
case 1: {
|
||||
bool value = false;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(value);
|
||||
return;
|
||||
}
|
||||
// Int
|
||||
case 2: {
|
||||
int64_t value = 0;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(value);
|
||||
return;
|
||||
}
|
||||
// Double
|
||||
case 3: {
|
||||
double value = 0.0;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(value);
|
||||
return;
|
||||
}
|
||||
// String
|
||||
case 4: {
|
||||
std::string value;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(std::move(value));
|
||||
return;
|
||||
}
|
||||
// List
|
||||
case 5: {
|
||||
std::vector<PropertyValue> value;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(std::move(value));
|
||||
return;
|
||||
}
|
||||
// Map
|
||||
case 6: {
|
||||
std::map<std::string, PropertyValue> value;
|
||||
Load(&value, reader);
|
||||
*obj = PropertyValue(std::move(value));
|
||||
return;
|
||||
}
|
||||
// Invalid type
|
||||
default: { throw SlkDecodeException("Couldn't load property value!"); }
|
||||
}
|
||||
}
|
||||
} // namespace slk
|
126
src/storage/common/types/slk.cpp
Normal file
126
src/storage/common/types/slk.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "storage/common/types/slk.hpp"
|
||||
|
||||
namespace slk {
|
||||
|
||||
void Save(const PropertyValue &value, slk::Builder *builder) {
|
||||
switch (value.type()) {
|
||||
case PropertyValue::Type::Null:
|
||||
slk::Save(static_cast<uint8_t>(0), builder);
|
||||
return;
|
||||
case PropertyValue::Type::Bool:
|
||||
slk::Save(static_cast<uint8_t>(1), builder);
|
||||
slk::Save(value.Value<bool>(), builder);
|
||||
return;
|
||||
case PropertyValue::Type::Int:
|
||||
slk::Save(static_cast<uint8_t>(2), builder);
|
||||
slk::Save(value.Value<int64_t>(), builder);
|
||||
return;
|
||||
case PropertyValue::Type::Double:
|
||||
slk::Save(static_cast<uint8_t>(3), builder);
|
||||
slk::Save(value.Value<double>(), builder);
|
||||
return;
|
||||
case PropertyValue::Type::String:
|
||||
slk::Save(static_cast<uint8_t>(4), builder);
|
||||
slk::Save(value.Value<std::string>(), builder);
|
||||
return;
|
||||
case PropertyValue::Type::List: {
|
||||
slk::Save(static_cast<uint8_t>(5), builder);
|
||||
const auto &values = value.Value<std::vector<PropertyValue>>();
|
||||
size_t size = values.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &v : values) {
|
||||
slk::Save(v, builder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case PropertyValue::Type::Map: {
|
||||
slk::Save(static_cast<uint8_t>(6), builder);
|
||||
const auto &map = value.Value<std::map<std::string, PropertyValue>>();
|
||||
size_t size = map.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &kv : map) {
|
||||
slk::Save(kv, builder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load(PropertyValue *value, slk::Reader *reader) {
|
||||
uint8_t type;
|
||||
slk::Load(&type, reader);
|
||||
switch (type) {
|
||||
case static_cast<uint8_t>(0):
|
||||
*value = PropertyValue::Null;
|
||||
return;
|
||||
case static_cast<uint8_t>(1): {
|
||||
bool v;
|
||||
slk::Load(&v, reader);
|
||||
*value = v;
|
||||
return;
|
||||
}
|
||||
case static_cast<uint8_t>(2): {
|
||||
int64_t v;
|
||||
slk::Load(&v, reader);
|
||||
*value = v;
|
||||
return;
|
||||
}
|
||||
case static_cast<uint8_t>(3): {
|
||||
double v;
|
||||
slk::Load(&v, reader);
|
||||
*value = v;
|
||||
return;
|
||||
}
|
||||
case static_cast<uint8_t>(4): {
|
||||
std::string v;
|
||||
slk::Load(&v, reader);
|
||||
*value = std::move(v);
|
||||
return;
|
||||
}
|
||||
case static_cast<uint8_t>(5): {
|
||||
size_t size;
|
||||
slk::Load(&size, reader);
|
||||
std::vector<PropertyValue> list(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
slk::Load(&list[i], reader);
|
||||
}
|
||||
*value = std::move(list);
|
||||
return;
|
||||
}
|
||||
case static_cast<uint8_t>(6): {
|
||||
size_t size;
|
||||
slk::Load(&size, reader);
|
||||
std::map<std::string, PropertyValue> map;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
std::pair<std::string, PropertyValue> kv;
|
||||
slk::Load(&kv, reader);
|
||||
map.insert(kv);
|
||||
}
|
||||
*value = std::move(map);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw slk::SlkDecodeException("Trying to load unknown PropertyValue!");
|
||||
}
|
||||
}
|
||||
|
||||
void Save(const PropertyValueStore &properties, slk::Builder *builder) {
|
||||
size_t size = properties.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &kv : properties) {
|
||||
slk::Save(kv, builder);
|
||||
}
|
||||
}
|
||||
|
||||
void Load(PropertyValueStore *properties, slk::Reader *reader) {
|
||||
properties->clear();
|
||||
size_t size;
|
||||
slk::Load(&size, reader);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
std::pair<storage::Property, PropertyValue> kv;
|
||||
slk::Load(&kv, reader);
|
||||
properties->set(kv.first, kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace slk
|
42
src/storage/common/types/slk.hpp
Normal file
42
src/storage/common/types/slk.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/rpc/serialization.hpp"
|
||||
#include "communication/rpc/streams.hpp"
|
||||
#include "storage/common/types/property_value.hpp"
|
||||
#include "storage/common/types/property_value_store.hpp"
|
||||
#include "storage/common/types/types.hpp"
|
||||
|
||||
namespace slk {
|
||||
|
||||
inline void Save(const storage::Label &common, slk::Builder *builder) {
|
||||
slk::Save(common.id_, builder);
|
||||
}
|
||||
|
||||
inline void Load(storage::Label *common, slk::Reader *reader) {
|
||||
slk::Load(&common->id_, reader);
|
||||
}
|
||||
|
||||
inline void Save(const storage::EdgeType &common, slk::Builder *builder) {
|
||||
slk::Save(common.id_, builder);
|
||||
}
|
||||
|
||||
inline void Load(storage::EdgeType *common, slk::Reader *reader) {
|
||||
slk::Load(&common->id_, reader);
|
||||
}
|
||||
inline void Save(const storage::Property &common, slk::Builder *builder) {
|
||||
slk::Save(common.id_, builder);
|
||||
}
|
||||
|
||||
inline void Load(storage::Property *common, slk::Reader *reader) {
|
||||
slk::Load(&common->id_, reader);
|
||||
}
|
||||
|
||||
void Save(const PropertyValue &value, slk::Builder *builder);
|
||||
|
||||
void Load(PropertyValue *value, slk::Reader *reader);
|
||||
|
||||
void Save(const PropertyValueStore &properties, slk::Builder *builder);
|
||||
|
||||
void Load(PropertyValueStore *properties, slk::Reader *reader);
|
||||
|
||||
} // namespace slk
|
@ -313,3 +313,213 @@ EdgeAccessor LoadEdgeAccessor(const capnp::EdgeAccessor::Reader &reader,
|
||||
}
|
||||
|
||||
} // namespace storage
|
||||
|
||||
namespace slk {
|
||||
|
||||
void Save(const storage::SendVersions &versions, slk::Builder *builder) {
|
||||
uint8_t enum_value;
|
||||
switch (versions) {
|
||||
case storage::SendVersions::BOTH:
|
||||
enum_value = 0;
|
||||
break;
|
||||
case storage::SendVersions::ONLY_OLD:
|
||||
enum_value = 1;
|
||||
break;
|
||||
case storage::SendVersions::ONLY_NEW:
|
||||
enum_value = 2;
|
||||
break;
|
||||
}
|
||||
slk::Save(enum_value, builder);
|
||||
}
|
||||
|
||||
void Load(storage::SendVersions *versions, slk::Reader *reader) {
|
||||
uint8_t enum_value;
|
||||
slk::Load(&enum_value, reader);
|
||||
switch (enum_value) {
|
||||
case static_cast<uint8_t>(0):
|
||||
*versions = storage::SendVersions::BOTH;
|
||||
break;
|
||||
case static_cast<uint8_t>(1):
|
||||
*versions = storage::SendVersions::ONLY_OLD;
|
||||
break;
|
||||
case static_cast<uint8_t>(2):
|
||||
*versions = storage::SendVersions::ONLY_NEW;
|
||||
break;
|
||||
default:
|
||||
throw slk::SlkDecodeException("Trying to load unknown enum value!");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <class TRecordAccessor>
|
||||
void SaveRecordAccessor(const TRecordAccessor &accessor, slk::Builder *builder,
|
||||
storage::SendVersions versions, int16_t worker_id) {
|
||||
bool reconstructed = false;
|
||||
if (!accessor.GetOld() && !accessor.GetNew()) {
|
||||
reconstructed = true;
|
||||
bool result = accessor.Reconstruct();
|
||||
CHECK(result) << "Attempting to serialize an element not visible to "
|
||||
"current transaction.";
|
||||
}
|
||||
auto save_optional_record = [builder, worker_id](const auto *rec) {
|
||||
slk::Save(static_cast<bool>(rec), builder);
|
||||
if (rec) {
|
||||
slk::Save(*rec, builder, worker_id);
|
||||
}
|
||||
};
|
||||
slk::Save(accessor.CypherId(), builder);
|
||||
slk::Save(accessor.GlobalAddress(), builder);
|
||||
// Save old record first
|
||||
if (versions != storage::SendVersions::ONLY_NEW) {
|
||||
save_optional_record(accessor.GetOld());
|
||||
} else {
|
||||
// Mark old record as empty
|
||||
slk::Save(false, builder);
|
||||
}
|
||||
// Save new record
|
||||
if (versions != storage::SendVersions::ONLY_OLD) {
|
||||
if (!reconstructed && !accessor.GetNew()) {
|
||||
bool result = accessor.Reconstruct();
|
||||
CHECK(result) << "Attempting to serialize an element not visible to "
|
||||
"current transaction.";
|
||||
}
|
||||
save_optional_record(accessor.GetNew());
|
||||
} else {
|
||||
// Mark new record as empty
|
||||
slk::Save(false, builder);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Save(const VertexAccessor &value, slk::Builder *builder,
|
||||
storage::SendVersions versions, int16_t worker_id) {
|
||||
SaveRecordAccessor(value, builder, versions, worker_id);
|
||||
}
|
||||
|
||||
VertexAccessor LoadVertexAccessor(slk::Reader *reader,
|
||||
database::GraphDbAccessor *dba,
|
||||
distributed::DataManager *data_manager) {
|
||||
auto load_optional_record = [reader]() {
|
||||
std::unique_ptr<Vertex> rec;
|
||||
bool has_ptr;
|
||||
slk::Load(&has_ptr, reader);
|
||||
if (has_ptr) {
|
||||
rec = std::make_unique<Vertex>();
|
||||
slk::Load(rec.get(), reader);
|
||||
}
|
||||
return rec;
|
||||
};
|
||||
int64_t cypher_id;
|
||||
slk::Load(&cypher_id, reader);
|
||||
storage::VertexAddress global_address;
|
||||
slk::Load(&global_address, reader);
|
||||
auto old_record = load_optional_record();
|
||||
auto new_record = load_optional_record();
|
||||
data_manager->Emplace(
|
||||
dba->transaction_id(), global_address.gid(),
|
||||
distributed::CachedRecordData<Vertex>(cypher_id, std::move(old_record),
|
||||
std::move(new_record)));
|
||||
return VertexAccessor(global_address, *dba);
|
||||
}
|
||||
|
||||
void Save(const EdgeAccessor &value, slk::Builder *builder,
|
||||
storage::SendVersions versions, int16_t worker_id) {
|
||||
SaveRecordAccessor(value, builder, versions, worker_id);
|
||||
}
|
||||
|
||||
EdgeAccessor LoadEdgeAccessor(slk::Reader *reader,
|
||||
database::GraphDbAccessor *dba,
|
||||
distributed::DataManager *data_manager) {
|
||||
auto load_optional_record = [reader]() {
|
||||
std::unique_ptr<Edge> rec;
|
||||
bool has_ptr;
|
||||
slk::Load(&has_ptr, reader);
|
||||
if (has_ptr) {
|
||||
slk::Load(&rec, reader);
|
||||
}
|
||||
return rec;
|
||||
};
|
||||
int64_t cypher_id;
|
||||
slk::Load(&cypher_id, reader);
|
||||
storage::EdgeAddress global_address;
|
||||
slk::Load(&global_address, reader);
|
||||
auto old_record = load_optional_record();
|
||||
auto new_record = load_optional_record();
|
||||
data_manager->Emplace(
|
||||
dba->transaction_id(), global_address.gid(),
|
||||
distributed::CachedRecordData<Edge>(cypher_id, std::move(old_record),
|
||||
std::move(new_record)));
|
||||
return EdgeAccessor(global_address, *dba);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO: WTF is with saving adress in a special way?
|
||||
template <class TAddress>
|
||||
void SaveAddress(TAddress address, slk::Builder *builder, int16_t worker_id) {
|
||||
TAddress global_address =
|
||||
address.is_local() ? TAddress(address.local()->gid_, worker_id) : address;
|
||||
slk::Save(global_address.raw(), builder);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Save(const Vertex &vertex, slk::Builder *builder, int16_t worker_id) {
|
||||
auto save_edges = [builder, worker_id](const auto &edges) {
|
||||
size_t size = edges.size();
|
||||
slk::Save(size, builder);
|
||||
for (const auto &edge : edges) {
|
||||
SaveAddress(edge.vertex, builder, worker_id);
|
||||
SaveAddress(edge.edge, builder, worker_id);
|
||||
slk::Save(edge.edge_type, builder);
|
||||
}
|
||||
};
|
||||
save_edges(vertex.out_);
|
||||
save_edges(vertex.in_);
|
||||
slk::Save(vertex.labels_, builder);
|
||||
slk::Save(vertex.properties_, builder);
|
||||
}
|
||||
|
||||
void Load(Vertex *vertex, slk::Reader *reader) {
|
||||
auto load_edges = [reader]() {
|
||||
Edges edges;
|
||||
size_t size;
|
||||
slk::Load(&size, reader);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
storage::VertexAddress vertex_address;
|
||||
slk::Load(&vertex_address, reader);
|
||||
storage::EdgeAddress edge_address;
|
||||
slk::Load(&edge_address, reader);
|
||||
storage::EdgeType edge_type;
|
||||
slk::Load(&edge_type, reader);
|
||||
edges.emplace(vertex_address, edge_address, edge_type);
|
||||
}
|
||||
return edges;
|
||||
};
|
||||
vertex->out_ = load_edges();
|
||||
vertex->in_ = load_edges();
|
||||
slk::Load(&vertex->labels_, reader);
|
||||
slk::Load(&vertex->properties_, reader);
|
||||
}
|
||||
|
||||
void Save(const Edge &edge, slk::Builder *builder, int16_t worker_id) {
|
||||
SaveAddress(edge.from_, builder, worker_id);
|
||||
SaveAddress(edge.to_, builder, worker_id);
|
||||
slk::Save(edge.edge_type_, builder);
|
||||
slk::Save(edge.properties_, builder);
|
||||
}
|
||||
|
||||
void Load(std::unique_ptr<Edge> *edge, slk::Reader *reader) {
|
||||
storage::VertexAddress from;
|
||||
slk::Load(&from, reader);
|
||||
storage::VertexAddress to;
|
||||
slk::Load(&to, reader);
|
||||
storage::EdgeType edge_type;
|
||||
slk::Load(&edge_type, reader);
|
||||
*edge = std::make_unique<Edge>(from, to, edge_type);
|
||||
slk::Load(&(*edge)->properties_, reader);
|
||||
}
|
||||
|
||||
} // namespace slk
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/rpc/serialization.hpp"
|
||||
#include "storage/common/types/property_value.hpp"
|
||||
#include "storage/common/types/property_value_store.hpp"
|
||||
#include "storage/common/types/slk.hpp"
|
||||
#include "storage/distributed/edge.hpp"
|
||||
#include "storage/distributed/edge_accessor.hpp"
|
||||
#include "storage/distributed/rpc/serialization.capnp.h"
|
||||
@ -89,3 +91,45 @@ EdgeAccessor LoadEdgeAccessor(const capnp::EdgeAccessor::Reader &reader,
|
||||
distributed::DataManager *data_manager);
|
||||
|
||||
} // namespace storage
|
||||
|
||||
namespace slk {
|
||||
|
||||
template <typename TLocalObj>
|
||||
void Save(const storage::Address<TLocalObj> &address, slk::Builder *builder) {
|
||||
// TODO: Is this even correct w.r.t. local and global address?
|
||||
slk::Save(address.storage_, builder);
|
||||
}
|
||||
|
||||
template <typename TLocalObj>
|
||||
void Load(storage::Address<TLocalObj> *address, slk::Reader *reader) {
|
||||
// TODO: Is this even correct w.r.t. local and global address?
|
||||
slk::Load(&address->storage_, reader);
|
||||
}
|
||||
|
||||
void Save(const storage::SendVersions &versions, slk::Builder *builder);
|
||||
|
||||
void Load(storage::SendVersions *versions, slk::Reader *reader);
|
||||
|
||||
void Save(const VertexAccessor &value, slk::Builder *builder,
|
||||
storage::SendVersions versions, int16_t worker_id);
|
||||
|
||||
VertexAccessor LoadVertexAccessor(slk::Reader *reader,
|
||||
database::GraphDbAccessor *dba,
|
||||
distributed::DataManager *data_manager);
|
||||
|
||||
void Save(const EdgeAccessor &value, slk::Builder *builder,
|
||||
storage::SendVersions versions, int16_t worker_id);
|
||||
|
||||
EdgeAccessor LoadEdgeAccessor(slk::Reader *reader,
|
||||
database::GraphDbAccessor *dba,
|
||||
distributed::DataManager *data_manager);
|
||||
|
||||
void Save(const Vertex &vertex, slk::Builder *builder, int16_t worker_id);
|
||||
|
||||
void Load(Vertex *vertex, slk::Reader *reader);
|
||||
|
||||
void Save(const Edge &edge, slk::Builder *builder, int16_t worker_id);
|
||||
|
||||
void Load(std::unique_ptr<Edge> *edge, slk::Reader *reader);
|
||||
|
||||
} // namespace slk
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/rpc/serialization.hpp"
|
||||
#include "storage/common/types/property_value.hpp"
|
||||
#include "storage/common/types/slk.hpp"
|
||||
#include "storage/common/types/types.hpp"
|
||||
#include "storage/single_node_ha/rpc/serialization.capnp.h"
|
||||
|
||||
|
@ -216,7 +216,7 @@ add_unit_test(skiplist_suffix.cpp)
|
||||
target_link_libraries(${test_prefix}skiplist_suffix mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(slk_advanced.cpp)
|
||||
target_link_libraries(${test_prefix}slk_advanced mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}slk_advanced mg-distributed kvstore_dummy_lib)
|
||||
|
||||
# TODO (mferencevic): remove glog, gflags and mg-single-node
|
||||
add_unit_test(slk_core.cpp)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "storage/common/types/property_value.slk.hpp"
|
||||
#include "storage/common/types/slk.hpp"
|
||||
|
||||
TEST(SlkAdvanced, PropertyValueList) {
|
||||
std::vector<PropertyValue> original{"hello world!", 5, 1.123423, true,
|
||||
|
Loading…
Reference in New Issue
Block a user