Re: [Boost-users] [multi_index] Serialization problemwithmulti_indexcontainer
----- Mensaje original -----
De: John Reid
Joaquín Mª López Muñoz wrote:
What this means is, if you've got elements a,b and its corresponding deserialized equivalents a',b', then a
Ok thanks, that makes sense. I should have read that.
My value_type has a data member that is a pointer to an object of an abstract class. I would like one index to be sorted by the addresses of these objects.
Yep, here's the problem, addresses' order is not preserved.
There seems no way to do this and have direct serialisation of the multi_index container. Can you confirm?
Yes, I'm afraid you can't directly serialize a multi-index container one of whose indices is of type ordered_non_unique and the key is the address of some mmember (or the whole element.) You'll have to stick to your current workaround --but you can improve it a bit: you don't really need to use an intermediate vector if you do the serialization process "by hand": save: save the number of elements. traverse the first index and save he visited elements. load: clear the container. load the number of elements N. repeat N times: load an element and insert it into the container. The overall effect is the same as with the intermediate vector, without any extra overhead.
Maybe I'm missing something. Is there a reason why the serialisation implementation does not recalculate the indices on the fly?
Well, this is prewisely what's happening. Consider the following:
struct element
{
element(int x,int y,int z):x(x),y(y),z(z){}
int x,y,z;
};
typedef multi_index_container<
element,
indexed_by<
ordered_non_unique
multi_index_t;
multi_index t m; element a(0,1,0); element b(1,1,1); element b(2,1,2); m.get<1>()insert(a); m.get<1>().insert(b,m.get<1>().begin()); m.get<1>().insert(c,m.get<1>().begin()); Now, if you traverse m by its index #0, the result is (0,1,0), (1,1,1), (2,1,2) whereas if you traverse it by index #1, the order is, because of our use of hinted insertion, the following: (0,1,0), (2,1,2), (1,1,1) So far so good. When saving and subsequently loading this container, Boost.MultiIndex guarantees that the traversal order of *every* index is preserved. Now, suppose serialization were implemented the naive way, that is, by just saving the elements as they are visited by the first index and loading through the first index again, just as you're doing in your workaround (no offense meant by the use of the word "naive", of course.) If you examine the process carefully, you can see that, when performed this way, index #0 is correctly replicated, but the resulting order of the loaded index #1 is (0,1,0), (1,1,1), (2,1,2) which does not match the original. This is why Boost.MultiIndex saves, additionally to the elements, enough extra information to restore index traversal orders in those cases where such order is not univocally determined (ordered non-unique, sequenced and random-access indices.) And when applying this extra information, the kind of sanity check you've been bitten by is routinely performed. I hope I've made myself clear, sorry for the long explanation.
Thanks for your response, John.
Thank you for using Boost.MultiIndex. I'm sorry out-of-the-shelf serialization capabilities can't serve your particular needs. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
JOAQUIN LOPEZ MU?Z wrote:
So far so good. When saving and subsequently loading this container, Boost.MultiIndex guarantees that the traversal order of *every* index is preserved. Now, suppose serialization were implemented the naive way, that is, by just saving the elements as they are visited by the first index and loading through the first index again, just as you're doing in your workaround (no offense meant by the use of the word "naive", of course.) If you examine the process carefully, you can see that, when performed this way, index #0 is correctly replicated, but the resulting order of the loaded index #1 is
(0,1,0), (1,1,1), (2,1,2)
which does not match the original. This is why Boost.MultiIndex saves, additionally to the elements, enough extra information to restore index traversal orders in those cases where such order is not univocally determined (ordered non-unique, sequenced and random-access indices.) And when applying this extra information, the kind of sanity check you've been bitten by is routinely performed. I hope I've made myself clear, sorry for the long explanation.
Thanks for the very clear explanation. "Bitten by" is a kind way of saying "corrected by"! John.
participants (2)
-
JOAQUIN LOPEZ MU?Z
-
John Reid