Boost logo

Boost :

From: JOAQUIN LOPEZ MU?Z (joaquin_at_[hidden])
Date: 2006-06-27 17:36:56


Hello Felipe,

----- Mensaje original -----
De: Felipe Magno de Almeida <felipe.m.almeida_at_[hidden]>
Fecha: Martes, Junio 27, 2006 10:48 pm
Asunto: [boost] [multi_index] Working with a composite key of keys
with different sorting criterias

> Hi,
>
> First of all, I've read the documentation but I couldnt find the
> information I'm looking for. In fact the example composite_keys.cpp
> confused me even more.
>
> What I want to do is:
>
> I have a record that has two keys: domain and path.
> The domain is sorted by its end, so:
> .google.com
> abc.google.com
>
> .google.com is less than abc.google.com
>
> And path is sorted as usual:
>
> / is less than /abc
>
> But I'm not being able to figure out how to create a composite key
> with both keys.

I'm not completely sure where you're having trouble,
but I guess it's in how to use composite_key_compare
(introduced at http://tinyurl.com/acw5v at the end of the
section.) So, if your record class is something like:

struct record
{
  record(const std::string& domain,const std::string& path):
    domain(domain),path(path)
  {}
  
  std::string domain;
  std::string path;
};

and you use the following predicate to do reverse comparison:

struct reverse_str_less
{
  bool operator()(const std::string& x,const std::string& y)const
  {
    return std::lexicographical_compare(
      x.rbegin(),x.rend(),y.rbegin(),y.rend());
  }
};

then the composite_key you're after can be defined as follows:

typedef multi_index_container<
  record,
  indexed_by<
    ordered_unique<
      composite_key<
        record,
        member<record,std::string,&record::domain>,
        member<record,std::string,&record::path>
>,
      composite_key_compare<
        reverse_str_less,
        std::less<std::string>
>
>
>
> multi_index_t;

Does this help, or is your problem elsewhere? Complete
snippet attached.

>
> One question came up with the composite_keys.cpp:
>
> struct name_key:composite_key<
> file_entry,
> BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry*,dir),
> BOOST_MULTI_INDEX_MEMBER(file_entry,std::string,name)
> >{};
>
> The dir member will be ordered by its pointer value right?

...Yes. More precisely, file_entry elements will be sorted
by their dir member pointer value (and subsorted by their name.)

> I cant see
> much sense in this ordering since its completely platform
> independent.

[I guess you mean "dependent".] Well, sorting by pointer value
makes all entries under the same directory (i.e. with the same
"dir" pointer) to be kept together. What it's platform dependent
is the order in which different directory clusters appear, but
the example does not make any assumption about that. Have I
explained this sufficiently clear? (I'm not sure I made my
point through.)

> Shouldnt be by its directory name and path?
>
> Thanks in advance,
> --
> Felipe Magno de Almeida

Thanks for using Boost.MultiIndex. Best regards,

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk