bool CEventRateBucketGatherer::processFields()

in lib/model/CEventRateBucketGatherer.cc [828:950]


bool CEventRateBucketGatherer::processFields(const TStrCPtrVec& fieldValues,
                                             CEventData& result,
                                             CResourceMonitor& resourceMonitor) {
    using TOptionalSize = std::optional<std::size_t>;
    using TOptionalStr = std::optional<std::string>;

    if (fieldValues.size() != m_FieldNames.size()) {
        LOG_ERROR(<< "Unexpected field values: " << fieldValues
                  << ", for field names: " << m_FieldNames);
        return false;
    }

    const std::string* person = (fieldValues[0] == nullptr && m_DataGatherer.useNull())
                                    ? &EMPTY_STRING
                                    : fieldValues[0];
    if (person == nullptr) {
        // Just ignore: the "person" field wasn't present in the
        // record. Note that we don't warn here since we'll permit
        // a small fraction of records to having missing field
        // values.
        return false;
    }

    for (std::size_t i = m_DataGatherer.isPopulation() ? 2 : 1; i < m_BeginValueField; ++i) {
        result.addInfluence(fieldValues[i] ? TOptionalStr(*fieldValues[i]) : std::nullopt);
    }

    if (m_BeginValueField != m_BeginSummaryFields) {
        if (const std::string* value = fieldValues[m_BeginValueField]) {
            result.stringValue(*value);
        }
    }

    std::size_t count = 1;
    if (m_DataGatherer.summaryMode() != model_t::E_None) {
        if (m_DataGatherer.extractCountFromField(m_FieldNames[m_BeginSummaryFields],
                                                 fieldValues[m_BeginSummaryFields],
                                                 count) == false) {
            result.addValue();
            return true;
        }
    }

    if (count == CDataGatherer::EXPLICIT_NULL_SUMMARY_COUNT) {
        result.setExplicitNull();
    } else {
        model_t::EFeature feature = m_DataGatherer.feature(0);
        if ((feature == model_t::E_IndividualTimeOfDayByBucketAndPerson) ||
            (feature == model_t::E_PopulationTimeOfDayByBucketPersonAndAttribute)) {
            double t = static_cast<double>(result.time() % core::constants::DAY);
            result.addValue(TDouble1Vec(1, t));
        } else if ((feature == model_t::E_IndividualTimeOfWeekByBucketAndPerson) ||
                   (feature == model_t::E_PopulationTimeOfWeekByBucketPersonAndAttribute)) {
            double t = static_cast<double>(result.time() % core::constants::WEEK);
            result.addValue(TDouble1Vec(1, t));
        } else {
            result.addCountStatistic(count);
        }
    }

    bool addedPerson = false;
    std::size_t personId = CDynamicStringIdRegistry::INVALID_ID;
    if (result.isExplicitNull()) {
        m_DataGatherer.personId(*person, personId);
    } else {
        personId = m_DataGatherer.addPerson(*person, resourceMonitor, addedPerson);
    }

    if (personId == CDynamicStringIdRegistry::INVALID_ID) {
        if (!result.isExplicitNull()) {
            LOG_TRACE(<< "Couldn't create a person, over memory limit");
        }
        return false;
    }
    if (addedPerson) {
        resourceMonitor.addExtraMemory(m_DataGatherer.isPopulation()
                                           ? CDataGatherer::ESTIMATED_MEM_USAGE_PER_OVER_FIELD
                                           : CDataGatherer::ESTIMATED_MEM_USAGE_PER_BY_FIELD);
        ++(m_DataGatherer.isPopulation()
               ? core::CProgramCounters::counter(counter_t::E_TSADNumberOverFields)
               : core::CProgramCounters::counter(counter_t::E_TSADNumberByFields));
    }
    if (!result.person(personId)) {
        LOG_ERROR(<< "Bad by field value: " << *person);
        return false;
    }

    if (m_DataGatherer.isPopulation()) {
        const std::string* attribute =
            (fieldValues[1] == nullptr && m_DataGatherer.useNull()) ? &EMPTY_STRING
                                                                    : fieldValues[1];

        if (attribute == nullptr) {
            // Just ignore: the "by" field wasn't present in the
            // record. This doesn't necessarily stop us processing
            // the record by other models so we don't return false.
            // Note that we don't warn here since we'll permit a
            // small fraction of records to having missing field
            // values.
            result.addAttribute();
            return true;
        }

        bool addedAttribute = false;
        std::size_t newAttribute = CDynamicStringIdRegistry::INVALID_ID;
        if (result.isExplicitNull()) {
            m_DataGatherer.attributeId(*attribute, newAttribute);
        } else {
            newAttribute = m_DataGatherer.addAttribute(*attribute, resourceMonitor,
                                                       addedAttribute);
        }
        result.addAttribute(TOptionalSize(newAttribute));

        if (addedAttribute) {
            resourceMonitor.addExtraMemory(CDataGatherer::ESTIMATED_MEM_USAGE_PER_BY_FIELD);
            ++core::CProgramCounters::counter(counter_t::E_TSADNumberByFields);
        }
    } else {
        result.addAttribute(std::size_t(0));
    }

    return true;
}