-
Notifications
You must be signed in to change notification settings - Fork 0
bs srz rationale
Boost::serialization is great and sophisticated tool for saving and restoring persistent states of different objects. It has powerful machinery capable of tracking multiple references to the same object and eliminating duplicates.
When object is serialized via polymorphic pointer to base class, preferred method for boost::serialization to determine the most derived type, that is really hidden behind the pointer, is to associate a string ID with this type and register it using BOOST_CLASS_KEY
or BOOST_CLASS_EXPORT
macro. At the same time an internal BlueSky (abbrev: BS) type identification system already require each type to have a string ID, that can be accessed via T::bs_type() method that return type_descriptor instance for given type. So, the first task is to let boost::serialization utilize string IDs that already defined for each BS type.
All manipulations with BS objects are done through custom smart pointers. Smart pointer to BS type is really intrusive (in terms of boost smart pointers), because each BS type is virtually inherited from bs_refcounter
structure that implements reference counting and contain a mutex for synchronizing access in multi-threaded environment. Boost::serialization already implement serialization of boost::shared_ptr. A review of this implementation showed that it is deeply integrated inside archive implementation, overly complex and isn't in fact suitable for serializing BS smart pointers. That's why second task is to implement serialization of smart pointers to BS types. That task was rather easy to solve, because reference counter contained inside BS object. More work to be done to implement serialization of BS smart pointer to any type and that work is still in progress.
During smart pointer serialization an object, that it points to, is serialized via simple pointer. Investigation of boost::serialization code and proof-of-concept samples showed that in such a case when object is to be loaded from saved state, the required memory is first allocated on heap (with the help of heap_allocator< T >
structure) and then default implementation of load_construct_data
invokes inplace operator new
to construct object. One can only supply custom load_construct_data
to invoke non-default class constructor and cannot change memory allocation strategy. That behavior is incompatible with existing BS objects creation method using T::bs_create_instance
static method that is registered inside kernel and later invoked by kernel.create_object
to create and construct needed object. Replacing default object creation approach for BS types is the third task.
The most appropriate way to implement serialization code for existing big project is to write it as free serialize
functions, especially when interfaces are used to reduce modules dependency. The only modification that may be required with this method is providing access to private/protected class members in serialization code. Boost::serialization already contain solution for this in form of boost::serialization::access
class. Declare it as a friend of class to serialize and you're done. But that approach doesn't work for free serialize
function. Therefore, the forth task is to develop an easy-to-use solution to providing access to class's private members from free serialize
function.
And finally, fifth task is to develop set of handy macro to reduce typing and mistakes possibility.