Question

J'ai quelques difficultés à comprendre comment Boost.MultiIndex est mis en œuvre. Disons que je suit:

typedef multi_index_container<
    employee,
    indexed_by<    
        ordered_unique<member<employee, std::string, &employee::name> >,
        ordered_unique<member<employee, int, &employee::age> >
    > 
> employee_set;

Je suppose que j'ai un tableau, Employee[], qui stocke en fait les objets employee, et deux cartes

map<std::string, employee*>
map<int, employee*>

avec le nom et l'âge en tant que clés. Chaque carte a une valeur employee* qui pointe vers l'objet stocké dans le réseau. Est-ce ok?

Était-ce utile?

La solution

Une brève explication sur la structure sous-jacente est donnée ici , cité ci-dessous:

La mise en œuvre est basée sur des noeuds reliés entre eux avec des pointeurs, tout comme que votre mise en œuvre de std::set favori. Je vais élaborer un peu sur ce point: Un std::set est généralement mis en œuvre comme un rb-arbre où les nœuds ressemblent

struct node
{
  // header
  color      c;
  pointer    parent,left,right;
  // payload
  value_type value;
};

Eh bien, un nœud de multi_index_container est essentiellement un « multi-nœuds » avec autant de têtes que les indices ainsi que la charge utile. Par exemple, un multi_index_container avec deux soi-disant indices ordonnés utilise un noeud interne qui ressemble à

struct node
{
  // header index #0
  color      c0;
  pointer    parent0,left0,right0;
  // header index #1
  color      c1;
  pointer    parent1,left1,right2;
  // payload
  value_type value;
};

(La réalité est plus complexe, ces noeuds sont générés par une etc. metaprogramming mais vous voyez l'idée) [...]

Autres conseils

Conceptuellement, oui.

D'après ce que je comprends de Boost.MultiIndex (je l'ai utilisé, mais pas vu la mise en œuvre), votre exemple avec deux indices de ordered_unique sera en effet créer deux conteneurs associatifs (comme std::map triés) qui stockent des pointeurs / références / indices en un ensemble commun de employees.

Dans tous les cas, chaque employee est stockée une seule fois dans le conteneur multi-indexé, alors qu'une combinaison de map<string,employee> et map<int,employee> stockerait chaque employé deux fois.

Il se peut très bien qu'il y a en effet un tableau (dynamique) à l'intérieur des conteneurs multi-indexés, mais il y a aucune garantie que cela est vrai:

  

[indices d'accès aléatoire] ne fournissent pas contiguïté mémoire,   une propriété de std::vectors par lequel   les éléments sont stockés adjacente à une   l'autre dans un seul bloc de mémoire.

En outre,

En fait, je ne pense pas que ce soit.

Sur la base de ce qui est situé dans detail/node_type.hpp. Il me semble que comme un std::map le nœud contiendra à la fois la valeur et l'indice. Sauf que dans ce cas, les différents indices diffèrent les uns des autres et donc le nœud de se désentrelacement en fait fonction de différer l'indice que vous suivez.

Je ne suis pas sûr de ce que, en-têtes Boost sont certainement difficiles à analyser, mais il serait logique si vous pensez en terme de mémoire:

  • moins allocations: allocation plus rapide / désallocation
  • une meilleure localité de cache

Je vous serais reconnaissant une réponse définitive que, si quelqu'un sait sur le gore.

scroll top