Skip to content

Commit

Permalink
Fix CustomSerializers
Browse files Browse the repository at this point in the history
  • Loading branch information
facontidavide committed Nov 28, 2023
1 parent 03f9cda commit 46b4ab6
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 236 deletions.
22 changes: 12 additions & 10 deletions data_tamer/include/data_tamer/custom_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

#include <map>
#include <mutex>
#include <typeindex>
#include <typeinfo>
#include <optional>

#include "data_tamer/types.hpp"
#include "data_tamer/contrib/SerializeMe.hpp"
Expand Down Expand Up @@ -39,16 +38,18 @@ class CustomSerializer

virtual ~CustomSerializer() = default;
// name of the type, to be written in the schema string.
virtual const char* typeName() const = 0;
virtual const std::string& typeName() const = 0;
// optional custom schema of the type
virtual const char* typeSchema() const

virtual std::optional<CustomSchema> typeSchema() const
{
return nullptr;
return std::nullopt;
}
// size in bytes of the serialized object.
// Needed to pre-allocate memory in the buffer
virtual size_t serializedSize(const void* src_instance) const = 0;

// true if the serialized object will always have the same amount of bytes
virtual bool isFixedSize() const = 0;

// serialize an object into a buffer. Return the size in bytes of the serialized data
Expand All @@ -75,9 +76,10 @@ template <typename T>
class CustomSerializerT : public CustomSerializer
{
public:
CustomSerializerT(const std::string& type_name);

const char* typeName() const override;
CustomSerializerT(const std::string& type_name = TypeDefinition<T>().typeName());

const std::string& typeName() const override;

size_t serializedSize(const void* src_instance) const override;

Expand Down Expand Up @@ -169,9 +171,9 @@ template<typename T> inline
}

template<typename T> inline
const char *CustomSerializerT<T>::typeName() const
const std::string& CustomSerializerT<T>::typeName() const
{
return _name.c_str();
return _name;
}

template<typename T> inline
Expand Down Expand Up @@ -207,7 +209,7 @@ inline CustomSerializer::Ptr TypesRegistry::getSerializer()
"Don't pass containers as template type");

std::scoped_lock lk(_mutex);
const auto type_name = SerializeMe::TypeDefinition<T>().typeName();
const auto type_name = TypeDefinition<T>().typeName();
auto it = _types.find(type_name);

if (it == _types.end())
Expand Down
8 changes: 8 additions & 0 deletions data_tamer/include/data_tamer/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ struct TypeField
};

using FieldsVector = std::vector<TypeField>;
class CustomSerializer;

struct CustomSchema
{
std::string encoding;
std::string schema;
};

/**
* @brief DataTamer uses a simple "flat" schema of key/value pairs (each pair is a "field").
Expand All @@ -129,6 +136,7 @@ struct Schema
std::string channel_name;

std::unordered_map<std::string, FieldsVector> custom_types;
std::unordered_map<std::string, CustomSchema> custom_schemas;

friend std::ostream& operator<<(std::ostream& os, const Schema& schema);
};
Expand Down
133 changes: 72 additions & 61 deletions data_tamer/include/data_tamer/values.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ class ValuePtr
ValuePtr(const T* pointer, CustomSerializer::Ptr type_info = {});

template <template <class, class> class Container, class T, class... TArgs>
ValuePtr(const Container<T, TArgs...>* vect, CustomSerializer::Ptr type_info = {});
ValuePtr(const Container<T, TArgs...>* vect);

template <template <class, class> class Container, class T, class... TArgs>
ValuePtr(const Container<T, TArgs...>* vect, CustomSerializer::Ptr type_info);

template <typename T, size_t N>
ValuePtr(const std::array<T, N>* vect, CustomSerializer::Ptr type_info = {});
ValuePtr(const std::array<T, N>* vect);

template <typename T, size_t N>
ValuePtr(const std::array<T, N>* vect, CustomSerializer::Ptr type_info);

ValuePtr(ValuePtr const& other) = delete;
ValuePtr& operator=(ValuePtr const& other) = delete;
Expand Down Expand Up @@ -92,45 +98,60 @@ inline ValuePtr::ValuePtr(const T* pointer, CustomSerializer::Ptr type_info) :
}
}

template <template <class, class> class Container, class T, class... TArgs>
inline ValuePtr::ValuePtr(const Container<T, TArgs...>* vect) :
v_ptr_(vect), type_(GetBasicType<T>()), memory_size_(sizeof(T)), is_vector_(true)
{
serialize_impl_ = [vect](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *vect);
};
get_size_impl_ = [vect]() -> size_t {
return SerializeMe::BufferSize(*vect);
};
}

template <template <class, class> class Container, class T, class... TArgs>
inline ValuePtr::ValuePtr(const Container<T, TArgs...>* vect,
CustomSerializer::Ptr type_info) :
v_ptr_(vect), type_(GetBasicType<T>()), memory_size_(sizeof(T)), is_vector_(true)
{
if (type_info)
serialize_impl_ = [type_info, vect](SerializeMe::SpanBytes& buffer) -> void
{
serialize_impl_ = [type_info, vect](SerializeMe::SpanBytes& buffer) -> void
SerializeMe::SerializeIntoBuffer(buffer, uint32_t(vect->size()));
for(const auto& value: (*vect))
{
SerializeMe::SerializeIntoBuffer(buffer, uint32_t(vect->size()));
for(const auto& value: (*vect))
{
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, vect]() -> size_t {
if(vect->empty())
{
return 0;
}
if(type_info->isFixedSize())
{
return vect->size() * type_info->serializedSize(&vect->front());
}
size_t tot_size = 0;
for(const auto& value: (*vect))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}
else
{
serialize_impl_ = [vect](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *vect);
};
get_size_impl_ = [vect]() -> size_t { return SerializeMe::BufferSize(*vect); };
}
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, vect]() -> size_t {
if(vect->empty())
{
return sizeof(uint32_t);
}
if(type_info->isFixedSize())
{
return sizeof(uint32_t) + vect->size() * type_info->serializedSize(&vect->front());
}
size_t tot_size = sizeof(uint32_t);
for(const auto& value: (*vect))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}

template <typename T, size_t N>
inline ValuePtr::ValuePtr(const std::array<T, N>* array) :
v_ptr_(array),
type_(GetBasicType<T>()),
is_vector_(true),
array_size_(N)
{
serialize_impl_ = [array](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *array);
};
get_size_impl_ = [array]() { return SerializeMe::BufferSize(*array); };
}

template <typename T, size_t N>
Expand All @@ -141,35 +162,25 @@ inline ValuePtr::ValuePtr(const std::array<T, N>* array,
is_vector_(true),
array_size_(N)
{
if (type_info)
serialize_impl_ = [type_info, array](SerializeMe::SpanBytes& buffer) -> void
{
serialize_impl_ = [type_info, array](SerializeMe::SpanBytes& buffer) -> void
for(const auto& value: (*array))
{
for(const auto& value: (*array))
{
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, array]() {
size_t tot_size = 0;
if(type_info->isFixedSize())
{
return N * type_info->serializedSize(&array->front());
}
for(const auto& value: (*array))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}
else
{
serialize_impl_ = [array](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *array);
};
get_size_impl_ = [array]() { return SerializeMe::BufferSize(*array); };
}
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, array]() {
size_t tot_size = 0;
if(type_info->isFixedSize())
{
return N * type_info->serializedSize(&array->front());
}
for(const auto& value: (*array))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}

inline bool ValuePtr::operator==(const ValuePtr& other) const
Expand Down
10 changes: 10 additions & 0 deletions data_tamer/src/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ RegistrationID LogChannel::registerValueImpl(const std::string& name,
_p->schema.hash = AddFieldToHash(field, _p->schema.hash);
_p->schema.fields.emplace_back(std::move(field));

// if this was a special serializer with its own schema, save it instead in custom_schemas
if(type_info)
{
auto custom_schema = type_info->typeSchema();
if(custom_schema && _p->schema.custom_types.count(type_info->typeName()) == 0)
{
_p->schema.custom_schemas.insert( {type_info->typeName(), *custom_schema});
}
}

return {index, 1};
}

Expand Down
7 changes: 7 additions & 0 deletions data_tamer/src/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ std::ostream& operator<<(std::ostream& os, const Schema& schema)
os << field << "\n";
}
}
for (const auto& [type_name, custom_schema] : schema.custom_schemas)
{
os << "===========================================================\n"
<< "MSG: " << type_name << "\n"
<< "ENCODING: " << custom_schema.encoding << "\n"
<< custom_schema.schema << "\n";
}

return os;
}
Expand Down
5 changes: 4 additions & 1 deletion data_tamer/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
find_package(GTest REQUIRED)
include(GoogleTest)

add_executable(datatamer_test dt_tests.cpp parser_tests.cpp)
add_executable(datatamer_test
dt_tests.cpp
custom_types_tests.cpp
parser_tests.cpp)
gtest_discover_tests(datatamer_test DISCOVERY_MODE PRE_TEST)

target_include_directories(datatamer_test
Expand Down
Loading

0 comments on commit 46b4ab6

Please sign in to comment.