c++ boost multi-index boost-multi-index

c++ - cómo se implementa el impulso multi_index



boost multi-index (3)

Tengo algunas dificultades para entender cómo se implementa Boost.MultiIndex. Digamos que tengo lo siguiente:

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

Me imagino que tengo una matriz, Employee[] , que almacena los objetos de los employee , y dos mapas

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

Con nombre y edad como claves. Cada mapa tiene un valor de employee* que apunta al objeto almacenado en la matriz. ¿Esta bien?


Conceptualmente, sí.

Por lo que entiendo de Boost.MultiIndex (lo he usado, pero no he visto la implementación), su ejemplo con dos índices de ordered_unique creará dos contenedores asociativos ordenados (como std::map ) que almacenan punteros / referencias / índices en un conjunto común de employee s.

En cualquier caso, cada employee se almacena solo una vez en el contenedor multi-indexado, mientras que una combinación de map<string,employee> y map<int,employee> almacenaría cada empleado dos veces.

Puede muy bien ser que exista una matriz (dinámica) dentro de algunos contenedores multi-indexados, pero no hay garantía de que esto sea cierto:

[Los índices de acceso aleatorio] no proporcionan contigüidad de memoria, una propiedad de std::vector s por la cual los elementos se almacenan adyacentes entre sí en un solo bloque de memoria.

Además, Boost.Bimap se basa en Boost.MultiIndex y el primero permite diferentes representaciones de su estructura "troncal".


En realidad no creo que lo sea.

Basado en lo que se encuentra en detail/node_type.hpp . Me parece que, como un std::map el nodo contendrá tanto el valor como el índice. Excepto que, en este caso, los distintos índices difieren entre sí y, por lo tanto, el entrelazado de nodos diferiría en función del índice que esté siguiendo.

Sin embargo, no estoy seguro de esto, los encabezados de Boost son definitivamente difíciles de analizar, sin embargo, tendría sentido si piensas en términos de memoria:

  • Menos asignaciones: asignación / desasignación más rápida
  • mejor localidad de caché

Sin embargo, agradecería una respuesta definitiva, si alguien sabe sobre el gore.


Una breve explicación sobre la estructura subyacente se da here , citada a continuación:

La implementación se basa en nodos interconectados con punteros, al igual que su implementación std::set . Elaboraré un poco sobre esto: un std::set generalmente se implementa como un árbol rb donde los nodos se ven como

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

Bueno, el multi_index_container un multi_index_container es básicamente un "multinodo" con tantos encabezados como índices y la carga útil. Por ejemplo, un multi_index_container con dos denominados índices ordenados utiliza un nodo interno que parece

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 realidad es más complicada, estos nodos se generan a través de alguna metaprogramación, etc. pero se tiene la idea) [...]