Commit 5c311ad3 authored by Giorgio Azzinnaro's avatar Giorgio Azzinnaro

split marshaller and unmarshaller

parent 7b483bc1
......@@ -24,8 +24,9 @@
#include <profanedb/protobuf/storage.pb.h>
#include <profanedb/format/marshaller.h>
#include <profanedb/vault/storage.h>
#include <profanedb/format/marshaller.h>
#include <profanedb/format/unmarshaller.h>
#include <boost/log/trivial.hpp>
......@@ -37,9 +38,11 @@ class Db
{
public:
Db(std::shared_ptr<vault::Storage> storage,
std::shared_ptr< format::Marshaller<Message> > marshaller)
std::shared_ptr< format::Marshaller<Message> > marshaller,
std::shared_ptr< format::Unmarshaller<Message> > unmarshaller)
: storage(storage)
, marshaller(marshaller)
, unmarshaller(unmarshaller)
{
}
......@@ -47,7 +50,7 @@ public:
{
BOOST_LOG_TRIVIAL(debug) << "Retrieving " << key.message_type();
return this->marshaller->Unmarshal(this->storage->Retrieve(key));
return this->unmarshaller->Unmarshal(this->storage->Retrieve(key));
}
bool Put(const Message & message)
......@@ -84,6 +87,7 @@ protected:
private:
std::shared_ptr<vault::Storage> storage;
std::shared_ptr< format::Marshaller<Message> > marshaller;
std::shared_ptr< format::Unmarshaller<Message> > unmarshaller;
};
}
......
......@@ -3,7 +3,11 @@ find_package(Boost 1.54
REQUIRED
COMPONENTS log filesystem) # Boost Filesystem scans the .proto directory
add_library(profanedb_format STATIC protobuf/marshaller.cpp protobuf/loader.cpp)
add_library(profanedb_format STATIC
protobuf/marshaller.cpp
protobuf/unmarshaller.cpp
protobuf/loader.cpp
protobuf/util.cpp)
target_link_libraries(profanedb_format profanedb_protobuf ${Boost_LIBRARIES})
if(BUILD_SHARED_LIBS)
......
......@@ -27,16 +27,12 @@ namespace format {
// Marshaller does the actual manipulation on Messages,
// it takes care of converting them into a message tree
// and deserialise a single message as coming from the database back to the original format
template<typename Message>
class Marshaller
{
public:
// Create the whole graph with all nested referenced messages
virtual profanedb::protobuf::MessageTreeNode Marshal(const Message & message) = 0;
// Turn a stored message back into the original format
virtual const Message & Unmarshal(const profanedb::protobuf::StorableMessage & storable) = 0;
};
}
}
......
......@@ -36,10 +36,8 @@ namespace format {
namespace protobuf {
Marshaller::Marshaller(
std::shared_ptr<Storage> storage,
std::shared_ptr<Loader> loader)
: loader(loader)
, storage(storage)
{
}
......@@ -84,7 +82,7 @@ MessageTreeNode Marshaller::Marshal(const Message & message)
*messageTree.add_children() = nestedMessageTree;
// The field in the normalized message is assigned the root key from the contained message tree
this->CopyMessage(nestedMessageTree.message().key(),
CopyMessage(nestedMessageTree.message().key(),
normalizedMessage->GetReflection()->MutableMessage(
normalizedMessage, normalizedField));
}
......@@ -95,7 +93,7 @@ MessageTreeNode Marshaller::Marshal(const Message & message)
// We are pretty much sure at this point that we can copy the data,
// because messages in normalizedPool differ from those in schemaPool
// only on nested keyable messages, which we've already taken care of
this->CopyField(field, message, normalizedMessage);
CopyField(field, message, normalizedMessage);
}
}
......@@ -106,130 +104,6 @@ MessageTreeNode Marshaller::Marshal(const Message & message)
return messageTree;
}
const Message & Marshaller::Unmarshal(const StorableMessage & storable)
{
// An empty normalized message is generated using the Key
Message * normalizedMessage
= this->loader->CreateMessage(Loader::NORMALIZED,
storable.key().message_type())->New();
// The original message is also retrieved
Message * originalMessage
= this->loader->CreateMessage(Loader::SCHEMA,
storable.key().message_type())->New();
// StorableMessage payload contains the serialized normalized message,
// as previously stored into the DB
storable.payload().UnpackTo(normalizedMessage);
// Similarly to Marshal, set fields are retrieved
std::vector< const FieldDescriptor * > setFields;
normalizedMessage->GetReflection()->ListFields(*normalizedMessage, &setFields);
for (const auto normalizedField: setFields) {
// Whenever a Key is found, it is considered a separate normalized message to be retrieved
if (normalizedField->type() == FieldDescriptor::TYPE_MESSAGE
&& normalizedField->message_type() == Key::descriptor()
) {
// Get the key of the nested message (is embedded as Key object)
Key nestedKey;
nestedKey.MergeFrom(normalizedMessage->GetReflection()->GetMessage(*normalizedMessage, normalizedField));
// Retrieve the nested message from storage and unmarshal it as well
const Message & nestedMessage = this->Unmarshal(this->storage->Retrieve(nestedKey));
// We need the original descriptor field to set the message
const FieldDescriptor * originalField = originalMessage->GetDescriptor()->field(normalizedField->index());
// Copy the nested unmarshalled message to the original one
this->CopyMessage(nestedMessage,
originalMessage->GetReflection()->MutableMessage(
originalMessage, originalField));
}
else { // if field is not a reference
// Just like in Marshal, other fields are simply copied over,
// as normalized and original descriptors look the same except for nested keyable messages
this->CopyField(normalizedField, *normalizedMessage, originalMessage);
}
}
return *originalMessage;
}
void Marshaller::CopyMessage(const Message & from, Message * to)
{
std::vector< const FieldDescriptor * > setFields;
from.GetReflection()->ListFields(from, &setFields);
for (auto fromField : setFields)
this->CopyField(fromField, from, to);
}
void Marshaller::CopyField(
const FieldDescriptor * fromField,
const Message & from,
Message * to)
{
const Reflection * fromReflection = from.GetReflection();
const Reflection * toReflection = to->GetReflection();
const FieldDescriptor * toField = to->GetDescriptor()->field(fromField->index());
if (fromField->is_repeated()) {
for (int y = 0; y < fromReflection->FieldSize(from, fromField); y++) {
switch (fromField->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
toReflection->Add##METHOD(to, toField, \
fromReflection->GetRepeated##METHOD(from, fromField, y)); \
break;
HANDLE_TYPE(INT32 , Int32 );
HANDLE_TYPE(INT64 , Int64 );
HANDLE_TYPE(UINT32, UInt32);
HANDLE_TYPE(UINT64, UInt64);
HANDLE_TYPE(DOUBLE, Double);
HANDLE_TYPE(FLOAT , Float );
HANDLE_TYPE(BOOL , Bool );
HANDLE_TYPE(STRING, String);
HANDLE_TYPE(ENUM , Enum );
#undef HANDLE_TYPE
case FieldDescriptor::CPPTYPE_MESSAGE:
toReflection->AddMessage(to, toField)->MergeFrom(
fromReflection->GetRepeatedMessage(from, fromField, y));
break;
}
}
} else {
switch (fromField->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
toReflection->Set##METHOD(to, toField, \
fromReflection->Get##METHOD(from, fromField)); \
break;
HANDLE_TYPE(INT32 , Int32 );
HANDLE_TYPE(INT64 , Int64 );
HANDLE_TYPE(UINT32, UInt32);
HANDLE_TYPE(UINT64, UInt64);
HANDLE_TYPE(DOUBLE, Double);
HANDLE_TYPE(FLOAT , Float );
HANDLE_TYPE(BOOL , Bool );
HANDLE_TYPE(STRING, String);
HANDLE_TYPE(ENUM , Enum );
#undef HANDLE_TYPE
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
this->CopyMessage(
fromReflection->GetMessage(from, fromField),
toReflection->MutableMessage(to, toField));
break;
}
}
}
// TODO Should serialize differently... int(123) shouldn't become string("123")
Key Marshaller::FieldToKey(
const Message & message,
......
......@@ -34,6 +34,7 @@
#include <profanedb/format/marshaller.h>
#include "loader.h"
#include "util.h"
namespace profanedb {
namespace format {
......@@ -42,32 +43,13 @@ namespace protobuf {
class Marshaller : public profanedb::format::Marshaller<google::protobuf::Message>
{
public:
Marshaller(
std::shared_ptr<profanedb::vault::Storage> storage,
std::shared_ptr<Loader> loader);
Marshaller(std::shared_ptr<Loader> loader);
virtual profanedb::protobuf::MessageTreeNode Marshal(const google::protobuf::Message & message) override;
virtual const google::protobuf::Message & Unmarshal(const profanedb::protobuf::StorableMessage & storable) override;
private:
// Loader contains the schemaPool and normalizedPool
const std::shared_ptr<Loader> loader;
// Because a StorableMessage only holds references to its children objects,
// Storage is used to recursively retrieve them.
const std::shared_ptr<profanedb::vault::Storage> storage;
// Copy a Message, can't use MergeFrom because it checks Descriptors
void CopyMessage(
const google::protobuf::Message & from,
google::protobuf::Message * to);
// Copy a field from a message to another.
// Differs from MergeFrom because it doesn't check whether Descriptors match.
void CopyField(
const google::protobuf::FieldDescriptor * fromField,
const google::protobuf::Message & from,
google::protobuf::Message * to);
// Convert a field from a message to a Key object
profanedb::protobuf::Key FieldToKey(
const google::protobuf::Message & message,
......
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "unmarshaller.h"
using google::protobuf::Message;
using google::protobuf::Descriptor;
using google::protobuf::DescriptorPool;
using google::protobuf::FieldDescriptor;
using google::protobuf::Reflection;
using profanedb::vault::Storage;
using profanedb::protobuf::MessageTreeNode;
using profanedb::protobuf::StorableMessage;
using profanedb::protobuf::Key;
namespace profanedb {
namespace format {
namespace protobuf {
Unmarshaller::Unmarshaller(
std::shared_ptr<Storage> storage,
std::shared_ptr<Loader> loader)
: loader(loader)
, storage(storage)
{
}
const Message & Unmarshaller::Unmarshal(const StorableMessage & storable)
{
// An empty normalized message is generated using the Key
Message * normalizedMessage
= this->loader->CreateMessage(Loader::NORMALIZED,
storable.key().message_type())->New();
// The original message is also retrieved
Message * originalMessage
= this->loader->CreateMessage(Loader::SCHEMA,
storable.key().message_type())->New();
// StorableMessage payload contains the serialized normalized message,
// as previously stored into the DB
storable.payload().UnpackTo(normalizedMessage);
// Similarly to Marshal, set fields are retrieved
std::vector< const FieldDescriptor * > setFields;
normalizedMessage->GetReflection()->ListFields(*normalizedMessage, &setFields);
for (const auto normalizedField: setFields) {
// Whenever a Key is found, it is considered a separate normalized message to be retrieved
if (normalizedField->type() == FieldDescriptor::TYPE_MESSAGE
&& normalizedField->message_type() == Key::descriptor()
) {
// Get the key of the nested message (is embedded as Key object)
Key nestedKey;
nestedKey.MergeFrom(normalizedMessage->GetReflection()->GetMessage(*normalizedMessage, normalizedField));
// Retrieve the nested message from storage and unmarshal it as well
const Message & nestedMessage = this->Unmarshal(this->storage->Retrieve(nestedKey));
// We need the original descriptor field to set the message
const FieldDescriptor * originalField = originalMessage->GetDescriptor()->field(normalizedField->index());
// Copy the nested unmarshalled message to the original one
CopyMessage(nestedMessage,
originalMessage->GetReflection()->MutableMessage(
originalMessage, originalField));
}
else { // if field is not a reference
// Just like in Marshal, other fields are simply copied over,
// as normalized and original descriptors look the same except for nested keyable messages
CopyField(normalizedField, *normalizedMessage, originalMessage);
}
}
return *originalMessage;
}
}
}
}
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PROFANEDB_FORMAT_PROTOBUF_UNMARSHALLER_H
#define PROFANEDB_FORMAT_PROTOBUF_UNMARSHALLER_H
#include <memory>
#include <profanedb/protobuf/options.pb.h>
#include <profanedb/vault/storage.h>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <boost/log/trivial.hpp>
#include <profanedb/format/unmarshaller.h>
#include "util.h"
#include "loader.h"
namespace profanedb {
namespace format {
namespace protobuf {
class Unmarshaller : public profanedb::format::Unmarshaller<google::protobuf::Message>
{
public:
Unmarshaller(
std::shared_ptr<profanedb::vault::Storage> storage,
std::shared_ptr<Loader> loader);
virtual const google::protobuf::Message & Unmarshal(const profanedb::protobuf::StorableMessage & storable) override;
private:
// Loader contains the schemaPool and normalizedPool
const std::shared_ptr<Loader> loader;
// Because a StorableMessage only holds references to its children objects,
// Storage is used to recursively retrieve them.
const std::shared_ptr<profanedb::vault::Storage> storage;
};
}
}
}
#endif // PROFANEDB_FORMAT_PROTOBUF_UNMARSHALLER_H
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "util.h"
using google::protobuf::Message;
using google::protobuf::FieldDescriptor;
using google::protobuf::Reflection;
namespace profanedb {
namespace format {
namespace protobuf {
void CopyMessage(const Message & from, Message * to)
{
std::vector< const FieldDescriptor * > setFields;
from.GetReflection()->ListFields(from, &setFields);
for (auto fromField : setFields)
CopyField(fromField, from, to);
}
void CopyField(const FieldDescriptor * fromField, const Message & from, Message * to)
{
const Reflection * fromReflection = from.GetReflection();
const Reflection * toReflection = to->GetReflection();
const FieldDescriptor * toField = to->GetDescriptor()->field(fromField->index());
if (fromField->is_repeated()) {
for (int y = 0; y < fromReflection->FieldSize(from, fromField); y++) {
switch (fromField->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
toReflection->Add##METHOD(to, toField, \
fromReflection->GetRepeated##METHOD(from, fromField, y)); \
break;
HANDLE_TYPE(INT32 , Int32 );
HANDLE_TYPE(INT64 , Int64 );
HANDLE_TYPE(UINT32, UInt32);
HANDLE_TYPE(UINT64, UInt64);
HANDLE_TYPE(DOUBLE, Double);
HANDLE_TYPE(FLOAT , Float );
HANDLE_TYPE(BOOL , Bool );
HANDLE_TYPE(STRING, String);
HANDLE_TYPE(ENUM , Enum );
#undef HANDLE_TYPE
case FieldDescriptor::CPPTYPE_MESSAGE:
toReflection->AddMessage(to, toField)->MergeFrom(
fromReflection->GetRepeatedMessage(from, fromField, y));
break;
}
}
} else {
switch (fromField->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
toReflection->Set##METHOD(to, toField, \
fromReflection->Get##METHOD(from, fromField)); \
break;
HANDLE_TYPE(INT32 , Int32 );
HANDLE_TYPE(INT64 , Int64 );
HANDLE_TYPE(UINT32, UInt32);
HANDLE_TYPE(UINT64, UInt64);
HANDLE_TYPE(DOUBLE, Double);
HANDLE_TYPE(FLOAT , Float );
HANDLE_TYPE(BOOL , Bool );
HANDLE_TYPE(STRING, String);
HANDLE_TYPE(ENUM , Enum );
#undef HANDLE_TYPE
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
CopyMessage(
fromReflection->GetMessage(from, fromField),
toReflection->MutableMessage(to, toField));
break;
}
}
}
}
}
}
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PROFANEDB_FORMAT_PROTOBUF_UTIL_H
#define PROFANEDB_FORMAT_PROTOBUF_UTIL_H
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
namespace profanedb {
namespace format {
namespace protobuf {
// Copy a Message, can't use MergeFrom because it checks Descriptors
void CopyMessage(
const google::protobuf::Message & from,
google::protobuf::Message * to);
// Copy a field from a message to another.
// Differs from MergeFrom because it doesn't check whether Descriptors match.
void CopyField(
const google::protobuf::FieldDescriptor * fromField,
const google::protobuf::Message & from,
google::protobuf::Message * to);
}
}
}
#endif // PROFANEDB_FORMAT_PROTOBUF_UTIL_H
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PROFANEDB_FORMAT_UNMARSHALLER_H
#define PROFANEDB_FORMAT_UNMARSHALLER_H
#include <profanedb/protobuf/storage.pb.h>
namespace profanedb {
namespace format {
// Unmarshaller deserialises a single message as coming from the database back to the original format,
// it would usually require to interact with profanedb::vault::Storage as well
template<typename Message>
class Unmarshaller
{
public:
// Turn a stored message back into the original format
virtual const Message & Unmarshal(const profanedb::protobuf::StorableMessage & storable) = 0;
};
}
}
#endif // PROFANEDB_FORMAT_UNMARSHALLER_H
......@@ -22,6 +22,8 @@
using profanedb::format::protobuf::Loader;
using profanedb::format::Marshaller;
using ProtobufMarshaller = profanedb::format::protobuf::Marshaller;
using profanedb::format::Unmarshaller;
using ProtobufUnmarshaller = profanedb::format::protobuf::Unmarshaller;
using profanedb::vault::Storage;
using RocksStorage = profanedb::vault::rocksdb::Storage;
using profanedb::server::Config;
......@@ -64,9 +66,13 @@ Server::Server(const Config & config)
std::unique_ptr<Loader::RootSourceTree>(includeSourceTree),
std::unique_ptr<Loader::RootSourceTree>(schemaSourceTree));
auto marshaller = std::make_shared<ProtobufMarshaller>(storage, loader);
auto marshaller = std::make_shared<ProtobufMarshaller>(loader);
auto unmarshaller = std::make_shared<ProtobufUnmarshaller>(storage, loader);
service = std::make_unique<DbServiceImpl>(storage, marshaller, loader);
service = std::make_unique<DbServiceImpl>(storage,
marshaller,
unmarshaller,
loader);
}
Server::~Server()
......@@ -98,10 +104,12 @@ void Server::HandleRpcs()
Server::DbServiceImpl::DbServiceImpl(
std::shared_ptr<RocksStorage> storage,
std::shared_ptr<ProtobufMarshaller> marshaller,
std::shared_ptr<ProtobufUnmarshaller> unmarshaller,
std::shared_ptr<Loader> loader)
: rocksdbStorage(storage)
, protobufMarshaller(marshaller)
, profane(std::make_unique< profanedb::Db<Message> >(storage, marshaller))
, protobufUnmarshaller(unmarshaller)
, profane(std::make_unique< profanedb::Db<Message> >(storage, marshaller, unmarshaller))
, loader(loader)
{
}
......
......@@ -31,8 +31,9 @@
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <profanedb/format/protobuf/marshaller.h>
#include <profanedb/vault/rocksdb/storage.h>
#include <profanedb/format/protobuf/marshaller.h>
#include <profanedb/format/protobuf/unmarshaller.h>
#include <profanedb/db.hpp>
......@@ -60,6 +61,7 @@ private:
DbServiceImpl(
std::shared_ptr<profanedb::vault::rocksdb::Storage> storage,
std::shared_ptr<profanedb::format::protobuf::Marshaller> marshaller,
std::shared_ptr<profanedb::format::protobuf::Unmarshaller> unmarshaller,
std::shared_ptr<profanedb::format::protobuf::Loader> loader);
grpc::Status Get(
......@@ -79,7 +81,9 @@ private:
private:
std::shared_ptr<profanedb::vault::rocksdb::Storage> rocksdbStorage;
std::shared_ptr<profanedb::format::protobuf::Marshaller> protobufMarshaller;
std::shared_ptr<profanedb::format::protobuf::Unmarshaller> protobufUnmarshaller;
std::unique_ptr< profanedb::Db<google::protobuf::Message> > profane;
......
......@@ -7,18 +7,14 @@
#include <profanedb/protobuf/storage.pb.h>
#include <profanedb/format/protobuf/marshaller.h>
#include <profanedb/vault/rocksdb/storage.h>
#include <profanedb/util/randomgenerator.h>
using profanedb::format::protobuf::Loader;
using profanedb::format::Marshaller;
using ProtobufMarshaller = profanedb::format::protobuf::Marshaller;
using profanedb::vault::Storage;
using profanedb::protobuf::MessageTreeNode;
using RocksStorage = profanedb::vault::rocksdb::Storage;
using profanedb::util::RandomGenerator;
using google::protobuf::Message;
......@@ -34,7 +30,6 @@ private:
public:
std::shared_ptr<Loader> loader;
std::shared_ptr<ProtobufMarshaller> marshaller;
std::shared_ptr<RocksStorage> storage;