re: #30510 (review)
I’m having a hard time reading this TODO. Can you try and reformulate it?
I’m removed the TODO since it’s a low-priority efficiency improvement. Basically, there are 2 ways to call CustomReadField
and there are 2 ways to deserialize certain objects, and the code is not currently choosing the most efficient way to deserialize based on the way it is called.
To explain further, the CustomReadField
function is responsible for converting one field of a capnproto struct into a C++ object. (This C++ object will be an input parameter passed to a function in the IPC server process, or it will be an output parameter, return value, or an exception to be thrown in the IPC client process.)
One way to call CustomReadField
is to pass a ReadDestEmplace
object as the read_dest
parameter. The other way to call it is to pass a ReadDestValue
object as the read_dest
parameter.
You pass ReadDestValue
when you want the CustomReadField
implementation to read some capnpproto struct field and use the content to update an existing C++ object. ReadDestValue
just contains a reference to the object that should be updated.
You pass ReadDestEmplace
when there is no existing C++ object and you want the CustomReadField
implementation to read a capnproto field and construct a new C++ object from it by calling an emplace function. ReadDestEmplace
is needed if the C++ type is immutable like CTransaction
and can’t be modified after is created. It is also useful for mutable objects if they are being used as std::map
keys, because std::map
keys are const, so it is less awkward and more efficient to call std::map::emplace
than try to read the capnproto field into a temporary object and then try to move that object into the std::map
.
As for the TODO, the TODO is just saying right now if a C++ class has both a deserialize_type
constructor and an Unserialize
method, the current CustomReadField
implementation will always prefer calling the deserialize_type
constructor. This works and is ideal if ReadDestEmplace
is passed, but is not ideal if ReadDestValue
is passed, because that requires the existing C++ object to be destroyed and reconstructed to call the deserialize_type
constructor, when probably it would be more efficient to call the Unserialize
method instead. So the TODO describes a libmultiprocess modification which would enable that.