in fbpcs/emp_games/attribution/decoupled_aggregation/Aggregator.cpp [69:135]
virtual void aggregateAttributions(
const PrivateAggregation& privateAggregation) override {
XLOG(INFO, "Computing measurement aggregation based on attributions...");
const auto& privateTpmArrays = privateAggregation.privateTpm;
const auto& privateCvmArrays = privateAggregation.privateCvm;
const auto& privateTpAttributionArrays =
privateAggregation.tpAttributionResults;
const auto& privateCvmAttributionsArrays =
privateAggregation.convAttributionResults;
XLOGF(
DBG,
"For measurement aggregator, size of tpAttribution: {}, conversion attribution: {}, tp metadata: {}, conv metadata: {}",
privateTpAttributionArrays.size(),
privateCvmAttributionsArrays.size(),
privateTpmArrays.size(),
privateCvmArrays.size());
CHECK_EQ(privateTpAttributionArrays.size(), privateTpmArrays.size())
<< "Size of touchpoint attribution results and touchpoint metadata should be equal.";
CHECK_EQ(privateCvmAttributionsArrays.size(), privateTpmArrays.size())
<< "Size of conversion attribution results and touchpoint metadata should be equal.";
CHECK_EQ(privateCvmArrays.size(), privateTpmArrays.size())
<< "Size of conversion metadata and touchpoint metadata should be equal.";
std::vector<std::vector<
MeasurementAggregation::PrivateMeasurementAggregationResult>>
touchpointConversionResults;
for (std::size_t i = 0; i < privateCvmArrays.size(); i++) {
// Retrieve the touchpoint-conversion metadata pairs based on attribution
// results. One assumption here is that one conversion will only be
// attributed to one touchpoint.
auto touchpointConversionResultsPerId =
retrieveTouchpointForConversionPerID(
privateTpmArrays.at(i),
privateCvmArrays.at(i),
privateTpAttributionArrays.at(i),
privateCvmAttributionsArrays.at(i));
touchpointConversionResults.push_back(touchpointConversionResultsPerId);
}
for (auto& touchpointConversionResultsPerId : touchpointConversionResults) {
for (auto& touchpointConversionResult :
touchpointConversionResultsPerId) {
const auto& touchpoint =
touchpointConversionResult.measurementTouchpointMetadata;
const auto& conversion =
touchpointConversionResult.measurementConversionMetadata;
for (auto& [adId, metrics] : _adIdToMetrics) {
const emp::Integer zero{INT_SIZE_32, 0, emp::PUBLIC};
const emp::Integer one{INT_SIZE_32, 1, emp::PUBLIC};
const auto adIdMatches =
touchpointConversionResult.hasAttributedTouchpoint &
adId.equal(touchpoint.adId);
// emp::If(condition, true_case, false_case)
const auto convsDelta = emp::If(adIdMatches, one, zero);
const auto salesDelta =
emp::If(adIdMatches, conversion.conv_value, zero);
metrics.convs = metrics.convs + convsDelta;
metrics.sales = metrics.sales + salesDelta;
}
}
}
}