multi_index, best way to do insert_or_replace

Hi, I misread (or didn't read) the boost::multi_index_container documentation and assumed 'insert' on a unique index would do 'replace', but of course it doesn't and shouldn't. So, I've made this change: - s_negcache.insert(ne); + + pair<negcache_t::iterator, bool> res=s_negcache.insert(ne); + if(!res.second) { + s_negcache.erase(res.first); + s_negcache.insert(ne); + } But I can't help feeling there is probably a better and prettier way. Do people have any suggestions? In this case, ne is a NegCacheEntry, defined as: struct NegCacheEntry { string d_name; QType d_qtype; string d_qname; uint32_t d_ttd; }; And the index: typedef multi_index_container < NegCacheEntry, indexed_by < ordered_unique< composite_key< NegCacheEntry, member<NegCacheEntry, string, &NegCacheEntry::d_name>, member<NegCacheEntry, QType, &NegCacheEntry::d_qtype> >, composite_key_compare<CIStringCompare, std::less<QType> > >, ordered_non_unique< member<NegCacheEntry, uint32_t, &NegCacheEntry::d_ttd> >
negcache_t;
Thanks! -- http://www.PowerDNS.com Open source, database driven DNS Software http://netherlabs.nl Open and Closed source services

bert hubert ha escrito:
Hello Bert, You can do it more efficiently by using replace() instead of deleting and reinserting on collision. The following packages the entire procedure template<typename Index> std::pair<typename Index::iterator,bool> replacing_insert(Index& i,const typename Index::value_type& x) { std::pair<typename Index::iterator,bool> res=i.insert(x); if(!res.second)res.second=i.replace(res.first,x); return res; } So that you can say pair<negcache_t::iterator, bool> res=replacing_insert(s_negcache,ne); Note that replacing_insert() still cannot guarantee in the general case that insertion will always be succesful (hence its returning a pair<iterator,bool>): failure happens if two or more distinct elements are colliding with the value to be inserted. Check the attached code for an example of a failing call to replacing_insert(). HTH, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

On Fri, Apr 28, 2006 at 10:22:49AM +0200, Joaqu?n M? L?pez Mu?oz wrote:
pair<negcache_t::iterator, bool> res=replacing_insert(s_negcache,ne);
Works, thank you (again) Joaquin! See http://wiki.powerdns.com/projects/trac/changeset/785
Note that replacing_insert() still cannot guarantee in the general case that insertion will always be succesful (hence its returning a pair<iterator,bool>):
Indeed - but in this case I know there is only one unique index, so I don't check. Thanks! -- http://www.PowerDNS.com Open source, database driven DNS Software http://netherlabs.nl Open and Closed source services
participants (2)
-
bert hubert
-
Joaquín Mª López Muñoz