[boost-users][Milti-Index] labmda and composite key
Hello, I've got the following data structure: struct Service; typedef shared_ptr<Service> ServicePtr; struct Event { ServicePtr service() const; ptime time() const; }; typedef shared_ptr<Event> EventPtr; struct Cache { struct time_tag{}; typedef mi::multi_index_container< EventPtr, mi::indexed_by< mi::ordered_non_unique< mi::tag<time_tag>, mi::composite_key< EventPtr, mi::const_mem_fun<Event, ServicePtr, &Event::service> mi::const_mem_fun<Event, pt::ptime, &Event::time> > > > > type; typedef type::index<time_tag>::type ByTime; }; Cache cache_; ServicePtr servicePtr = ...; period = ...; I try to extract all the events belonging to some service and bounded by "period": namespace bl=boost::lambda; pair<Cache::type::iterator, Cache::type::iterator> byPeriod = cache_.get<Cache::time_tag>().range(bl::_1 >= make_tuple(servicePtr, period.begin()), bl::_1 <= make_tuple(servicePtr, period.last())); The cache contains lots of matching events, but for some reason, this expression always returs empty region, i.e. byPeriod.first==byPeriod.second. So I'd like to know if the above expression is correct or I'm doing something wrong? Thank you.
Just typo correction in the topic (for those who filters by keywords).
Hi Igor, Excuse my very late answering, it's only today I returned from vacation and could sit in front of a computer to study your problem. Igor R escribió:
Hello,
I've got the following data structure:
[...]
I try to extract all the events belonging to some service and bounded by "period":
namespace bl=boost::lambda; pair<Cache::type::iterator, Cache::type::iterator> byPeriod = cache_.get<Cache::time_tag>().range(bl::_1 >= make_tuple(servicePtr, period.begin()), bl::_1 <= make_tuple(servicePtr, period.last()));
The cache contains lots of matching events, but for some reason, this expression always returs empty region, i.e. byPeriod.first==byPeriod.second.
As far as I can see your expression is correct and should work as you intend. I've written a small complete program that simulates your scenario and everything works fine (see attached file). Maybe you can have a look a it and check for similarities/differences with your code. Rereading your question, I realize that the first key of your composite key compares ServicePtrs, which is not the same as comparing the pointed to Services. Maybe your problem is related to this? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/mem_fun.hpp> #include <boost/lambda/lambda.hpp> #include <boost/shared_ptr.hpp> #include <iostream> using boost::shared_ptr; namespace mi=boost::multi_index; namespace pt{typedef unsigned ptime;} struct Service{}; typedef shared_ptr<Service> ServicePtr; struct Event { ServicePtr service() const{return service_;} unsigned time() const{return time_;} Event(const ServicePtr& service_,unsigned time_): service_(service_),time_(time_){} private: ServicePtr service_; unsigned time_; }; typedef shared_ptr<Event> EventPtr; struct Cache { struct time_tag{}; typedef mi::multi_index_container< EventPtr, mi::indexed_by< mi::ordered_non_unique< mi::tag<time_tag>, mi::composite_key< EventPtr, mi::const_mem_fun<Event, ServicePtr, &Event::service>, mi::const_mem_fun<Event, pt::ptime, &Event::time> > > > > type; typedef type::index<time_tag>::type ByTime; }; int main() { Cache::type cache_; ServicePtr servicePtr=ServicePtr(new Service); ServicePtr servicePtr2=ServicePtr(new Service); unsigned period_begin=0; unsigned period_last=1; cache_.insert(EventPtr(new Event(servicePtr,0))); cache_.insert(EventPtr(new Event(servicePtr,1))); cache_.insert(EventPtr(new Event(servicePtr,2))); cache_.insert(EventPtr(new Event(servicePtr2,0))); namespace bl=boost::lambda; using std::pair; pair<Cache::type::iterator, Cache::type::iterator> byPeriod = cache_.get<Cache::time_tag>().range(bl::_1 >= make_tuple(servicePtr, period_begin), bl::_1 <= make_tuple(servicePtr, period_last)); for(;byPeriod.first!=byPeriod.second;++byPeriod.first){ std::cout<<(*byPeriod.first)->service()<<" "<<(*byPeriod.first)->time()<<std::endl; } }
Hi Joaquín,
As far as I can see your expression is correct and should work as you intend.
Thank you! It apperas that the problem was in the criteria initialization.
Rereading your question, I realize that the first key of your composite key compares ServicePtrs, which is not the same as comparing the pointed to Services. Maybe your problem is related to this?
The idea itself was correct (I wanted to use the shared_ptr's equality), but the implementation was bad - the ptrs were improperly initialized. Thank you again, Igor'.
participants (2)
-
Igor R
-
joaquin@tid.es