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