I'm using boost::multi_index_container to perform some operations on satellite data.
I have a data structure that looks like this:
struct SatData {
std::string sat_system;
std::string band;
int index;
uint64_t time;
double data;
SatData(const std::string& ss,
const std::string& b,
const int& i,
const uint64_t& t,
const double& d) : sat_system(ss), band(b), index(i), time(t), data(d) {}
};
using SatDataset =
multi_index_container <SatData, indexed_by
<
ordered_unique // given a specific satellite and a time, the measurement is unique
<
composite_key
<
SatData,
member<SatData, std::string, &SatData::sat_system>,
member<SatData, std::string, &SatData::band>,
member<SatData, int, &SatData::index>,
member<SatData, uint64_t, &SatData::time>
> // composite key
> // ordered_not_unique
> // indexed_by
>; // multi_index_container
I would like to retrieve, for each sat_system+band+index, the number of measurements, so for example, if I had a table like this:
GPS | L1 | 1 | 10
GPS | L1 | 1 | 11
GPS | L1 | 1 | 12
GPS | L2 | 1 | 10
GPS | L2 | 1 | 11
GPS | L2 | 1 | 12
GPS | L2 | 4 | 11
GPS | L2 | 4 | 12
GALILEO | E5b | 2 | 10
GLONASS | G1 | 1 | 10
GLONASS | G1 | 1 | 11
GLONASS | G1 | 2 | 10
the answer would be:
GPS | L1 | 1 | 3
GPS | L2 | 1 | 2
GPS | L2 | 1 | 1
GPS | L2 | 4 | 2
GALILEO | E5b | 2 | 1
GLONASS | G1 | 1 | 3
I'm a bit rusty but I think a pseudo-SQL equivalent would be something like:
SELECT sat_stystem, band, index, COUNT(time)
GROUP_BY sat_stystem, band, index
I have found this related question: How to get the distinct count of first key in boost::multi_index_container with composite key
but it is specific for one search query, while I would like to have a result for the whole table instead.
There's no prefab functionality for that, but you can basically do it yourself the same way a SQL planner would do internally:
Live Coliru Demo
Output
Also, if you're going to do many of these operations, considering using ranked indices:
Live Coliru Demo
You need to measure in order to know which approach is faster, but in principle ranked indices will get the group sizes (
rank_next - rank_first) in logarithmic time, whereas ordered indices are linear on the number of elements in each group.Updated Aug 30
As per the OP's additional question, getting other calculated values, such as measurement averaging, is straightworfward once we have the range on which to do the calculation:
Live Coliru Demo
Output