【问题标题】:Clarification about Boost multi-index container关于 Boost 多索引容器的说明
【发布时间】:2015-11-20 16:40:11
【问题描述】:

我正在尝试了解 Boost 多索引,请寻求帮助。

数据如下:

 index1, index2, index3, index4, value
 alpha   a       1       101     0.5
 alpha   a       1       102     0.6
 ...    ...     ...     ....     ...
 alpha   a       1       120     0.7
 alpha   a       2       101     0.3
 ...    ...     ...     ....     ... 
 alpha   a       2       101     0.3
 alpha   b       1       101     0.3
 ...    ...     ...     ....     ...
 beta   a       1       101     0.7
 ...    ...     ...     ....     ...

现在我已经创建了一个结构:

struct data
{
   data(std::string index1,
      std::string index2,
      int index3,
      int index4,
      double value):index1_(index1),index2_(index2),index3_(index3),
      index4_(index4),value_(value){}
    std::string index1_;
    std::string index2_;
    int index3_;
    int index4_;    
    double value_;
};

还有:

struct index1{};
struct index2{};
struct index3{};
struct index4{};
struct value{}; // I guess i do not need this because this is a data point
                // and not an index. Can someone please comment ?

接下来我创建了一个 typedef,如下所示:我不确定是使用“ordered_unique”还是“ordered_non_unique”。有人可以帮忙吗。

我很困惑,因为 4 元组 (index1,index2,index3,inde4) 是指向数据值的唯一坐标。但是对于它们中的每一个,都会重复出现(例如,对于 index1,字符串“alpha”会重复多次)

typedef boost::multi_index::multi_index_container<
    data, boost::multi_index::indexed_by<
           boost::multi_index::ordered_unique<boost::multi_index::tag<index1>,boost::multi_index::member<data, std::string,&data::index1_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index2>,boost::multi_index::member<data, std::string,&data::index2_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index3>,boost::multi_index::member<data, int,&data::index3_> >,
           boost::multi_index::ordered_unique<boost::multi_index::tag<index4>,boost::multi_index::member<data, int,&data::index4_> >,

     // not sure if I need the line below. because it is not an index

           boost::multi_index::ordered_unique<boost::multi_index::tag<value>,boost::multi_index::member<data, double,&data::value_> >,
       >
    > data_map;  

接下来在 main() 中,我通过遍历每个数据点并执行如下插入操作来填充数据:

 data_map DATA;
 DATA.insert(data(alpha,a,1,101,0.5));

之后,我想检查一下 index4 的范围是多少(即最小值和最大值是多少)。我正在尝试类似:

    const boost::multi_index::index<data_map,index4>::type& in_index4 = boost::multi_index::get<index4>(DATA);
    int nIndex4 = in_index4.size(); // I do not get the correct size here

当我尝试时,我也没有得到预期的结果。

    boost::multi_index::index<data_map,index4>::type::const_iterator index_itr=in_index4.begin();
    for(;index_itr!=in_index4.end();index_itr++)
    {
        int xx = (*index_itr).index4_;
    }

有人可以指出我的错误并帮助我理解。 在此先感谢

【问题讨论】:

  • 你真的想做几何相关的事情吗? (Boost Geometry 索引可能是一个更好的主意)。或者是图像数据(考虑 Boost GIL)。无论如何,请考虑将(index1,index2,index3,index4) 设为一个类型。
  • 再次感谢。你的回答消除了我的困惑。我将检查升压几何。我没有做任何图像处理或与几何相关的事情(但也许它可以被映射。但不确定,我必须考虑一下)。我正在尝试处理带有大量“标签”的大数据(在这种情况下是索引)。类似于“Essbase”立方体所做的事情。
  • 这就是所谓的OLAP。我会为此考虑优化存储(可能在内存映射段中),或现有关系数据的适当 ROLAP 视图(使用现有工具!)

标签: c++ dictionary boost


【解决方案1】:

问。

struct value{}; // I guess i do not need this because this is a data point
                // and not an index. Can someone please comment ?

仅创建您使用的索引。

问。我不确定是使用ordered_unique 还是ordered_non_unique。有人可以帮忙吗。

我很困惑,因为 4 元组 (index1,index2,index3,inde4) 是指向数据值的唯一坐标。但是对于它们中的每一个,都会重复出现(例如,对于 index1,字符串“alpha”会重复多次)

你需要一个复合键的唯一索引:

bmi::indexed_by<
    bmi::ordered_unique<
        bmi::composite_key<data,
            bmi::member<data, std::string, &data::index1_>,
            bmi::member<data, std::string, &data::index2_>,
            bmi::member<data, int,         &data::index3_>,
            bmi::member<data, int,         &data::index4_>
        >
    >
>

Q.接下来在 main() 中,我通过遍历每个数据点并执行如下插入操作来填充数据:

我可以建议统一初始化吗:

Table table {
    //index1, index2, index3, index4, value
    data {   "alpha", "a", 1, 101, 0.5 },
    data {   "alpha", "a", 1, 102, 0.6 },
    // ...
    data {   "alpha", "a", 1, 120, 0.7 },
    data {   "alpha", "a", 2, 101, 0.3 },
    // ...
    data {   "alpha", "a", 2, 101, 0.3 },
    data {   "alpha", "b", 1, 101, 0.3 },
    // ...
    data {   "beta",  "a", 1, 101, 0.7 },
};

问。之后,我想检查一下 index4 的范围是多少(即最小值和最大值是多少)。我正在尝试类似:

  const boost::multi_index::index<data_map,index4>::type& in_index4 = boost::multi_index::get<index4>(DATA);
  int nIndex4 = in_index4.size(); // I do not get the correct size here

size() 无论如何都会返回容器中元素的数量。您可以添加索引

bmi::ordered_non_unique<
    bmi::tag<struct index4>, bmi::member<data, int, &data::index4_>
>

并“利用”它是有序的事实:

int min4 = table.get<index4>().begin() ->index4_;
int max4 = table.get<index4>().rbegin()->index4_;

完整演示

Live On Coliru

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <string>
#include <iostream>

struct data
{
    std::string index1_;
    std::string index2_;
    int         index3_;
    int         index4_;
    double      value_;
};

namespace bmi = boost::multi_index;

using Table = bmi::multi_index_container<
    data, bmi::indexed_by<
        bmi::ordered_unique<
            bmi::composite_key<data,
                bmi::member<data, std::string, &data::index1_>,
                bmi::member<data, std::string, &data::index2_>,
                bmi::member<data, int,         &data::index3_>,
                bmi::member<data, int,         &data::index4_>
            >
        >,
        bmi::ordered_non_unique<
            bmi::tag<struct index4>,
            bmi::member<data, int, &data::index4_>
        >
    >
>;

int main() {
    Table table {
        //index1, index2, index3, index4, value
        data {   "alpha", "a", 1, 101, 0.5 },
        data {   "alpha", "a", 1, 102, 0.6 },
        // ...
        data {   "alpha", "a", 1, 120, 0.7 },
        data {   "alpha", "a", 2, 101, 0.3 },
        // ...
        data {   "alpha", "a", 2, 101, 0.3 },
        data {   "alpha", "b", 1, 101, 0.3 },
        // ...
        data {   "beta",  "a", 1, 101, 0.7 },
    };

    // max min index4, exploiting the ordered-ness of the index
    if (!table.empty()) {
        int min4 = table.get<index4>().begin() ->index4_;
        int max4 = table.get<index4>().rbegin()->index4_;

        std::cout << "index4: " << min4 << " - " << max4 << "\n";
    }
}

打印:

index4: 101 - 120

【讨论】:

  • 非常感谢。我从你的回答中得到了更好的理解。
  • 非常感谢。如果可以,还有一个问题。一旦构建了表格,我如何获得坐标 {"alpha", "a", 1, 101} 的值,即我想 "find" {"alpha", "a", 1, 101} “价值”并说更新它。
  • 迭代器像指针一样被取消引用。只是it = table.find(..); 然后*it 是你的对象(除非它没有被发现!)
  • 我应该尝试找到对象还是元组?我正在尝试的是 boost::tuple<:string std::string size> index = boost::make_tuple("alpha", "a", 1, 101);然后我正在尝试数据 d= *(table.find(index))。但它不工作。我想我很困惑,但无法抓住错误。
  • 您通过索引键搜索索引;键被定义为组合(参见元组)。你得到的只是容器元素类型。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2015-02-20
  • 2014-12-15
  • 1970-01-01
  • 2016-12-09
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多