Update the index of a hashed_non_unique entry in boost::multiindex
I have a boost::multiindex container which has an index as follows :
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByNonUniqueId>,
boost::multi_index::const_mem_fun
On Mon, Oct 24, 2016 at 6:35 AM, Ram
I have a boost::multiindex container which has an index as follows :
boost::multi_index::hashed_non_unique<
boost::multi_index::tag<IndexByNonUniqueId>,
boost::multi_index::const_mem_fun
>
This ID comes in as ""(empty string) when I initially get the object. I add it to the multiindex at this point. But later in the course of the program the ID gets populated using its "setNonUniqueId" method. At this point of time inside "setNonUniqueId" I would like to update the index to the object(in the multiindex) as well(while the ID is being updated from "" to something concrete). How do I do this? How do I locate the specific object and update the index
You must notify the BMI of the change, or more exactly, you must do the change via the index's modify() [1] method. Don't update the field first, since that changes the hash behind the BMI's back, breaking its invariants. While working on this code, you may want to set this define [3] in debug builds to catch such invariant-breaking mistakes. Update the field via the functors you pass to the index's modify() method. You do need an iterator to pass to modify(), and for that you typically use one of your unique indexes, which you then project() [2] into the non-unique index you want to update. --DD [1] http://www.boost.org/doc/libs/1_62_0/libs/multi_index/doc/reference/hash_ind... [2] http://www.boost.org/doc/libs/1_62_0/libs/multi_index/doc/reference/multi_in... [3] http://www.boost.org/doc/libs/1_62_0/libs/multi_index/doc/tutorial/debug.htm...
Hi Devienne, I am not sure I understood a few things you said like, [ While working on this code, you may want to set this define [3] in debug builds to catch such invariant-breaking mistakes. Update the field via the functors you pass to the index's modify() method. ] and [ Update the field via the functors you pass to the index's modify() method. ] Does this, [ You do need an iterator to pass to modify(), and for that you typically use one of your unique indexes, which you then project() [2] into the non-unique index you want to update. ] mean I would need to iterate using the unique key and find the object I want to update and change this non-unique key to the new one? Thanks, Ram
On Mon, Oct 24, 2016 at 9:27 AM, Ram
I am not sure I understood a few things you said like, [...] Does this, [...] mean I would need to iterate using the unique key and find the object I want to update and change this non-unique key to the new one?
No. Perhaps the pseudo C++11 code below will help? Lets assume your unique index is the first index (index = 0), and the non-unique one is second index (index = 1). using bmi_t = ...; bmi_t& bmi = /*get the BMI container*/; auto& uniq_idx = bmi.get<0>(); auto unique_idx_iter = uniq_idx.find(uniq_key); if (unique_idx_iter == uniq_idx.end()) return; auto nonunique_iter = bmi.project<1>(unique_idx_iter); auto& nonuniq_idx = bmi.get<0>(); bool ok = nonuniq_idx.modify(nonunique_iter, [&new_value](bmi_t::value_type& element) { element.setNonUniqueIdString(new_value); }); if the modification could be veto'd by any of your indexes, you'd probably use the overload with a Rollback functor. For actual code, I'm sure there's an example in your Boost install. --DD PS: If you don't have a unique index and unique key for your element, then indeed you need to iterate on your container (or non-unique index), and figure out in an ad-hoc way which exact element you want to modify. (and need to project<1>() only if not iterating on the index you want to modify).
participants (2)
-
Dominique Devienne
-
Ram