memilio icon indicating copy to clipboard operation
memilio copied to clipboard

Implement serialize() and deserialize() in World object and its members

Open khoanguyen-dev opened this issue 2 years ago • 0 comments

Motivation / Current Behaviour

As part of issue #364, the World now has a serialize() and a deserialize() function. This, however, requires to implement these functions in its member classes, including Trip, Person and Location.

For more details, see Daniel's comment: https://github.com/DLR-SC/memilio/pull/572#issuecomment-1582847162

The serialization of Locations and Persons is incomplete as far as I can tell. But here is a general comment.

Unlike the other object structures we serialize, the ABM World is a graph instead of a tree because of the pointers between locations and persons, i.e. locations storing pointers to persons and persons storing pointers to locations. Our serialization framework doesn't currently support graphs, only trees.

The easy way to serialize the World would be for Locations and Persons to serialize everything but the pointers. The World object would serialize the persons, the locations, and then the relations between locations and persons in some form (e.g. a list of location indices, one per person) so that the relations can be restored upon deserialization. The serialize/deserialize functions of the World would become more complex then usual, but manageable.

The harder but general reusable solution would be to extend the serialization framework to support graphs with pointers and references. Maybe add a function to the serializer/IOContext, add_referenced_element or something. When a pointer to an element (e.g. a Location or Person) is passed to that function:

  • the serializer stores the pointer internally
  • the serializer serializes the pointer
  • the serializer serializes the object pointed to (so the location or person) When the serializer sees a pointer that it has already seen before it only serializes the pointer, not the object, because that has already been serialized. Upon deserialization the thing is done in reverse: when a pointer is first encountered, the corresponding object is deserialized and a mapping is created between the deserialized pointer and the new memory adress of the deserialized object. When the pointer is encountered again, the new memory address is used instead of the pointer. This can be made to work with pointers, shared_ptr, references, etc, at least for objects that are created individually on the heap (e.g. with new or make_unique or make_shared). At some point during the deserialization, the original owner will take ownership of the object. For objects that are not individually created on the heap (maybe stored in a vector or as part of some other object) its more complicated.

Enhancement description

Implement serialize() and a deserialize() functions in Trip, Person and Location.

Additional context

No response

Checklist

  • [X] Attached labels, especially loc:: or model:: labels.
  • [X] Linked to project

khoanguyen-dev avatar May 26 '23 08:05 khoanguyen-dev