Boost logo

Boost Users :

Subject: Re: [Boost-users] boost::multi_index
From: joaquin_at_[hidden]
Date: 2011-04-07 02:22:15


ppatel_at_[hidden] escribió:
> Thanks for your answer Igor. Unfortunately that is out of my control.
> This is the type of structure we used across multiple applications. I
> was checking key extractors and I think that might work but haven't
> tried out yet.
>

Hello Priyank,

Please don't top-post:
http://www.boost.org/community/policy.html#quoting

The rest of my answer below.

>>> 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….
>>>
>>> };
>>>
>>>
>>>
>>> Do I really read to specify this lengths for character arrays? If
>>> yes, how
>>> do I do that while specifying key parts as below?
>>>
>>> typedef multi_index_container <
>>>
>>> TestStruct,
>>>
>>> indexed_by<
>>>
>>> //non-unique as some subscribers might have more than one number
>>>
>>> hashed_unique<
>>>
>>> composite_key<
>>>
>>> TestStruct,
>>>
>>> member<TestStruct, char*, &TestStruct::firstKeyPart>,
>>>
>>> member<TestStruct, char*, &TestStruct::secondKeyPart>,
>>>
>>> member<TestStruct, uint32_t, &TestStruct::thirdKeyPart>,
>>>
>>> >
>>>
>>> >
>>>
>>> >
>>>
>>>
>>>> TS;
>>>>
>> The above keys will hash the pointer values, which is probably not
>> what you want.
>> If you change plain C arrays to std::string, it will work as you
>> expect.
>>

Leaving aside the fact that the syntax for member that you've used us
incorrect (see the
following example for the proper usage), Igor correctly points out that
you'd be hashing
pointers rather than the strings these arrays contain. The way to do
this is by providing
user-defined hashers and equality comparers as explained in
http://www.boost.org/libs/multi_index/doc/tutorial/key_extraction.html#composite_keys_hash

So, in your particular example we can have something like this:

  struct CStrHasher // (C) Ion Gaztañaga
  {
     std::size_t operator()(const char *str)const
     {
        std::size_t seed = 0;
        for(;*str;++str)boost::hash_combine(seed,*str);
        return seed;
     }
  };

  struct CStrEqualTo
  {
     bool operator()(const char *str1,const char *str2)const
     {
       return std::strcmp(str1,str2)==0;
     }
  };

  typedef multi_index_container<
    TestStruct,
    indexed_by<
      hashed_unique<
        composite_key<
          TestStruct,
          member<TestStruct,char[50],&TestStruct::firstKeyPart>,
          member<TestStruct,char[3],&TestStruct::secondKeyPart>,
          member<TestStruct,uint32_t,&TestStruct::thirdKeyPart>
>,
        composite_key_hash<
          CStrHasher,
          CStrHasher,
          boost::hash<uint32_t>
>,
        composite_key_equal_to<
          CStrEqualTo,
          CStrEqualTo,
          std::equal_to<uint32_t>
>
>
>
> TS;

Hope this helps,

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 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