|
Boost : |
From: Preston A. Elder (prez_at_[hidden])
Date: 2006-04-04 14:10:45
Robert Ramey <ramey_at_[hidden]> wrote:
> This would be done by setting the serialization trait "tracking" to
> track_never. This would inhibit the checking for duplicates. This
> would occur before it gets to the stream buf implementation
This has one other side-effect though. It also means I cannot have
pointer references.
Consider, say, a tree - where nodes have pointers to the next entry,
parent entry, and first child entry. I want to be able to pass a node,
and have those pointers re-established, just as it would with tracking
on. However I also want to be able to re-pass a node if it gets
updated (eg. if its a 'node with data' or even if I now have a new
first child or a new next sibling). Assume for this case, that a node
is serialized on creation, and its pointers will either be NULL or
refer to previously serialized objects.
Turning off tracking means it does not know how to re-establish those
links, and I'd end up with duplicate copies of the same node. As
previously mentioned - being able to serialize the same object over and
over is only part of replication - the real core is to be able to
UPDATE a node that has been previously serialized, without having to
a) de-serialize a new object, lookup the object and then operator=.
and b) forego being able to serialize a pointer to that class-type and
have it realize it has already seen that class and thus just make it
point to the same thing.
Right now, I'm going to hack my way around it by having tracking turned
on, so my pointers get re-established, and create a derived class that
exists just to create a new type that I can disable tracking for (since
using a typedef will not work). The idea being that if the object has
already been serialized once, I'll follow up the object with a derived
version of the object. The deserializing procedure will then similarly
check to see if its previously deserialized and if so, expect a
follow-up object and then just operator= the original object (a pointer
to which I will have thanks to deserialization's tracking) with the
follow-up object.
Or, pseudocode would be:
Serialize:
Object *myobj = ...;
/* ... */
ar & myobj;
if (myobj->previously_serialized())
ar & (NonTrackingObject *) myobj;
Deserialize:
Object *myobj;
ar & myobj;
if (myobj->previously_deserialized())
ar & *myobj;
If my understanding is correct, if a tracking object has previously
been serialized (by pointer), any further attempt to deserialize a
pointer to that object will merely set the pointer to the previous
deserialized version. Thus when a previously deserialization has
happened, the first ar & myobj will only set myobj's pointer, and the
second, because the object in this case is non-tracking, it will have
the actual data I need, and since I deserialize to the deferenced
pointer, it will deserialize into that object.
Of course, any other place I deserialize the same pointer, I would not
do this check, since I want only a reference.
-- PreZ :) Death is life's way of telling you you've been fired. -- R. Geis
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk