Boost logo

Boost Users :

Subject: Re: [Boost-users] [MultIndex] Iterator/Range validity when modify entries.
From: Joaquin M López Muñoz (joaquinlopezmunoz_at_[hidden])
Date: 2016-09-08 12:39:25


El 08/09/2016 a las 18:22, Deniz Bahadir escribió:
> Hi guys,
>
> [...]
>
> My main question is now:
> Does modifying an entry invalidate my range although I do not modify
> the member
> that was used as key for obtaining the range?
>
> The code in question would possibly look like this:
>
> <code>
>
> auto& index1 = db.get<Index1>();
> auto range = index1.equal_range(42);
>
> for (auto it = range.first; it != range.second; ++it)
> {
> index1.modify(it, [](Entry& entry)
> {
> entry.key2 = 123; // <---- Does this invalidate my range?
> // entry.key1 is not getting modified!
> });
> }
>
> </code>

Hi,

You got lucky :-) if key1 is not modified, then the element maintains
its position in
Index1 and you can safely continue iterating. The reference guarantees
that much:

http://www.boost.org/libs/multi_index/doc/reference/hash_indices.html#modify

"Postconditions: Validity of position is preserved if the operation
succeeds. If the
key of the modified value is equivalent to that of the original value,
the position of
the element does not change."

The only potential problem would be if modify fails (i.e. it returns
false) in which case
the element is erased and the iterator is no longer valid: in your code
this can't happen
as Index2 (the index whose key you're changing) is non-unique.

> My follow-up question is then:
> If the range is indeed invalidated, what would be a working solution
> for that problem?

This can only happen, as said above, when there is a collision (the
index is unique and you've
duplicated the key).

> Incrementing the loop-iterator by hand before modifying the entry (and
> not letting
> the loop do it)?
> So, would the following be a valid solution?
>
> <code>
>
> auto& index1 = db.get<Index1>();
> auto range = index1.equal_range(42);
>
> if (range.first != range.second)
> {
> auto it = range.first;
> auto end = --range.second;
> do {
> index1.modify(it++, [](Entry& entry)
> {
> entry.key2 = 123; // <---- Does this invalidate my range?
> // entry.key1 is not getting modified!
> });
> while (it != end);
> }
>
> </code>

Yep, that'd do, but you don't really need to take this precaution here as
already explained.

> [...]
>
> And one last question:
> Does this problem or its solution apply to all index-types or just to
> hashed indexes?

All index types provide the same guarantees wrt modify.

> PS: Oh and by the way: Boost.MultiIndex is a really cool library. :-)

Thank you!

Joaquín M López Muñoz


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net