virtual void aggregateAttributions()

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;
        }
      }
    }
  }