Reputation: 1415
I am trying to learn about Boost multi-index, may I please seek some help regarding that.
The data looks like as follows:
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
... ... ... .... ...
Now I have created a structure:
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_;
};
and also have:
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 ?
Next I created a typedef as follows: I am not sure whether to use "ordered_unique" or "ordered_non_unique". Can someone please help.
I have the confusion because the 4-tuple (index1,index2,index3,inde4) is unique co-ordinate pointing to a data value. But for each of them there are repeated occurrence (e.g. for index1 the string "alpha" is repeated several times)
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;
Next in the main() I populate the data by looping through each data point and doing an insert like I give below:
data_map DATA;
DATA.insert(data(alpha,a,1,101,0.5));
Thereafter, I want to check what is the range of say index4 (i.e. what is the minimum and maximum value). I am trying something like:
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
Also when I try I do not get the intended results.
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_;
}
Can someone please point out my mistakes and help me with my understanding. Thanks in advance
Upvotes: 2
Views: 540
Reputation: 392911
Q.:
struct value{}; // I guess i do not need this because this is a data point // and not an index. Can someone please comment ?
Only create the indexes you use.
Q.: I am not sure whether to use
ordered_unique
orordered_non_unique
. Can someone please help.I have the confusion because the 4-tuple (index1,index2,index3,inde4) is unique co-ordinate pointing to a data value. But for each of them there are repeated occurrence (e.g. for index1 the string "alpha" is repeated several times)
You need a unique index on the composite key:
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.: Next in the main() I populate the data by looping through each data point and doing an insert like I give below:
May I suggest uniform initialization:
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 },
};
Q.: Thereafter, I want to check what is the range of say index4 (i.e. what is the minimum and maximum value). I am trying something like:
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()
returns the number of elements in the container, anyways. You can add the index
bmi::ordered_non_unique<
bmi::tag<struct index4>, bmi::member<data, int, &data::index4_>
>
and "exploit" the fact that it is ordered:
int min4 = table.get<index4>().begin() ->index4_;
int max4 = table.get<index4>().rbegin()->index4_;
#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";
}
}
Prints:
index4: 101 - 120
Upvotes: 2