boost multi-index container find method.

Hello Joaquin, I have a class like below that uses mult-index container's find method. I have a record pattern as below initially: Idx : 100 Flag : 5 Idx : 200 Flag : 5 Idx : 300 Flag : 5 Idx : 400 Flag : 5 I modify the flag for index 100 to 6 & take a dump, the change is OK Idx : 100 Flag : 6 Idx : 200 Flag : 5 Idx : 300 Flag : 5 Idx : 400 Flag : 5 I modify the flag for 100 back to 5 and take a dump, which is also fine. Idx : 100 Flag : 5 Idx : 200 Flag : 5 Idx : 300 Flag : 5 Idx : 400 Flag : 5 Now I do a find based on flag value set to 5 I get the results as below: Idx : 200 flag : 5 While find functionally is correct in picking up the correct data, but I am wondering why it doesnt pick the first record (100) which has the flag value set to 5? am I missing something in the indexing definition in the container itself? Thanks /R ========================= using namespace std; #include <boost/lambda/lambda.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/member.hpp> #include <iostream> #include <iterator> #include <iostream> #include <string> struct Token { unsigned long mIdx; unsigned char mflag; public: Token(unsigned long pIdx, unsigned char pflag): mIdx(pIdx), mflag(pflag){} void Update(unsigned char pflag) { mflag = pflag; } ~Token() { mIdx = 0; mflag = 1; } }; struct mIdx{}; struct mflag{}; using namespace boost::multi_index; namespace ll = boost::lambda; typedef multi_index_container< Token, indexed_by< ordered_unique< tag <mIdx>, BOOST_MULTI_INDEX_MEMBER(Token,unsigned long,mIdx)>, ordered_non_unique< tag <mflag>, BOOST_MULTI_INDEX_MEMBER(Token,unsigned char,mflag)> >
tToken;
class TokenMaster { tToken TokenContainer; public: unsigned long getByFlag(unsigned long useFlag); bool modify(unsigned long idx, unsigned char flag); bool insert(unsigned long, unsigned char); void dump(); }; unsigned long TokenMaster::getByFlag(unsigned long useFlag) { typedef tToken::index<mflag>::type itflag; itflag& mflag_index = TokenContainer.get<mflag>(); tToken::index_iterator<mflag>::type flagit = mflag_index.find(useFlag); if (flagit == mflag_index.end()) { return 0; } printf("Idx : %d flag : %d\n", flagit->mIdx, flagit->mflag); return flagit->mIdx; } bool TokenMaster::modify(unsigned long idx, unsigned char flag) { tToken::iterator itIp=TokenContainer.find(idx); if (itIp == TokenContainer.end()) return false; return TokenContainer.modify(itIp,(&ll::_1)->*&Token::mflag=flag); } bool TokenMaster::insert(unsigned long idx, unsigned char flag) { tToken::iterator it; bool secres; std::pair<tToken::iterator, bool> result = TokenContainer.insert(Token(idx, flag)); it = result.first; secres = result.second; if (secres) return true; else return false; } void TokenMaster::dump() { unsigned long count = 0; printf("\n\n List of indexes\n"); for (tToken::iterator it = TokenContainer.begin(), it_end=TokenContainer.end(); it != it_end; ++it, count++) { printf("Idx : %d Flag : %d\n", it->mIdx, it->mflag); } printf("\n"); } main() { TokenMaster T1; T1.insert(100, 5); T1.insert(200, 5); T1.insert(300, 5); T1.insert(400, 5); T1.dump(); printf("Modifiying 100 to 6\n"); T1.modify(100, 6); T1.dump(); printf("Modifiying 100 back to 5\n"); T1.modify(100, 5); T1.dump(); printf("\n\nGet by flag \n"); T1.getByFlag(5); } ==========================

Ramesh <rramesh1 <at> gmail.com> writes:
Hello Joaquin,
Hi Ramesh,
[...]
find() returns an element with the searched key in case there is one, but note that no guarantee is made about which element is returned when there are several to choose from (in case you're curious: ordered indices are internally implemented as rd-trees, and find simply returns the first element found when traversing the tree topdown). Even if you use lower_bound() to find the first element of the range, there is no guarantee that (100,5) appears the first on the flag-based index. You can follow Igor's advice on using a composite key here. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (3)
-
Igor R
-
Joaquin M Lopez Munoz
-
Ramesh