Commit 376b56a7 authored by outro56's avatar outro56

Optimize serialization by using type numbers

Always write type number during serialization
parent 90a18f93
......@@ -156,15 +156,22 @@ binary_deserializer::binary_deserializer(const void* bbegin, const void* bend,
}
const uniform_type_info* binary_deserializer::begin_object() {
std::string tname;
m_pos = read_range(m_pos, m_end, tname);
auto uti_map = detail::singletons::get_uniform_type_info_map();
auto uti = uti_map->by_uniform_name(tname);
if (!uti) {
std::string err = "received type name \"";
err += tname;
err += "\" but no such type is known";
throw std::runtime_error(err);
detail::uniform_type_info_map::pointer uti;
uint16_t nr;
m_pos = read_range(m_pos, m_end, nr);
if (nr) {
uti = uti_map->by_type_nr(nr);
} else {
std::string tname;
m_pos = read_range(m_pos, m_end, tname);
uti = uti_map->by_uniform_name(tname);
if (!uti) {
std::string err = "received type name \"";
err += tname;
err += "\" but no such type is known";
throw std::runtime_error(err);
}
}
return uti;
}
......
......@@ -95,7 +95,11 @@ class binary_writer : public static_visitor<> {
};
void binary_serializer::begin_object(const uniform_type_info* uti) {
binary_writer::write_string(m_out, uti->name());
auto nr = uti->type_nr();
binary_writer::write_int(m_out, nr);
if (!nr) {
binary_writer::write_string(m_out, uti->name());
}
}
void binary_serializer::end_object() {
......
......@@ -43,6 +43,7 @@
#include <algorithm>
#include <functional>
#include <type_traits>
#include <tuple>
#include "caf/message.hpp"
#include "caf/announce.hpp"
......@@ -115,14 +116,106 @@ struct raw_struct_type_info : detail::abstract_uniform_type_info<raw_struct> {
}
};
enum class test_enum {
a,
b,
c
};
struct common_fixture {
common_fixture(int32_t i32 = -345,
test_enum te = test_enum::b,
string str = "Lorem ipsum dolor sit amet.")
: i32(i32), te(te), str(str), rs{string(str.rbegin(), str.rend())} {
msg = make_message(i32, te, str, rs);
}
int32_t i32;
test_enum te;
string str;
raw_struct rs;
message msg;
} fixture = {};
template<typename F, typename T>
void apply_func(F&& f, T&& t) {
f(std::forward<T>(t));
}
template<typename F, typename T, typename... Ts>
void apply_func(F&& f, T&& t, Ts&&... ts) {
f(std::forward<T>(t));
apply_func(std::forward<F>(f), std::forward<Ts>(ts)...);
}
struct binary_util {
static actor_namespace*& serialization_namespace() {
static actor_namespace* ns = nullptr;
return ns;
}
template <typename T, typename... Ts>
static string serialize(T&& t, Ts&&... ts) {
std::stringstream ss;
binary_serializer bs {
std::ostreambuf_iterator<char>(ss),
serialization_namespace()
};
apply_func(
serializer_lambda{&bs},
std::forward<T>(t), std::forward<Ts>(ts)...
);
return ss.str();
}
template <typename T, typename... Ts>
static void deserialize(string const& buff, T* t, Ts*... ts) {
binary_deserializer bd {
buff.data(), buff.size(),
serialization_namespace()
};
apply_func(deserializer_lambda{&bd}, t, ts...);
}
private:
struct serializer_lambda {
serializer_lambda(binary_serializer* bs) : bs(bs) {}
binary_serializer* bs;
template <typename T>
void operator()(T&& x) const {
*bs << x;
}
};
struct deserializer_lambda {
deserializer_lambda(binary_deserializer* bd) : bd(bd) {}
binary_deserializer* bd;
template <typename T>
void operator()(T* x) const {
uniform_typeid<T>()->deserialize(x, bd);
}
};
};
struct is_message {
explicit is_message(message& msg) : msg(msg) {}
message msg;
template <typename T, typename... Ts>
bool equal(T&& t, Ts&&... ts) {
bool ok = false;
// work around for gcc bug
auto tup = tie(t, ts...);
message_handler impl {
[&](T const& u, Ts const&... us) {
ok = tup == tie(u, us...);
}
};
impl(msg);
return ok;
}
};
} // namespace <anonymous>
CAF_TEST(test_serialization) {
......@@ -162,6 +255,54 @@ CAF_TEST(test_ieee_754) {
CAF_CHECK_EQUAL(f2, u2);
}
CAF_TEST(test_int32_t) {
auto buff = binary_util::serialize(fixture.i32);
int32_t i32;
binary_util::deserialize(buff, &i32);
CAF_CHECK_EQUAL(fixture.i32, i32);
}
CAF_TEST(test_enum) {
auto buff = binary_util::serialize(fixture.te);
test_enum te;
binary_util::deserialize(buff, &te);
CAF_CHECK(fixture.te == te);
}
CAF_TEST(test_string) {
auto buff = binary_util::serialize(fixture.str);
string str;
binary_util::deserialize(buff, &str);
CAF_CHECK_EQUAL(fixture.str, str);
}
CAF_TEST(test_raw_struct) {
auto buff = binary_util::serialize(fixture.rs);
raw_struct rs;
binary_util::deserialize(buff, &rs);
CAF_CHECK(fixture.rs == rs);
}
CAF_TEST(test_single_message) {
auto buff = binary_util::serialize(fixture.msg);
message msg;
binary_util::deserialize(buff, &msg);
CAF_CHECK(fixture.msg == msg);
CAF_CHECK(is_message(msg).equal(fixture.i32, fixture.te, fixture.str, fixture.rs));
}
CAF_TEST(test_multiple_messages) {
auto m = make_message(fixture.rs, fixture.te);
auto buff = binary_util::serialize(fixture.te, m, fixture.msg);
test_enum t;
message m1;
message m2;
binary_util::deserialize(buff, &t, &m1, &m2);
CAF_CHECK(tie(t, m1, m2) == tie(fixture.te, m, fixture.msg));
CAF_CHECK(is_message(m1).equal(fixture.rs, fixture.te));
CAF_CHECK(is_message(m2).equal(fixture.i32, fixture.te, fixture.str, fixture.rs));
}
CAF_TEST(test_string_serialization) {
auto input = make_message("hello \"actor world\"!", atom("foo"));
auto s = to_string(input);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment