void AggMetrics::mergeWithViaAddition()

in fbpcs/emp_games/attribution/shard_aggregator/AggMetrics.cpp [211:272]


void AggMetrics::mergeWithViaAddition(
    const std::shared_ptr<AggMetrics>& metrics) {
  checkMyType(metrics->getTag());

  switch (metrics->getTag()) {
    case AggMetricsTag::Map: {
      for (const auto& [key, innerMetrics] : metrics->getAsMap()) {
        // have not merged with this key yet
        if (getAsMap().find(key) == getAsMap().end()) {
          if (innerMetrics->getTag() == AggMetricsTag::EmpInteger) {
            emplace(
                key,
                std::make_shared<AggMetrics>(
                    AggMetrics{innerMetrics->getEmpIntValue()}));

          } else {
            // emplace the new structure and merge the correct values in
            emplace(
                key,
                std::make_shared<AggMetrics>(
                    AggMetrics{innerMetrics->getTag()}));
            getAtKey(key)->mergeWithViaAddition(innerMetrics);
          }

        } else {
          getAtKey(key)->mergeWithViaAddition(innerMetrics);
        }
      }
      break;
    }
    case AggMetricsTag::List: {
      for (std::size_t i = 0; i < metrics->getAsList().size(); ++i) {
        // have not merged with this list index yet
        if (getAsList().size() <= i) {
          if (metrics->getAtIndex(i)->getTag() == AggMetricsTag::EmpInteger) {
            pushBack(std::make_shared<AggMetrics>(
                AggMetrics{metrics->getAtIndex(i)->getEmpIntValue()}));

          } else {
            // push back the new structure and merge the correct values in
            pushBack(std::make_shared<AggMetrics>(
                AggMetrics{metrics->getAtIndex(i)->getTag()}));
            getAtIndex(i)->mergeWithViaAddition(metrics->getAtIndex(i));
          }
        } else {
          getAtIndex(i)->mergeWithViaAddition(metrics->getAtIndex(i));
        }
      }
      break;
    }
    case AggMetricsTag::EmpInteger: {
      // merge innermost values via addition
      value_ = getEmpIntValue() + metrics->getEmpIntValue();
      break;
    }
    default: {
      XLOG(FATAL)
          << "accumulator should only store a map, list, or emp::Integer at this point";
      break;
    }
  }
}