0

I created a boost multi_index in which I am inserting objects.

My multi_index looks as follows,

typedef boost::multi_index_container<
    Container*,
    boost::multi_index::indexed_by<
        boost::multi_index::hashed_unique<
            boost::multi_index::tag<IndexByUniqueId>,
            boost::multi_index::const_mem_fun<StoreMe, Id, &StoreMe::getUId> 
        >,
        boost::multi_index::hashed_non_unique<
            boost::multi_index::tag<IndexByNonUId>,
            boost::multi_index::const_mem_fun<StoreMe, std::string, &Container::getNUIdString> 
        >
    >
> mi_Container;

When I insert objects the non-unique ID and the unique IDs are not present in the object initially. Later in the course of the program they get updated and only after that "getNUIdString" and "getUId" would return 0/non-empty values.

In that case when I try to look up using the non-unique ID I am not able to get the value stored. Is it expected that they are filled at the time of insertion? Or is it fine if they are updated as and when they are required and I can still look up my the value at that moment?

Edit1:

I understand that I would need to update the index using "replace" or "modify" while the index is changed. So is it that it initially while inserting inserts with empty string as the key for one index and 0 for the other index, and when I look up using a specific value it doesnt return me anything? Which means if I look up using the empty string "". It should return me all the values(and thus would be lookup time O(n))?

Edit2: I tried getting all the values mapped to "", empty string. I still get no results. The first of the pair of iterators is equal to the end().

Also if I wanted to change the value of the key for only one of the non_unique keys value pairs when the value is being set in the setter for that object, how would I do it? I would want to do it every time I set a value through the setter for an object, so that I am able to look it up using the multi_index I have.

TIA

-R

codeworks
  • 149
  • 1
  • 15

1 Answers1

1

With the little context you provide one can only guess. Provided that

  • you've implemented boost::hash_value and operator== correctly for your Id class (if this is really a class and not an alias for a fundamental type),
  • all the elements you've inserted have an empty string as the key for the IndexByNonUId index,
  • you really managed to insert something (i.e. the container is not empty),
  • the elements remain valid (I see they're of type Container * so they might conceivably be deleted or something),
  • you haven't changed the keys of the elements,

then looking for a null string in the IndexByNonUId index should return something different than the empty range. You might want to check all the clauses above.

Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20
  • Thanks @Joaquin! Here are the answers to your questions, – codeworks Oct 20 '16 at 07:59
  • * The Index returns a std::string * Yes * Yes, I checked it with the debugger, there are 27xxx objects in the container * I guess so, since I know they should be * Yes, I havent changed the keys of the elements, using replace or similar No, the equal_range("") returns a pair whose first is equal to the containers.end() – codeworks Oct 20 '16 at 08:02
  • Please let me know if you need some more information, I can provide it for you. Thanks again – codeworks Oct 20 '16 at 08:02
  • Does the following return any element at all? (change `c` for the name of your container) c.get().equal_range((*c.get().begin())->getNUIdString()) – Joaquín M López Muñoz Oct 20 '16 at 08:10
  • I made you statement return into a pair of iterators and the code crashed, probably the value is NULL? I will investigate and let you know – codeworks Oct 20 '16 at 10:03