Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::multi_index
From: Priyank Patel (ppatel_at_[hidden])
Date: 2011-04-08 12:34:45


Thanks a lot for replies.

On 04/08/2011 01:26 AM, joaquin_at_[hidden] wrote:
> El 07/04/2011 16:20, Dominique Devienne escribió:
>
>> On Wed, Apr 6, 2011 at 1:54 PM,<ppatel_at_[hidden]> wrote:
>>
>>> I have a question regarding creating composite key/specifying length for
>>> arrays while using multi_index container based on following structure.
>>>
>>> struct TestStruct {
>>> char firstKey[50];
>>> char secondKeyPart[3];
>>> uint32_t thirdKeyPart;
>>> ……Some other information….
>>> };
>>>
>> Using a composite key and associated hasher/equalTo types yields some
>> pretty long (and ugly?) types for the multi-index
>> container/extractor/hasher/equaler. If "……Some other information…." is
>> not too large such that TestStruct is not too expensive to construct,
>> you're often better of using the identity key extractor, and implement
>> the hasher and op== in terms of TestStruct itself. The only downside I
>> see is that you must constructs a whole new TestStruct when you want
>> to look one up instead of doing a make_tuple(part1, part2, part3),
>> which is why I mentioned above "if TestStruct is not too expensive to
>> construct". This is the route we followed, away from composite keys
>> and into custom hasher/equaler of our own structs. Not sure if Joaquin
>> also recommend that route, but it worked fine for us and makes things
>> simpler IMHO. --DD
>>
> I leans towards the composite_key solution, as it more clearly expresses the intention
> than the equivalent, hand-coded solution, but this is after all a matter of personal
> taste.
>
> As for the downside you refer to, having to create a potentially expensive TestStruct,
> Boost.MultiIndex features so-called compatible keys, which can come to the rescue here:
>
> http://www.boost.org/libs/multi_index/doc/tutorial/basics.html#special_lookup
>
> The idea is that you can simply use some structure that contains the key info without
> the overload and make this interoperable with TestStruct with respect to hashing and
> equality comparison:
>
> struct TestStructKeyInfo
> {
> TestStructKeyInfo(const char* f,const char* s,uint32_t t)
> {
> std::strcpy(firstKeyPart,f);
> std::strcpy(secondKeyPart,s);
> thirdKeyPart=t;
> }
>
> char firstKeyPart[50];
> char secondKeyPart[3];
> uint32_t thirdKeyPart;
> };
>
> std::size_t hash_value(const TestStruct& t)
> {
> std::size_t seed=0;
> for(const char* str=t.firstKeyPart;*str;++str)
> boost::hash_combine(seed,*str);
> for(const char* str=t.secondKeyPart;*str;++str)
> boost::hash_combine(seed,*str);
> boost::hash_combine(seed,t.thirdKeyPart);
> return seed;
> }
>
> std::size_t hash_value(const TestStructKeyInfo& t)
> {
> std::size_t seed=0;
> for(const char* str=t.firstKeyPart;*str;++str)
> boost::hash_combine(seed,*str);
> for(const char* str=t.secondKeyPart;*str;++str)
> boost::hash_combine(seed,*str);
> boost::hash_combine(seed,t.thirdKeyPart);
> return seed;
> }
>
> bool operator==(const TestStruct& t1,const TestStruct& t2)
> {
> return
> std::strcmp(t1.firstKeyPart,t2.firstKeyPart)==0&&
> std::strcmp(t1.secondKeyPart,t2.secondKeyPart)==0&&
> t1.thirdKeyPart==t2.thirdKeyPart;
> }
>
> bool operator==(const TestStruct& t1,const TestStructKeyInfo& t2)
> {
> return
> std::strcmp(t1.firstKeyPart,t2.firstKeyPart)==0&&
> std::strcmp(t1.secondKeyPart,t2.secondKeyPart)==0&&
> t1.thirdKeyPart==t2.thirdKeyPart;
> }
>
> bool operator==(const TestStructKeyInfo& t1,const TestStruct& t2)
> {
> return
> std::strcmp(t1.firstKeyPart,t2.firstKeyPart)==0&&
> std::strcmp(t1.secondKeyPart,t2.secondKeyPart)==0&&
> t1.thirdKeyPart==t2.thirdKeyPart;
> }
>
> so that you can define the container like this:
>
> struct TestStructHash:
> boost::hash<TestStruct>,
> boost::hash<TestStructKeyInfo>
> {
> using boost::hash<TestStruct>::operator();
> using boost::hash<TestStructKeyInfo>::operator();
> };
>
> struct TestStructEqualTo:std::equal_to<TestStruct>
> {
> using std::equal_to<TestStruct>::operator();
> bool operator()(const TestStruct& t1,const TestStructKeyInfo& t2)const
> {
> return t1==t2;
> }
> bool operator()(const TestStructKeyInfo& t1,const TestStruct& t2)const
> {
> return t1==t2;
> }
> };
>
> typedef multi_index_container<
> TestStruct,
> indexed_by<
> hashed_unique<
> identity<TestStruct>,
> TestStructHash,
> TestStructEqualTo
> >
> >
> > TS;
>
> and use TestStructKeyInfo for lookup operations:
>
> TS::iterator it=ts.find(TestStructKeyInfo("hello","ab",2));
>
> This is, after all, not much different from passing tuples around when using
> composite keys.
>
> Joaquín M López Muñoz
> Telefónica, Investigación y Desarrollo
>
>
> Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
> This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at.
> http://www.tid.es/ES/PAGINAS/disclaimer.aspx
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net