Fix multicontainer deserialization #874
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Subject
As reported in this issue ( #865 ), deserialization of the std::multimap and std::multiset breaks the container invariants. These containers are expected ( by the standard ), to maintain the relative (insertion) order of the values who's keys evaluate as equivalent.
The
loadmethod for these containers usesinsert_hint(hint, value)( oremplace_hint) methods to add values to the container during load. This results in reversing the order of the elements with equivalent keys, because the method places the new element before thehintinstead of after.Solution
Implement handlers for these method separately instead of generically. Regular emplace is needed in order to maintain the insertion order of equivalent keys. For keys that are not equivalent there is no expectation of order so they can be placed in any order. In order to still maintain the benefits of the faster
emplace_hint, it is still used when the current key is not equivalent to the previous. If the current key is equivalent to the previous key,emplaceneeds to be used.Testing
By running the following cmake commands old I asserted that the current behaviour was not broken:
The new behaviour was tested using the script given in the original issue.
Compilation issues
The cmake build seems to be broken in some files. In order to build the test at all the following diffs were applied: