【问题标题】:how boost multi_index is implementedboost multi_index 是如何实现的
【发布时间】:2011-05-11 12:26:28
【问题描述】:

我很难理解 Boost.MultiIndex 是如何实现的。假设我有以下内容:

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

我想我有一个数组Employee[],它实际上存储了employee 对象和两个映射

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

以姓名和年龄为键。每个映射都有employee* 值,它指向数组中存储的对象。这样可以吗?

【问题讨论】:

标签: c++ boost multi-index boost-multi-index


【解决方案1】:

在here给出了底层结构的简短解释,引用如下:

该实现基于与指针互连的节点,就像您最喜欢的std::set 实现一样。我将对此进行详细说明:std::set 通常实现为节点看起来像的 rb-tree

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

嗯,multi_index_container 的节点基本上是一个“多节点”,其标头与索引以及有效负载一样多。例如,带有两个所谓的有序索引的multi_index_container 使用的内部节点看起来像

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

(现实更复杂,这些节点是通过一些元编程等生成的,但你明白了)[...]

【讨论】:

  • +1,准确地解释了 OP 的用例。我想知道 Boost.MultiIndex 是否在内部使用了 Boost.Intrusive?
  • 不,Boost.MultiIndex 不使用 Boost.Intrusive,主要是因为前者的库比后者的旧。不过,根据 Boost.Intrusive 重写原则上是可行的。
  • @JoaquínMLópezMuñoz:我知道这是一个旧答案,但是如果您可以在此处发布您的电子邮件摘录,那就太好了。 SO 问题和答案中的指导方针是直接提供详细信息,以便链接腐烂或离线查看不会显着降低其价值。
  • @JoaquínMLópezMuñoz:谢谢!!
【解决方案2】:

从概念上讲,是的。

根据我对 Boost.MultiIndex 的理解(我已经使用过,但没有看到实现),您的示例带有两个 ordered_unique 索引确实会创建两个存储指针的排序关联容器(如 std::map)/引用/索引到一组通用的employees。

在任何情况下,每个employee 在多索引容器中只存储一次,而map&lt;string,employee&gt; 和map&lt;int,employee&gt; 的组合将存储每个员工两次。

很可能在某些多索引容器中确实存在一个(动态)数组,但有no guarantee 表明这是真的:

[随机访问索引]不提供内存连续性, std::vectors 的属性 元素相邻存储 另一个在单个内存块中。

此外,Boost.Bimap is based on Boost.MultiIndex 和前者允许其“主干”结构的不同表示形式。

【讨论】:

    【解决方案3】:

    其实我不这么认为。

    基于detail/node_type.hpp 中的内容。在我看来,就像std::map 一样,节点将包含值和索引。除了在这种情况下,各种索引彼此不同,因此节点交错实际上会根据您所关注的索引而有所不同。

    虽然我不确定这一点,Boost 标头肯定很难解析,但是如果你从内存的角度考虑它会很有意义:

    • 更少的分配:更快的分配/解除分配
    • 更好的缓存局部性

    如果有人知道血腥,我将不胜感激。

    【讨论】:

      猜你喜欢
      • 2017-01-23
      • 2017-01-27
      • 2016-03-23
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多