diff --git a/.clang-tidy b/.clang-tidy index 146d35bce..9459552c1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -23,6 +23,7 @@ Checks: > -modernize-use-trailing-return-type, -modernize-concat-nested-namespaces, -modernize-use-nodiscard, + -modernize-use-ranges, performance-*, diff --git a/include/model/CBucketGatherer.h b/include/model/CBucketGatherer.h index 24c425673..82000ea0d 100644 --- a/include/model/CBucketGatherer.h +++ b/include/model/CBucketGatherer.h @@ -32,7 +32,6 @@ #include #include #include -#include #include namespace ml { @@ -98,7 +97,7 @@ class MODEL_EXPORT CBucketGatherer { //! \brief Hashes a ((size_t, size_t), string*) pair. struct MODEL_EXPORT SSizeSizePrOptionalStrPrHash { std::size_t operator()(const TSizeSizePrOptionalStrPr& key) const { - std::uint64_t seed = core::CHashing::hashCombine( + std::uint64_t const seed = core::CHashing::hashCombine( static_cast(key.first.first), static_cast(key.first.second)); return core::CHashing::hashCombine(seed, s_Hasher(key.second)); @@ -132,6 +131,26 @@ class MODEL_EXPORT CBucketGatherer { using TTimeVec = std::vector; using TTimeVecCItr = TTimeVec::const_iterator; + struct SBucketGathererInitData { + // The name of the field holding the summary count. + const std::string& s_SummaryCountFieldName; + // The name of the field which identifies people. + const std::string& s_PersonFieldName; + // The name of the field which defines the person attributes. + const std::string& s_AttributeFieldName; + // The name of the field which contains the metric values. + const std::string& s_ValueFieldName; + // The field names for which we will compute influences. + const TStrVec& s_InfluenceFieldNames; + // The start of the time interval for which to gather data. + core_t::TTime s_StartTime; + // Override for the number of measurements + // in a statistic. (Note that this is intended for testing only.) + // A zero value means that the data gatherer class will determine + // an appropriate value for the bucket length and data rate. + unsigned int s_SampleOverrideCount; + }; + public: static const std::string EVENTRATE_BUCKET_GATHERER_TAG; static const std::string METRIC_BUCKET_GATHERER_TAG; @@ -142,11 +161,10 @@ class MODEL_EXPORT CBucketGatherer { //! Create a new data series gatherer. //! //! \param[in] dataGatherer The owning data gatherer. - //! \param[in] startTime The start of the time interval for which - //! to gather data. - //! \param[in] numberInfluencers The number of result influencers - //! for which to gather data. - CBucketGatherer(CDataGatherer& dataGatherer, core_t::TTime startTime, std::size_t numberInfluencers); + //! \param[in] bucketGathererInitData The parameter initialization object + //! for the bucket gatherer. + CBucketGatherer(CDataGatherer& dataGatherer, + const SBucketGathererInitData& bucketGathererInitData); //! Create a copy that will result in the same persisted state as the //! original. This is effectively a copy constructor that creates a diff --git a/include/model/CCountingModelFactory.h b/include/model/CCountingModelFactory.h index bd2ccb3da..372f970a8 100644 --- a/include/model/CCountingModelFactory.h +++ b/include/model/CCountingModelFactory.h @@ -68,15 +68,15 @@ class MODEL_EXPORT CCountingModelFactory : public CModelFactory { //! \param[in] initData The parameters needed to initialize the data //! gatherer. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const SGathererInitializationData& initData) const override; + TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const override; //! Make a new event rate data gatherer from part of a state document. //! //! \param[in] partitionFieldValue The partition field value. //! \param[in,out] traverser A state document traverser. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const override; + TDataGathererPtr makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const override; //@} //! \name Defaults diff --git a/include/model/CDataGatherer.h b/include/model/CDataGatherer.h index b15e7514e..6dd202885 100644 --- a/include/model/CDataGatherer.h +++ b/include/model/CDataGatherer.h @@ -146,51 +146,26 @@ class MODEL_EXPORT CDataGatherer { //! \param[in] summaryMode Indicates whether the data being gathered //! are already summarized by an external aggregation process. //! \param[in] modelParams The global configuration parameters. - //! \param[in] summaryCountFieldName If \p summaryMode is E_Manual - //! then this is the name of the field holding the summary count. //! \param[in] partitionFieldValue The value of the field which splits //! the data. - //! \param[in] personFieldName The name of the field which identifies - //! people. - //! \param[in] attributeFieldName The name of the field which defines - //! the person attributes. - //! \param[in] valueFieldName The name of the field which contains - //! the metric values. - //! \param[in] influenceFieldNames The field names for which we will - //! compute influences. //! \param[in] key The key of the search for which to gatherer data. //! \param[in] features The features of the data to model. - //! \param[in] startTime The start of the time interval for which - //! to gather data. - //! \param[in] sampleCountOverride for the number of measurements - //! in a statistic. (Note that this is intended for testing only.) - //! A zero value means that the data gatherer class will determine - //! an appropriate value for the bucket length and data rate. + //! \param[in] bucketGathererInitData The parameter initialization object for the bucket gatherer. CDataGatherer(model_t::EAnalysisCategory gathererType, model_t::ESummaryMode summaryMode, const SModelParams& modelParams, - const std::string& summaryCountFieldName, - const std::string& partitionFieldValue, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + std::string partitionFieldValue, const CSearchKey& key, const TFeatureVec& features, - core_t::TTime startTime, - int sampleCountOverride); + const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData); //! Construct from a state document. CDataGatherer(model_t::EAnalysisCategory gathererType, model_t::ESummaryMode summaryMode, const SModelParams& modelParams, - const std::string& summaryCountFieldName, - const std::string& partitionFieldValue, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + std::string partitionFieldValue, const CSearchKey& key, + const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser); //! Create a copy that will result in the same persisted state as the @@ -330,6 +305,7 @@ class MODEL_EXPORT CDataGatherer { //! containing \p time. //! //! \param[in] time The time of interest. + //! \param[in] bucketLength The length of the bucketing interval. //! \param[out] result Filled in with the feature data at \p time. //! \tparam T The type of the feature data. template @@ -648,9 +624,9 @@ class MODEL_EXPORT CDataGatherer { //! Helper to avoid code duplication when getting a count from a //! field. Logs different errors for missing value and invalid value. - bool extractCountFromField(const std::string& fieldName, - const std::string* fieldValue, - std::size_t& count) const; + static bool extractCountFromField(const std::string& fieldName, + const std::string* fieldValue, + std::size_t& count); //! Helper to avoid code duplication when getting a metric value from a //! field. Logs different errors for missing value and invalid value. @@ -675,19 +651,11 @@ class MODEL_EXPORT CDataGatherer { private: //! Restore state from supplied traverser. - bool acceptRestoreTraverser(const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + bool acceptRestoreTraverser(const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser); //! Restore a bucket gatherer from the supplied traverser. - bool restoreBucketGatherer(const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + bool restoreBucketGatherer(const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser); //! Persist a bucket gatherer by passing information to the supplied @@ -696,13 +664,7 @@ class MODEL_EXPORT CDataGatherer { //! Create the bucket specific data gatherer. void createBucketGatherer(model_t::EAnalysisCategory gathererType, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime, - unsigned int sampleCountOverride); + const CBucketGatherer::SBucketGathererInitData& initData); private: //! The type of the bucket gatherer(s) used. diff --git a/include/model/CEventRateBucketGatherer.h b/include/model/CEventRateBucketGatherer.h index 3a1b5fafe..947c74fef 100644 --- a/include/model/CEventRateBucketGatherer.h +++ b/include/model/CEventRateBucketGatherer.h @@ -111,33 +111,13 @@ class MODEL_EXPORT CEventRateBucketGatherer final : public CBucketGatherer { //! Create an event rate bucket gatherer. //! //! \param[in] dataGatherer The owning data gatherer. - //! \param[in] summaryCountFieldName If summaryMode is E_Manual - //! then this is the name of the field holding the summary count. - //! \param[in] personFieldName The name of the field which identifies - //! people. - //! \param[in] attributeFieldName The name of the field which defines - //! the person attributes. - //! \param[in] valueFieldName The name of the field which contains - //! the metric values. - //! \param[in] influenceFieldNames The field names for which we will - //! compute influences. - //! \param[in] startTime The start of the time interval for which - //! to gather data. + //! \param[in] bucketGathererInitData The parameter initialization object. CEventRateBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime); + const SBucketGathererInitData& bucketGathererInitData); //! Construct from a state document. CEventRateBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + const SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser); //! Create a copy that will result in the same persisted state as the @@ -444,11 +424,7 @@ class MODEL_EXPORT CEventRateBucketGatherer final : public CBucketGatherer { void startNewBucket(core_t::TTime time, bool skipUpdates) override; //! Initialize the field names collection. - void initializeFieldNames(const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const std::string& summaryCountFieldName, - const TStrVec& influenceFieldNames); + void initializeFieldNames(const CBucketGatherer::SBucketGathererInitData& initData); //! Initialize the feature data gatherers. void initializeFeatureData(); @@ -481,13 +457,13 @@ class MODEL_EXPORT CEventRateBucketGatherer final : public CBucketGatherer { TStrVec m_FieldNames; //! The position of the first influencer field - std::size_t m_BeginInfluencingFields; + std::size_t m_BeginInfluencingFields{0}; //! The position of the first count/value field. - std::size_t m_BeginValueField; + std::size_t m_BeginValueField{0}; //! The position of the field holding the summarised count. - std::size_t m_BeginSummaryFields; + std::size_t m_BeginSummaryFields{0}; //! The data features we are gathering. TCategoryAnyMap m_FeatureData; diff --git a/include/model/CEventRateModelFactory.h b/include/model/CEventRateModelFactory.h index 0d7981ced..f94dc8cc0 100644 --- a/include/model/CEventRateModelFactory.h +++ b/include/model/CEventRateModelFactory.h @@ -69,15 +69,15 @@ class MODEL_EXPORT CEventRateModelFactory final : public CModelFactory { //! \param[in] initData The parameters needed to initialize the data //! gatherer. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const SGathererInitializationData& initData) const override; + TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const override; //! Make a new event rate data gatherer from part of a state document. //! //! \param[in] partitionFieldValue The partition field value. //! \param[in,out] traverser A state document traverser. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const override; + TDataGathererPtr makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const override; //@} //! \name Defaults diff --git a/include/model/CEventRatePopulationModelFactory.h b/include/model/CEventRatePopulationModelFactory.h index 2595e3b72..974abdf4f 100644 --- a/include/model/CEventRatePopulationModelFactory.h +++ b/include/model/CEventRatePopulationModelFactory.h @@ -69,7 +69,7 @@ class MODEL_EXPORT CEventRatePopulationModelFactory final : public CModelFactory //! \param[in] initData The parameters needed to initialize the //! data gatherer. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const SGathererInitializationData& initData) const override; + TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const override; //! Make a new population event rate data gatherer from part of //! a state document. @@ -77,8 +77,8 @@ class MODEL_EXPORT CEventRatePopulationModelFactory final : public CModelFactory //! \param[in] partitionFieldValue The partition field value. //! \param[in,out] traverser A state document traverser. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const override; + TDataGathererPtr makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const override; //@} //! \name Defaults diff --git a/include/model/CMetricBucketGatherer.h b/include/model/CMetricBucketGatherer.h index d55e6292a..bd309d8aa 100644 --- a/include/model/CMetricBucketGatherer.h +++ b/include/model/CMetricBucketGatherer.h @@ -53,33 +53,13 @@ class MODEL_EXPORT CMetricBucketGatherer final : public CBucketGatherer { //! Create a new population metric data gatherer. //! //! \param[in] dataGatherer The owning data gatherer. - //! \param[in] summaryCountFieldName If \p summaryMode is E_Manual - //! then this is the name of the field holding the summary count. - //! \param[in] personFieldName The name of the field which identifies - //! people. - //! \param[in] attributeFieldName The name of the field which defines - //! the person attributes. - //! \param[in] valueFieldName The name of the field which contains - //! the metric values. - //! \param[in] influenceFieldNames The field names for which we will - //! compute influences. - //! \param[in] startTime The start of the time interval for which - //! to gather data. - CMetricBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime); + //! \param[in] initData The parameter initialization object for the bucket + //! gatherer. + CMetricBucketGatherer(CDataGatherer& dataGatherer, const SBucketGathererInitData& initData); //! Construct from a state document. CMetricBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + const SBucketGathererInitData& initData, core::CStateRestoreTraverser& traverser); //! Create a copy that will result in the same persisted state as the @@ -266,9 +246,7 @@ class MODEL_EXPORT CMetricBucketGatherer final : public CBucketGatherer { //! 1) initializeFieldNamesPart1() //! 2) restore state //! 3) initializeFieldNamesPart2() - void initializeFieldNamesPart1(const std::string& personFieldName, - const std::string& attributeFieldName, - const TStrVec& influenceFieldNames); + void initializeFieldNamesPart1(const SBucketGathererInitData& initData); //! Initialize the field names collection. //! initializeFieldNamesPart1() must be called before this. @@ -277,8 +255,7 @@ class MODEL_EXPORT CMetricBucketGatherer final : public CBucketGatherer { //! 1) initializeFieldNamesPart1() //! 2) restore state //! 3) initializeFieldNamesPart2() - void initializeFieldNamesPart2(const std::string& valueFieldName, - const std::string& summaryCountFieldName); + void initializeFieldNamesPart2(const SBucketGathererInitData& initData); //! Initialize the feature data gatherers. void initializeFeatureData(); @@ -307,10 +284,10 @@ class MODEL_EXPORT CMetricBucketGatherer final : public CBucketGatherer { TStrVec m_FieldNames; //! The position of the first influencing field. - std::size_t m_BeginInfluencingFields; + std::size_t m_BeginInfluencingFields{0}; //! The position of the first count/value field. - std::size_t m_BeginValueFields; + std::size_t m_BeginValueFields{0}; //! For summarized values, this stores the metric categories //! corresponding to the summarized field names in m_FieldNames; diff --git a/include/model/CMetricModelFactory.h b/include/model/CMetricModelFactory.h index 52ecc127c..c14f7aca6 100644 --- a/include/model/CMetricModelFactory.h +++ b/include/model/CMetricModelFactory.h @@ -69,15 +69,15 @@ class MODEL_EXPORT CMetricModelFactory final : public CModelFactory { //! \param[in] initData The parameters needed to initialize the //! data gatherer. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const SGathererInitializationData& initData) const override; + TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const override; //! Make a new metric data gatherer from part of a state document. //! //! \param[in] partitionFieldValue The partition field value. //! \param[in,out] traverser A state document traverser. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const override; + TDataGathererPtr makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const override; //@} //! \name Defaults diff --git a/include/model/CMetricPopulationModelFactory.h b/include/model/CMetricPopulationModelFactory.h index 2f8c4dbb6..caa4a5949 100644 --- a/include/model/CMetricPopulationModelFactory.h +++ b/include/model/CMetricPopulationModelFactory.h @@ -69,7 +69,7 @@ class MODEL_EXPORT CMetricPopulationModelFactory final : public CModelFactory { //! \param[in] initData The parameters needed to initialize the data //! gatherer. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const SGathererInitializationData& initData) const override; + TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const override; //! Make a new metric population data gatherer from part of a state //! document. @@ -77,8 +77,8 @@ class MODEL_EXPORT CMetricPopulationModelFactory final : public CModelFactory { //! \param[in] partitionFieldValue The partition field value. //! \param[in,out] traverser A state document traverser. //! \warning It is owned by the calling code. - CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const override; + TDataGathererPtr makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const override; //@} //! \name Defaults diff --git a/include/model/CModelFactory.h b/include/model/CModelFactory.h index 623f88db8..166d81674 100644 --- a/include/model/CModelFactory.h +++ b/include/model/CModelFactory.h @@ -24,7 +24,6 @@ #include #include #include -#include #include namespace ml { @@ -175,7 +174,7 @@ class MODEL_EXPORT CModelFactory { //! \param[in] initData The parameters needed to initialize the //! data gatherer. //! \warning It is owned by the calling code. - virtual CDataGatherer* + virtual TDataGathererPtr makeDataGatherer(const SGathererInitializationData& initData) const = 0; //! Make a new data gatherer from part of a state document. @@ -183,8 +182,9 @@ class MODEL_EXPORT CModelFactory { //! \param[in,out] traverser A state document traverser. //! \param[in] partitionFieldValue The partition field value. //! \warning It is owned by the calling code. - virtual CDataGatherer* makeDataGatherer(const std::string& partitionFieldValue, - core::CStateRestoreTraverser& traverser) const = 0; + virtual TDataGathererPtr + makeDataGatherer(const std::string& partitionFieldValue, + core::CStateRestoreTraverser& traverser) const = 0; //@} //! \name Defaults diff --git a/lib/model/CAnomalyDetector.cc b/lib/model/CAnomalyDetector.cc index f8c36d005..2049e49c8 100644 --- a/lib/model/CAnomalyDetector.cc +++ b/lib/model/CAnomalyDetector.cc @@ -206,8 +206,7 @@ bool CAnomalyDetector::legacyModelEnsembleAcceptRestoreTraverser(const std::stri do { const std::string& name = traverser.name(); if (name == DATA_GATHERER_TAG) { - m_DataGatherer.reset( - m_ModelFactory->makeDataGatherer(partitionFieldValue, traverser)); + m_DataGatherer = m_ModelFactory->makeDataGatherer(partitionFieldValue, traverser); if (m_DataGatherer == nullptr || m_DataGatherer->checkInvariants() == false) { LOG_ERROR(<< "Failed to restore the data gatherer from " << traverser.value()); diff --git a/lib/model/CBucketGatherer.cc b/lib/model/CBucketGatherer.cc index 7a987ec6a..1c59ddd44 100644 --- a/lib/model/CBucketGatherer.cc +++ b/lib/model/CBucketGatherer.cc @@ -108,10 +108,10 @@ bool restoreInfluencerPersonAttributeCounts(core::CStateRestoreTraverser& traver TSizeSizePrOptionalStrPrUInt64UMap& map) { std::size_t person = 0; std::size_t attribute = 0; - std::string influence = ""; + std::string influence; std::uint64_t count = 0; do { - const std::string name = traverser.name(); + const std::string& name = traverser.name(); RESTORE_BUILT_IN(PERSON_UID_TAG, person) RESTORE_BUILT_IN(ATTRIBUTE_UID_TAG, attribute) RESTORE_NO_ERROR(INFLUENCER_TAG, influence = traverser.value()) @@ -137,10 +137,11 @@ struct SBucketCountsPersister { personAttributeCounts.assign(bucketCounts.begin(), bucketCounts.end()); std::sort(personAttributeCounts.begin(), personAttributeCounts.end()); for (std::size_t i = 0; i < personAttributeCounts.size(); ++i) { - inserter.insertLevel(PERSON_ATTRIBUTE_COUNT_TAG, - std::bind(&insertPersonAttributeCounts, - std::cref(personAttributeCounts[i]), - std::placeholders::_1)); + inserter.insertLevel( + PERSON_ATTRIBUTE_COUNT_TAG, [tuple = std::cref(personAttributeCounts[i])]( + core::CStatePersistInserter & inserter_) { + insertPersonAttributeCounts(tuple, inserter_); + }); } } @@ -148,13 +149,13 @@ struct SBucketCountsPersister { core::CStateRestoreTraverser& traverser) { do { TSizeSizePr key; - std::uint64_t count{0u}; + std::uint64_t count{0U}; if (!traverser.hasSubLevel()) { continue; } - if (traverser.traverseSubLevel( - std::bind(&restorePersonAttributeCounts, std::placeholders::_1, - std::ref(key), std::ref(count))) == false) { + if (traverser.traverseSubLevel([&key, &count](core::CStateRestoreTraverser& traverser_) { + return restorePersonAttributeCounts(traverser_, key, count); + }) == false) { LOG_ERROR(<< "Invalid person attribute count"); continue; } @@ -172,9 +173,10 @@ struct SInfluencerCountsPersister { core::CStatePersistInserter& inserter) { for (std::size_t i = 0; i < data.size(); ++i) { inserter.insertValue(INFLUENCE_COUNT_TAG, i); - inserter.insertLevel(INFLUENCE_ITEM_TAG, - std::bind(&insertInfluencerPersonAttributeCounts, - std::cref(data[i]), std::placeholders::_1)); + inserter.insertLevel(INFLUENCE_ITEM_TAG, [map = std::cref(data[i])]( + core::CStatePersistInserter & inserter_) { + insertInfluencerPersonAttributeCounts(map, inserter_); + }); } } @@ -202,21 +204,22 @@ const std::string CBucketGatherer::EVENTRATE_BUCKET_GATHERER_TAG("a"); const std::string CBucketGatherer::METRIC_BUCKET_GATHERER_TAG("b"); CBucketGatherer::CBucketGatherer(CDataGatherer& dataGatherer, - core_t::TTime startTime, - std::size_t numberInfluencers) - : m_DataGatherer(dataGatherer), m_EarliestTime(startTime), m_BucketStart(startTime), + const SBucketGathererInitData& initData) + : m_DataGatherer(dataGatherer), m_EarliestTime(initData.s_StartTime), + m_BucketStart(initData.s_StartTime), m_PersonAttributeCounts(dataGatherer.params().s_LatencyBuckets, dataGatherer.params().s_BucketLength, - startTime, + initData.s_StartTime, TSizeSizePrUInt64UMap(1)), m_PersonAttributeExplicitNulls(dataGatherer.params().s_LatencyBuckets, dataGatherer.params().s_BucketLength, - startTime, + initData.s_StartTime, TSizeSizePrUSet(1)), m_InfluencerCounts(dataGatherer.params().s_LatencyBuckets + 3, dataGatherer.params().s_BucketLength, - startTime, - TSizeSizePrOptionalStrPrUInt64UMapVec(numberInfluencers)) { + initData.s_StartTime, + TSizeSizePrOptionalStrPrUInt64UMapVec( + initData.s_InfluenceFieldNames.size())) { } CBucketGatherer::CBucketGatherer(bool isForPersistence, const CBucketGatherer& other) @@ -231,7 +234,7 @@ CBucketGatherer::CBucketGatherer(bool isForPersistence, const CBucketGatherer& o } bool CBucketGatherer::addEventData(CEventData& data) { - core_t::TTime time = data.time(); + core_t::TTime const time = data.time(); if (time < this->earliestBucketStartTime()) { // Ignore records that are out of the latency window @@ -247,9 +250,9 @@ bool CBucketGatherer::addEventData(CEventData& data) { return false; } - std::size_t pid = *data.personId(); - std::size_t cid = *data.attributeId(); - std::size_t count = *data.count(); + std::size_t const pid = *data.personId(); + std::size_t const cid = *data.attributeId(); + std::size_t const count = *data.count(); if ((pid != CDynamicStringIdRegistry::INVALID_ID) && (cid != CDynamicStringIdRegistry::INVALID_ID)) { // Has the person/attribute been deleted from the gatherer? @@ -262,7 +265,7 @@ bool CBucketGatherer::addEventData(CEventData& data) { return false; } - TSizeSizePr pidCid = std::make_pair(pid, cid); + TSizeSizePr const pidCid = std::make_pair(pid, cid); // If record is explicit null just note that a null record has been seen // for the given (pid, cid) pair. @@ -297,7 +300,7 @@ bool CBucketGatherer::addEventData(CEventData& data) { influencerCounts[i] .emplace(boost::unordered::piecewise_construct, boost::make_tuple(pidCid, inf), - boost::make_tuple(std::uint64_t(0))) + boost::make_tuple(static_cast(0))) .first->second += count; } } @@ -315,7 +318,7 @@ void CBucketGatherer::timeNow(core_t::TTime time) { void CBucketGatherer::hiddenTimeNow(core_t::TTime time, bool skipUpdates) { m_EarliestTime = std::min(m_EarliestTime, time); - core_t::TTime n = (time - m_BucketStart) / this->bucketLength(); + core_t::TTime const n = (time - m_BucketStart) / this->bucketLength(); core_t::TTime newBucketStart = m_BucketStart; for (core_t::TTime i = 0; i < n; ++i) { newBucketStart += this->bucketLength(); @@ -324,7 +327,8 @@ void CBucketGatherer::hiddenTimeNow(core_t::TTime time, bool skipUpdates) { // the gatherers may finalise the earliest bucket within // the latency window, thus we push a new count bucket only // after startNewBucket has been called. - std::ptrdiff_t numberInfluences{this->endInfluencers() - this->beginInfluencers()}; + std::ptrdiff_t const numberInfluences{this->endInfluencers() - + this->beginInfluencers()}; this->startNewBucket(newBucketStart, skipUpdates); m_PersonAttributeCounts.push(TSizeSizePrUInt64UMap(1), newBucketStart); m_PersonAttributeExplicitNulls.push(TSizeSizePrUSet(1), newBucketStart); @@ -335,17 +339,17 @@ void CBucketGatherer::hiddenTimeNow(core_t::TTime time, bool skipUpdates) { } void CBucketGatherer::sampleNow(core_t::TTime sampleBucketStart) { - core_t::TTime timeNow = + core_t::TTime const timeNow = sampleBucketStart + - (m_DataGatherer.params().s_LatencyBuckets + 1) * this->bucketLength() - 1; + ((m_DataGatherer.params().s_LatencyBuckets + 1) * this->bucketLength()) - 1; this->timeNow(timeNow); this->sample(sampleBucketStart); } void CBucketGatherer::skipSampleNow(core_t::TTime sampleBucketStart) { - core_t::TTime timeNow = + core_t::TTime const timeNow = sampleBucketStart + - (m_DataGatherer.params().s_LatencyBuckets + 1) * this->bucketLength() - 1; + ((m_DataGatherer.params().s_LatencyBuckets + 1) * this->bucketLength()) - 1; this->hiddenTimeNow(timeNow, true); } @@ -380,7 +384,7 @@ void CBucketGatherer::recyclePeople(const TSizeVec& peopleToRemove) { void CBucketGatherer::removePeople(std::size_t lowestPersonToRemove) { if (lowestPersonToRemove < m_DataGatherer.numberPeople()) { TSizeVec peopleToRemove; - std::size_t maxPersonId = m_DataGatherer.numberPeople(); + std::size_t const maxPersonId = m_DataGatherer.numberPeople(); peopleToRemove.reserve(maxPersonId - lowestPersonToRemove); for (std::size_t pid = lowestPersonToRemove; pid < maxPersonId; ++pid) { peopleToRemove.push_back(pid); @@ -493,7 +497,7 @@ bool CBucketGatherer::hasExplicitNullsOnly(core_t::TTime time, std::size_t pid, return false; } const TSizeSizePrUInt64UMap& bucketCounts = m_PersonAttributeCounts.get(time); - TSizeSizePr pidCid = std::make_pair(pid, cid); + TSizeSizePr const pidCid = std::make_pair(pid, cid); return bucketExplicitNulls.find(pidCid) != bucketExplicitNulls.end() && bucketCounts.find(pidCid) == bucketCounts.end(); } @@ -513,10 +517,10 @@ std::uint64_t CBucketGatherer::checksum() const { TStrCRefStrCRefPrUInt64PrVec personAttributeCounts; personAttributeCounts.reserve(bucketCounts.size()); for (const auto& count : bucketCounts) { - std::size_t pid = CDataGatherer::extractPersonId(count); - std::size_t cid = CDataGatherer::extractAttributeId(count); - TStrCRefStrCRefPr key(TStrCRef(m_DataGatherer.personName(pid)), - TStrCRef(m_DataGatherer.attributeName(cid))); + std::size_t const pid = CDataGatherer::extractPersonId(count); + std::size_t const cid = CDataGatherer::extractAttributeId(count); + TStrCRefStrCRefPr const key(TStrCRef(m_DataGatherer.personName(pid)), + TStrCRef(m_DataGatherer.attributeName(cid))); personAttributeCounts.emplace_back(key, CDataGatherer::extractData(count)); } std::sort(personAttributeCounts.begin(), personAttributeCounts.end(), @@ -530,10 +534,10 @@ std::uint64_t CBucketGatherer::checksum() const { TStrCRefStrCRefPrVec personAttributeExplicitNulls; personAttributeExplicitNulls.reserve(bucketExplicitNulls.size()); for (const auto& nulls : bucketExplicitNulls) { - std::size_t pid = CDataGatherer::extractPersonId(nulls); - std::size_t cid = CDataGatherer::extractAttributeId(nulls); - TStrCRefStrCRefPr key(TStrCRef(m_DataGatherer.personName(pid)), - TStrCRef(m_DataGatherer.attributeName(cid))); + std::size_t const pid = CDataGatherer::extractPersonId(nulls); + std::size_t const cid = CDataGatherer::extractAttributeId(nulls); + TStrCRefStrCRefPr const key(TStrCRef(m_DataGatherer.personName(pid)), + TStrCRef(m_DataGatherer.attributeName(cid))); personAttributeExplicitNulls.push_back(key); } std::sort(personAttributeExplicitNulls.begin(), @@ -582,7 +586,7 @@ bool CBucketGatherer::resetBucket(core_t::TTime bucketStart) { } LOG_TRACE(<< "Resetting bucket starting at " << bucketStart); - std::ptrdiff_t numberInfluences{this->endInfluencers() - this->beginInfluencers()}; + std::ptrdiff_t const numberInfluences{this->endInfluencers() - this->beginInfluencers()}; m_PersonAttributeCounts.get(bucketStart).clear(); m_PersonAttributeExplicitNulls.get(bucketStart).clear(); m_InfluencerCounts.get(bucketStart) = TSizeSizePrOptionalStrPrUInt64UMapVec(numberInfluences); @@ -596,7 +600,7 @@ void CBucketGatherer::baseAcceptPersistInserter(core::CStatePersistInserter& ins std::bind(TSizeSizePrUInt64UMapQueue::CSerializer(), std::cref(m_PersonAttributeCounts), std::placeholders::_1)); // Clear any empty collections before persist these are resized on restore. - TSizeSizePrOptionalStrPrUInt64UMapVecQueue influencerCounts{m_InfluencerCounts}; + TSizeSizePrOptionalStrPrUInt64UMapVecQueue const influencerCounts{m_InfluencerCounts}; inserter.insertLevel( INFLUENCERS_COUNT_TAG, std::bind(TSizeSizePrOptionalStrPrUInt64UMapVecQueue::CSerializer(), diff --git a/lib/model/CCountingModelFactory.cc b/lib/model/CCountingModelFactory.cc index ac11f9dcb..fe0238a14 100644 --- a/lib/model/CCountingModelFactory.cc +++ b/lib/model/CCountingModelFactory.cc @@ -59,21 +59,29 @@ CCountingModelFactory::makeModel(const SModelInitializationData& initData, this->interimBucketCorrector(), traverser); } -CDataGatherer* +CModelFactory::TDataGathererPtr CCountingModelFactory::makeDataGatherer(const SGathererInitializationData& initData) const { - return new CDataGatherer(model_t::E_EventRate, m_SummaryMode, this->modelParams(), - m_SummaryCountFieldName, initData.s_PartitionFieldValue, - m_PersonFieldName, EMPTY_STRING, EMPTY_STRING, {}, - this->searchKey(), m_Features, initData.s_StartTime, 0); -} - -CDataGatherer* + const CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + EMPTY_STRING, + EMPTY_STRING, + {}, + initData.s_StartTime, + 0}; + return std::make_shared( + model_t::E_EventRate, m_SummaryMode, this->modelParams(), initData.s_PartitionFieldValue, + this->searchKey(), m_Features, bucketGathererInitData); +} + +CModelFactory::TDataGathererPtr CCountingModelFactory::makeDataGatherer(const std::string& partitionFieldValue, core::CStateRestoreTraverser& traverser) const { - return new CDataGatherer(model_t::E_EventRate, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - partitionFieldValue, m_PersonFieldName, EMPTY_STRING, - EMPTY_STRING, {}, this->searchKey(), traverser); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, m_PersonFieldName, EMPTY_STRING, EMPTY_STRING, {}, 0, 0}; + return std::make_shared( + model_t::E_EventRate, m_SummaryMode, this->modelParams(), + partitionFieldValue, this->searchKey(), bucketGathererInitData, traverser); } CCountingModelFactory::TPriorPtr diff --git a/lib/model/CDataGatherer.cc b/lib/model/CDataGatherer.cc index d224feb9a..dffe6efb8 100644 --- a/lib/model/CDataGatherer.cc +++ b/lib/model/CDataGatherer.cc @@ -28,6 +28,7 @@ #include #include +#include namespace ml { namespace model { @@ -145,20 +146,14 @@ const std::size_t CDataGatherer::ESTIMATED_MEM_USAGE_PER_OVER_FIELD(1000); CDataGatherer::CDataGatherer(model_t::EAnalysisCategory gathererType, model_t::ESummaryMode summaryMode, const SModelParams& modelParams, - const std::string& summaryCountFieldName, - const std::string& partitionFieldValue, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + std::string partitionFieldValue, const CSearchKey& key, const TFeatureVec& features, - core_t::TTime startTime, - int sampleCountOverride) + const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData) : m_GathererType(gathererType), m_Features(detail::sanitize(features, gathererType)), m_SummaryMode(summaryMode), m_Params(modelParams), m_SearchKey(key), - m_PartitionFieldValue(partitionFieldValue), + m_PartitionFieldValue(std::move(partitionFieldValue)), m_PeopleRegistry(PERSON, counter_t::E_TSADNumberNewPeople, counter_t::E_TSADNumberNewPeopleNotAllowed, @@ -170,24 +165,18 @@ CDataGatherer::CDataGatherer(model_t::EAnalysisCategory gathererType, m_Population(detail::isPopulation(gathererType)), m_UseNull(key.useNull()) { std::sort(m_Features.begin(), m_Features.end()); - this->createBucketGatherer(gathererType, summaryCountFieldName, - personFieldName, attributeFieldName, valueFieldName, - influenceFieldNames, startTime, sampleCountOverride); + this->createBucketGatherer(gathererType, bucketGathererInitData); } CDataGatherer::CDataGatherer(model_t::EAnalysisCategory gathererType, model_t::ESummaryMode summaryMode, const SModelParams& modelParams, - const std::string& summaryCountFieldName, - const std::string& partitionFieldValue, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + std::string partitionFieldValue, const CSearchKey& key, + const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser) : m_GathererType(gathererType), m_SummaryMode(summaryMode), m_Params(modelParams), - m_SearchKey(key), m_PartitionFieldValue(partitionFieldValue), + m_SearchKey(key), m_PartitionFieldValue(std::move(partitionFieldValue)), m_PeopleRegistry(PERSON, counter_t::E_TSADNumberNewPeople, counter_t::E_TSADNumberNewPeopleNotAllowed, @@ -197,10 +186,10 @@ CDataGatherer::CDataGatherer(model_t::EAnalysisCategory gathererType, counter_t::E_TSADNumberNewAttributesNotAllowed, counter_t::E_TSADNumberNewAttributesRecycled), m_Population(detail::isPopulation(gathererType)), m_UseNull(key.useNull()) { - if (traverser.traverseSubLevel(std::bind( - &CDataGatherer::acceptRestoreTraverser, this, std::cref(summaryCountFieldName), - std::cref(personFieldName), std::cref(attributeFieldName), std::cref(valueFieldName), - std::cref(influenceFieldNames), std::placeholders::_1)) == false) { + auto func = [this, &bucketGathererInitData](core::CStateRestoreTraverser& traverser_) { + return acceptRestoreTraverser(bucketGathererInitData, traverser_); + }; + if (traverser.traverseSubLevel(func) == false) { LOG_ERROR(<< "Failed to correctly restore data gatherer"); } } @@ -222,8 +211,7 @@ CDataGatherer::CDataGatherer(bool isForPersistence, const CDataGatherer& other) } } -CDataGatherer::~CDataGatherer() { -} +CDataGatherer::~CDataGatherer() = default; CDataGatherer* CDataGatherer::cloneForPersistence() const { return new CDataGatherer(true, *this); @@ -308,8 +296,8 @@ bool CDataGatherer::addArrival(const TStrCPtrVec& fieldValues, // the number of partitions created. m_BucketGatherer->processFields(fieldValues, data, resourceMonitor); - core_t::TTime time = data.time(); - if (time < m_BucketGatherer->earliestBucketStartTime()) { + if (core_t::TTime const time = data.time(); + time < m_BucketGatherer->earliestBucketStartTime()) { // Ignore records that are out of the latency window. // Records in an incomplete first bucket will end up here, // but we don't want to model these. @@ -368,7 +356,7 @@ const std::string& CDataGatherer::personName(std::size_t pid, const std::string& } void CDataGatherer::personNonZeroCounts(core_t::TTime time, TSizeUInt64PrVec& result) const { - return m_BucketGatherer->personNonZeroCounts(time, result); + m_BucketGatherer->personNonZeroCounts(time, result); } void CDataGatherer::recyclePeople(const TSizeVec& peopleToRemove) { @@ -486,19 +474,17 @@ std::size_t CDataGatherer::addAttribute(const std::string& attribute, double CDataGatherer::sampleCount(std::size_t id) const { if (m_SampleCounts) { return static_cast(m_SampleCounts->count(id)); - } else { - LOG_ERROR(<< "Sample count for non-metric gatherer"); - return 0.0; } + LOG_ERROR(<< "Sample count for non-metric gatherer"); + return 0.0; } double CDataGatherer::effectiveSampleCount(std::size_t id) const { if (m_SampleCounts) { return m_SampleCounts->effectiveSampleCount(id); - } else { - LOG_ERROR(<< "Effective sample count for non-metric gatherer"); - return 0.0; } + LOG_ERROR(<< "Effective sample count for non-metric gatherer"); + return 0.0; } void CDataGatherer::resetSampleCount(std::size_t id) { @@ -608,24 +594,26 @@ const SModelParams& CDataGatherer::params() const { } void CDataGatherer::acceptPersistInserter(core::CStatePersistInserter& inserter) const { - for (std::size_t i = 0; i < m_Features.size(); ++i) { - inserter.insertValue(FEATURE_TAG, static_cast(m_Features[i])); + for (auto m_Feature : m_Features) { + inserter.insertValue(FEATURE_TAG, static_cast(m_Feature)); } - inserter.insertLevel(PEOPLE_REGISTRY_TAG, - std::bind(&CDynamicStringIdRegistry::acceptPersistInserter, - m_PeopleRegistry, std::placeholders::_1)); - inserter.insertLevel(ATTRIBUTES_REGISTRY_TAG, - std::bind(&CDynamicStringIdRegistry::acceptPersistInserter, - m_AttributesRegistry, std::placeholders::_1)); + inserter.insertLevel(PEOPLE_REGISTRY_TAG, [this](core::CStatePersistInserter& inserter_) { + m_PeopleRegistry.acceptPersistInserter(inserter_); + }); + inserter.insertLevel(ATTRIBUTES_REGISTRY_TAG, [this](core::CStatePersistInserter& inserter_) { + m_AttributesRegistry.acceptPersistInserter(inserter_); + }); if (m_SampleCounts) { - inserter.insertLevel(SAMPLE_COUNTS_TAG, - std::bind(&CSampleCounts::acceptPersistInserter, - m_SampleCounts.get(), std::placeholders::_1)); + inserter.insertLevel(SAMPLE_COUNTS_TAG, [sampleCounts = m_SampleCounts.get()]( + core::CStatePersistInserter & inserter_) { + sampleCounts->acceptPersistInserter(inserter_); + }); } - inserter.insertLevel(BUCKET_GATHERER_TAG, std::bind(&CDataGatherer::persistBucketGatherers, - this, std::placeholders::_1)); + inserter.insertLevel(BUCKET_GATHERER_TAG, [this](core::CStatePersistInserter& inserter_) { + persistBucketGatherers(inserter_); + }); } bool CDataGatherer::determineMetricCategory(TMetricCategoryVec& fieldMetricCategories) const { @@ -654,7 +642,7 @@ bool CDataGatherer::determineMetricCategory(TMetricCategoryVec& fieldMetricCateg bool CDataGatherer::extractCountFromField(const std::string& fieldName, const std::string* fieldValue, - std::size_t& count) const { + std::size_t& count) { if (fieldValue == nullptr) { // Treat not present as explicit null count = EXPLICIT_NULL_SUMMARY_COUNT; @@ -695,13 +683,13 @@ bool CDataGatherer::extractMetricFromField(const std::string& fieldName, // Split the string up by the delimiter and parse each token separately. std::size_t first = 0; do { - std::size_t last = fieldValue.find(delimiter, first); + std::size_t const last = fieldValue.find(delimiter, first); double value; // Avoid a string duplication in the (common) case of only one value - bool convertedOk = (first == 0 && last == std::string::npos) - ? core::CStringUtils::stringToType(fieldValue, value) - : core::CStringUtils::stringToType( - fieldValue.substr(first, last - first), value); + bool const convertedOk = (first == 0 && last == std::string::npos) + ? core::CStringUtils::stringToType(fieldValue, value) + : core::CStringUtils::stringToType( + fieldValue.substr(first, last - first), value); if (!convertedOk) { LOG_ERROR(<< "Unable to extract " << fieldName << " from " << fieldValue); result.clear(); @@ -739,11 +727,7 @@ bool CDataGatherer::checkInvariants() const { return true; } -bool CDataGatherer::acceptRestoreTraverser(const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, +bool CDataGatherer::acceptRestoreTraverser(const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser) { this->clear(); m_Features.clear(); @@ -775,34 +759,26 @@ bool CDataGatherer::acceptRestoreTraverser(const std::string& summaryCountFieldN RESTORE(BUCKET_GATHERER_TAG, traverser.traverseSubLevel(std::bind( &CDataGatherer::restoreBucketGatherer, this, - std::cref(summaryCountFieldName), std::cref(personFieldName), - std::cref(attributeFieldName), std::cref(valueFieldName), - std::cref(influenceFieldNames), std::placeholders::_1))) + std::cref(bucketGathererInitData), std::placeholders::_1))) } while (traverser.next()); return true; } -bool CDataGatherer::restoreBucketGatherer(const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, +bool CDataGatherer::restoreBucketGatherer(const CBucketGatherer::SBucketGathererInitData& bucketGathererInitData, core::CStateRestoreTraverser& traverser) { do { const std::string& name = traverser.name(); if (name == CBucketGatherer::EVENTRATE_BUCKET_GATHERER_TAG) { m_BucketGatherer = std::make_unique( - *this, summaryCountFieldName, personFieldName, attributeFieldName, - valueFieldName, influenceFieldNames, traverser); + *this, bucketGathererInitData, traverser); if (m_BucketGatherer == nullptr) { LOG_ERROR(<< "Failed to create event rate bucket gatherer"); return false; } } else if (name == CBucketGatherer::METRIC_BUCKET_GATHERER_TAG) { m_BucketGatherer = std::make_unique( - *this, summaryCountFieldName, personFieldName, attributeFieldName, - valueFieldName, influenceFieldNames, traverser); + *this, bucketGathererInitData, traverser); if (m_BucketGatherer == nullptr) { LOG_ERROR(<< "Failed to create metric bucket gatherer"); return false; @@ -819,32 +795,24 @@ bool CDataGatherer::restoreBucketGatherer(const std::string& summaryCountFieldNa } void CDataGatherer::persistBucketGatherers(core::CStatePersistInserter& inserter) const { - inserter.insertLevel(m_BucketGatherer->persistenceTag(), - std::bind(&CBucketGatherer::acceptPersistInserter, - m_BucketGatherer.get(), std::placeholders::_1)); + inserter.insertLevel( + m_BucketGatherer->persistenceTag(), [capture0 = m_BucketGatherer.get()]( + core::CStatePersistInserter & inserter_) { + capture0->acceptPersistInserter(inserter_); + }); } void CDataGatherer::createBucketGatherer(model_t::EAnalysisCategory gathererType, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime, - unsigned int sampleCountOverride) { + const CBucketGatherer::SBucketGathererInitData& initData) { switch (gathererType) { case model_t::E_EventRate: case model_t::E_PopulationEventRate: - m_BucketGatherer = std::make_unique( - *this, summaryCountFieldName, personFieldName, attributeFieldName, - valueFieldName, influenceFieldNames, startTime); + m_BucketGatherer = std::make_unique(*this, initData); break; case model_t::E_Metric: case model_t::E_PopulationMetric: - m_SampleCounts = std::make_unique(sampleCountOverride); - m_BucketGatherer = std::make_unique( - *this, summaryCountFieldName, personFieldName, attributeFieldName, - valueFieldName, influenceFieldNames, startTime); + m_SampleCounts = std::make_unique(initData.s_SampleOverrideCount); + m_BucketGatherer = std::make_unique(*this, initData); break; } } diff --git a/lib/model/CEventRateBucketGatherer.cc b/lib/model/CEventRateBucketGatherer.cc index c30dd1585..a01ddc9cd 100644 --- a/lib/model/CEventRateBucketGatherer.cc +++ b/lib/model/CEventRateBucketGatherer.cc @@ -727,30 +727,17 @@ void registerMemoryCallbacks() { } // unnamed:: CEventRateBucketGatherer::CEventRateBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime) - : CBucketGatherer(dataGatherer, startTime, influenceFieldNames.size()), - m_BeginInfluencingFields(0), m_BeginValueField(0), m_BeginSummaryFields(0) { - this->initializeFieldNames(personFieldName, attributeFieldName, valueFieldName, - summaryCountFieldName, influenceFieldNames); + const SBucketGathererInitData& initData) + : CBucketGatherer(dataGatherer, initData) { + this->initializeFieldNames(initData); this->initializeFeatureData(); } CEventRateBucketGatherer::CEventRateBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + const SBucketGathererInitData& initData, core::CStateRestoreTraverser& traverser) - : CBucketGatherer(dataGatherer, 0, influenceFieldNames.size()), - m_BeginInfluencingFields(0), m_BeginValueField(0), m_BeginSummaryFields(0) { - this->initializeFieldNames(personFieldName, attributeFieldName, valueFieldName, - summaryCountFieldName, influenceFieldNames); + : CBucketGatherer(dataGatherer, initData) { + this->initializeFieldNames(initData); if (traverser.traverseSubLevel(std::bind(&CEventRateBucketGatherer::acceptRestoreTraverser, this, std::placeholders::_1)) == false) { traverser.setBadState(); @@ -1501,23 +1488,19 @@ void CEventRateBucketGatherer::startNewBucket(core_t::TTime time, bool /*skipUpd }); } -void CEventRateBucketGatherer::initializeFieldNames(const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const std::string& summaryCountFieldName, - const TStrVec& influenceFieldNames) { - m_FieldNames.push_back(personFieldName); +void CEventRateBucketGatherer::initializeFieldNames(const CBucketGatherer::SBucketGathererInitData& initData) { + m_FieldNames.push_back(initData.s_PersonFieldName); if (m_DataGatherer.isPopulation()) { - m_FieldNames.push_back(attributeFieldName); + m_FieldNames.push_back(initData.s_AttributeFieldName); } m_BeginInfluencingFields = m_FieldNames.size(); - m_FieldNames.insert(m_FieldNames.end(), influenceFieldNames.begin(), - influenceFieldNames.end()); + m_FieldNames.insert(m_FieldNames.end(), initData.s_InfluenceFieldNames.begin(), + initData.s_InfluenceFieldNames.end()); m_BeginValueField = m_FieldNames.size(); - if (!valueFieldName.empty()) { - m_FieldNames.push_back(valueFieldName); + if (!initData.s_ValueFieldName.empty()) { + m_FieldNames.push_back(initData.s_ValueFieldName); } m_BeginSummaryFields = m_FieldNames.size(); @@ -1525,7 +1508,7 @@ void CEventRateBucketGatherer::initializeFieldNames(const std::string& personFie case model_t::E_None: break; case model_t::E_Manual: - m_FieldNames.push_back(summaryCountFieldName); + m_FieldNames.push_back(initData.s_SummaryCountFieldName); break; } diff --git a/lib/model/CEventRateModelFactory.cc b/lib/model/CEventRateModelFactory.cc index 2ddb927d4..2c2947bd8 100644 --- a/lib/model/CEventRateModelFactory.cc +++ b/lib/model/CEventRateModelFactory.cc @@ -90,24 +90,29 @@ CEventRateModelFactory::makeModel(const SModelInitializationData& initData, influenceCalculators, this->interimBucketCorrector(), traverser); } -CDataGatherer* +CModelFactory::TDataGathererPtr CEventRateModelFactory::makeDataGatherer(const SGathererInitializationData& initData) const { - return new CDataGatherer(model_t::E_EventRate, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - initData.s_PartitionFieldValue, m_PersonFieldName, - EMPTY_STRING /*AttributeFieldName*/, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), m_Features, - initData.s_StartTime, initData.s_SampleOverrideCount); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + EMPTY_STRING, + m_ValueFieldName, + m_InfluenceFieldNames, + initData.s_StartTime, + initData.s_SampleOverrideCount}; + return std::make_shared( + model_t::E_EventRate, m_SummaryMode, this->modelParams(), initData.s_PartitionFieldValue, + this->searchKey(), m_Features, bucketGathererInitData); } -CDataGatherer* +CModelFactory::TDataGathererPtr CEventRateModelFactory::makeDataGatherer(const std::string& partitionFieldValue, core::CStateRestoreTraverser& traverser) const { - return new CDataGatherer(model_t::E_EventRate, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - partitionFieldValue, m_PersonFieldName, - EMPTY_STRING /*AttributeFieldName*/, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), traverser); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, m_PersonFieldName, EMPTY_STRING, m_ValueFieldName, m_InfluenceFieldNames, 0, 0}; + return std::make_shared( + model_t::E_EventRate, m_SummaryMode, this->modelParams(), + partitionFieldValue, this->searchKey(), bucketGathererInitData, traverser); } CEventRateModelFactory::TPriorPtr diff --git a/lib/model/CEventRatePopulationModelFactory.cc b/lib/model/CEventRatePopulationModelFactory.cc index 39042ac74..1c3836c00 100644 --- a/lib/model/CEventRatePopulationModelFactory.cc +++ b/lib/model/CEventRatePopulationModelFactory.cc @@ -91,23 +91,36 @@ CEventRatePopulationModelFactory::makeModel(const SModelInitializationData& init influenceCalculators, this->interimBucketCorrector(), traverser); } -CDataGatherer* +CModelFactory::TDataGathererPtr CEventRatePopulationModelFactory::makeDataGatherer(const SGathererInitializationData& initData) const { - return new CDataGatherer(model_t::E_PopulationEventRate, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - initData.s_PartitionFieldValue, m_PersonFieldName, - m_AttributeFieldName, m_ValueFieldName, m_InfluenceFieldNames, - this->searchKey(), m_Features, initData.s_StartTime, 0); + CBucketGatherer::SBucketGathererInitData const bucketGathererInitData{ + .s_SummaryCountFieldName = m_SummaryCountFieldName, + .s_PersonFieldName = m_PersonFieldName, + .s_AttributeFieldName = m_AttributeFieldName, + .s_ValueFieldName = m_ValueFieldName, + .s_InfluenceFieldNames = m_InfluenceFieldNames, + .s_StartTime = initData.s_StartTime, + .s_SampleOverrideCount = 0}; + return std::make_shared( + model_t::E_PopulationEventRate, m_SummaryMode, this->modelParams(), + initData.s_PartitionFieldValue, this->searchKey(), m_Features, + bucketGathererInitData); } -CDataGatherer* +CModelFactory::TDataGathererPtr CEventRatePopulationModelFactory::makeDataGatherer(const std::string& partitionFieldValue, core::CStateRestoreTraverser& traverser) const { - return new CDataGatherer(model_t::E_PopulationEventRate, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - partitionFieldValue, m_PersonFieldName, - m_AttributeFieldName, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), traverser); + CBucketGatherer::SBucketGathererInitData const bucketGathererInitData{ + .s_SummaryCountFieldName = m_SummaryCountFieldName, + .s_PersonFieldName = m_PersonFieldName, + .s_AttributeFieldName = m_AttributeFieldName, + .s_ValueFieldName = m_ValueFieldName, + .s_InfluenceFieldNames = m_InfluenceFieldNames, + .s_StartTime = 0, + .s_SampleOverrideCount = 0}; + return std::make_shared( + model_t::E_PopulationEventRate, m_SummaryMode, this->modelParams(), + partitionFieldValue, this->searchKey(), bucketGathererInitData, traverser); } CEventRatePopulationModelFactory::TPriorPtr diff --git a/lib/model/CMetricBucketGatherer.cc b/lib/model/CMetricBucketGatherer.cc index 80951cb98..19cfb8ccb 100644 --- a/lib/model/CMetricBucketGatherer.cc +++ b/lib/model/CMetricBucketGatherer.cc @@ -925,35 +925,25 @@ struct SReleaseMemory { } // unnamed:: CMetricBucketGatherer::CMetricBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, - core_t::TTime startTime) - : CBucketGatherer(dataGatherer, startTime, influenceFieldNames.size()), - m_ValueFieldName(valueFieldName), m_BeginInfluencingFields(0), - m_BeginValueFields(0) { - this->initializeFieldNamesPart1(personFieldName, attributeFieldName, influenceFieldNames); - this->initializeFieldNamesPart2(valueFieldName, summaryCountFieldName); + const SBucketGathererInitData& initData) + : CBucketGatherer(dataGatherer, initData), + m_ValueFieldName(initData.s_ValueFieldName) { + this->initializeFieldNamesPart1(initData); + this->initializeFieldNamesPart2(initData); this->initializeFeatureData(); } CMetricBucketGatherer::CMetricBucketGatherer(CDataGatherer& dataGatherer, - const std::string& summaryCountFieldName, - const std::string& personFieldName, - const std::string& attributeFieldName, - const std::string& valueFieldName, - const TStrVec& influenceFieldNames, + const SBucketGathererInitData& initData, core::CStateRestoreTraverser& traverser) - : CBucketGatherer(dataGatherer, 0, influenceFieldNames.size()), - m_ValueFieldName(valueFieldName), m_BeginValueFields(0) { - this->initializeFieldNamesPart1(personFieldName, attributeFieldName, influenceFieldNames); + : CBucketGatherer(dataGatherer, initData), + m_ValueFieldName(initData.s_ValueFieldName) { + this->initializeFieldNamesPart1(initData); if (traverser.traverseSubLevel(std::bind(&CMetricBucketGatherer::acceptRestoreTraverser, this, std::placeholders::_1)) == false) { traverser.setBadState(); } else { - this->initializeFieldNamesPart2(valueFieldName, summaryCountFieldName); + this->initializeFieldNamesPart2(initData); } } @@ -1505,44 +1495,41 @@ void CMetricBucketGatherer::startNewBucket(core_t::TTime time, bool skipUpdates) }); } -void CMetricBucketGatherer::initializeFieldNamesPart1(const std::string& personFieldName, - const std::string& attributeFieldName, - const TStrVec& influenceFieldNames) { +void CMetricBucketGatherer::initializeFieldNamesPart1(const SBucketGathererInitData& initData) { switch (m_DataGatherer.summaryMode()) { case model_t::E_None: m_FieldNames.reserve(2 + static_cast(m_DataGatherer.isPopulation()) + - influenceFieldNames.size()); - m_FieldNames.push_back(personFieldName); + initData.s_InfluenceFieldNames.size()); + m_FieldNames.push_back(initData.s_PersonFieldName); if (m_DataGatherer.isPopulation()) - m_FieldNames.push_back(attributeFieldName); + m_FieldNames.push_back(initData.s_AttributeFieldName); m_BeginInfluencingFields = m_FieldNames.size(); - m_FieldNames.insert(m_FieldNames.end(), influenceFieldNames.begin(), - influenceFieldNames.end()); + m_FieldNames.insert(m_FieldNames.end(), initData.s_InfluenceFieldNames.begin(), + initData.s_InfluenceFieldNames.end()); m_BeginValueFields = m_FieldNames.size(); break; case model_t::E_Manual: m_FieldNames.reserve(3 + static_cast(m_DataGatherer.isPopulation()) + - influenceFieldNames.size()); - m_FieldNames.push_back(personFieldName); + initData.s_InfluenceFieldNames.size()); + m_FieldNames.push_back(initData.s_PersonFieldName); if (m_DataGatherer.isPopulation()) - m_FieldNames.push_back(attributeFieldName); + m_FieldNames.push_back(initData.s_AttributeFieldName); m_BeginInfluencingFields = m_FieldNames.size(); - m_FieldNames.insert(m_FieldNames.end(), influenceFieldNames.begin(), - influenceFieldNames.end()); + m_FieldNames.insert(m_FieldNames.end(), initData.s_InfluenceFieldNames.begin(), + initData.s_InfluenceFieldNames.end()); m_BeginValueFields = m_FieldNames.size(); break; - }; + } } -void CMetricBucketGatherer::initializeFieldNamesPart2(const std::string& valueFieldName, - const std::string& summaryCountFieldName) { +void CMetricBucketGatherer::initializeFieldNamesPart2(const SBucketGathererInitData& initData) { switch (m_DataGatherer.summaryMode()) { case model_t::E_None: - m_FieldNames.push_back(valueFieldName); + m_FieldNames.push_back(initData.s_ValueFieldName); break; case model_t::E_Manual: - m_FieldNames.push_back(summaryCountFieldName); - m_FieldNames.push_back(valueFieldName); + m_FieldNames.push_back(initData.s_SummaryCountFieldName); + m_FieldNames.push_back(initData.s_ValueFieldName); m_DataGatherer.determineMetricCategory(m_FieldMetricCategories); break; }; diff --git a/lib/model/CMetricModelFactory.cc b/lib/model/CMetricModelFactory.cc index e627bfc02..f74f2ce3b 100644 --- a/lib/model/CMetricModelFactory.cc +++ b/lib/model/CMetricModelFactory.cc @@ -90,23 +90,29 @@ CMetricModelFactory::makeModel(const SModelInitializationData& initData, influenceCalculators, this->interimBucketCorrector(), traverser); } -CDataGatherer* +CModelFactory::TDataGathererPtr CMetricModelFactory::makeDataGatherer(const SGathererInitializationData& initData) const { - return new CDataGatherer(model_t::E_Metric, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - initData.s_PartitionFieldValue, m_PersonFieldName, - EMPTY_STRING /*AttributeFieldName*/, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), m_Features, - initData.s_StartTime, initData.s_SampleOverrideCount); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + EMPTY_STRING /*AttributeFieldName*/, + m_ValueFieldName, + m_InfluenceFieldNames, + initData.s_StartTime, + initData.s_SampleOverrideCount}; + return std::make_shared( + model_t::E_Metric, m_SummaryMode, this->modelParams(), initData.s_PartitionFieldValue, + this->searchKey(), m_Features, bucketGathererInitData); } -CDataGatherer* +CModelFactory::TDataGathererPtr CMetricModelFactory::makeDataGatherer(const std::string& partitionFieldValue, core::CStateRestoreTraverser& traverser) const { - return new CDataGatherer(model_t::E_Metric, m_SummaryMode, this->modelParams(), - m_SummaryCountFieldName, partitionFieldValue, m_PersonFieldName, - EMPTY_STRING /*AttributeFieldName*/, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), traverser); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, m_PersonFieldName, EMPTY_STRING, m_ValueFieldName, m_InfluenceFieldNames, 0, 0}; + return std::make_shared( + model_t::E_Metric, m_SummaryMode, this->modelParams(), partitionFieldValue, + this->searchKey(), bucketGathererInitData, traverser); } CMetricModelFactory::TPriorPtr diff --git a/lib/model/CMetricPopulationModelFactory.cc b/lib/model/CMetricPopulationModelFactory.cc index a758937dd..deff0c863 100644 --- a/lib/model/CMetricPopulationModelFactory.cc +++ b/lib/model/CMetricPopulationModelFactory.cc @@ -90,24 +90,33 @@ CMetricPopulationModelFactory::makeModel(const SModelInitializationData& initDat influenceCalculators, this->interimBucketCorrector(), traverser); } -CDataGatherer* +CModelFactory::TDataGathererPtr CMetricPopulationModelFactory::makeDataGatherer(const SGathererInitializationData& initData) const { - return new CDataGatherer(model_t::E_PopulationMetric, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - initData.s_PartitionFieldValue, m_PersonFieldName, - m_AttributeFieldName, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), m_Features, - initData.s_StartTime, initData.s_SampleOverrideCount); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, m_PersonFieldName, + m_AttributeFieldName, m_ValueFieldName, + m_InfluenceFieldNames, initData.s_StartTime, + initData.s_SampleOverrideCount}; + return std::make_shared( + model_t::E_PopulationMetric, m_SummaryMode, this->modelParams(), + initData.s_PartitionFieldValue, this->searchKey(), m_Features, + bucketGathererInitData); } -CDataGatherer* +CModelFactory::TDataGathererPtr CMetricPopulationModelFactory::makeDataGatherer(const std::string& partitionFieldValue, core::CStateRestoreTraverser& traverser) const { - return new CDataGatherer(model_t::E_PopulationMetric, m_SummaryMode, - this->modelParams(), m_SummaryCountFieldName, - partitionFieldValue, m_PersonFieldName, - m_AttributeFieldName, m_ValueFieldName, - m_InfluenceFieldNames, this->searchKey(), traverser); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + m_AttributeFieldName, + m_ValueFieldName, + m_InfluenceFieldNames, + 0, + 0}; + return std::make_shared( + model_t::E_PopulationMetric, m_SummaryMode, this->modelParams(), + partitionFieldValue, this->searchKey(), bucketGathererInitData, traverser); } CMetricPopulationModelFactory::TPriorPtr diff --git a/lib/model/unittest/CEventRateDataGathererTest.cc b/lib/model/unittest/CEventRateDataGathererTest.cc index d62ef85a6..859d0e204 100644 --- a/lib/model/unittest/CEventRateDataGathererTest.cc +++ b/lib/model/unittest/CEventRateDataGathererTest.cc @@ -1723,6 +1723,7 @@ class CDiurnalTestFixture : public CTestFixture { .attributeFieldName("att") .build(); } + if (!isPopulation) { return builder.personFieldName("person").build(); } diff --git a/lib/model/unittest/CEventRatePopulationDataGathererTest.cc b/lib/model/unittest/CEventRatePopulationDataGathererTest.cc index 702704587..f10095646 100644 --- a/lib/model/unittest/CEventRatePopulationDataGathererTest.cc +++ b/lib/model/unittest/CEventRatePopulationDataGathererTest.cc @@ -783,10 +783,12 @@ void testPersistDataGatherer(const CDataGatherer& origDataGatherer, std::istringstream origJsonStrm("{\"topLevel\" : " + origJson.str() + "}"); core::CJsonStateRestoreTraverser traverser(origJsonStrm); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, {}, 0, 0}; + CDataGatherer restoredDataGatherer(model_t::E_PopulationEventRate, model_t::E_None, params, EMPTY_STRING, - EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, - EMPTY_STRING, {}, searchKey, traverser); + searchKey, bucketGathererInitData, traverser); // The Json representation of the new data gatherer should be the same as the // original @@ -809,6 +811,7 @@ BOOST_FIXTURE_TEST_CASE(testPersistence, CTestFixture) { features.push_back(model_t::E_PopulationUniquePersonCountByAttribute); SModelParams const params(bucketLength); CDataGatherer origDataGatherer = + CDataGathererBuilder(model_t::E_PopulationEventRate, features, params, searchKey, startTime) .build(); @@ -831,6 +834,7 @@ BOOST_FIXTURE_TEST_CASE(testPersistence, CTestFixture) { features.push_back(model_t::E_PopulationInfoContentByBucketPersonAndAttribute); SModelParams const params(bucketLength); CDataGatherer dataGatherer = + CDataGathererBuilder(model_t::E_PopulationEventRate, features, params, searchKey, startTime) .valueFieldName("value") diff --git a/lib/model/unittest/CHierarchicalResultsTest.cc b/lib/model/unittest/CHierarchicalResultsTest.cc index 1491592ec..4b54244cb 100644 --- a/lib/model/unittest/CHierarchicalResultsTest.cc +++ b/lib/model/unittest/CHierarchicalResultsTest.cc @@ -1446,7 +1446,7 @@ BOOST_AUTO_TEST_CASE(testWriter) { model::SModelParams const params(modelConfig.bucketLength()); auto interimBucketCorrector = std::make_shared(modelConfig.bucketLength()); - model::CSearchKey const key; + model::CSearchKey key; auto dataGatherer = model::CDataGathererBuilder(model_t::E_EventRate, {model_t::E_IndividualCountByBucketAndPerson}, diff --git a/lib/model/unittest/CMetricPopulationDataGathererTest.cc b/lib/model/unittest/CMetricPopulationDataGathererTest.cc index 6c4be3280..5dbc6d734 100644 --- a/lib/model/unittest/CMetricPopulationDataGathererTest.cc +++ b/lib/model/unittest/CMetricPopulationDataGathererTest.cc @@ -1028,11 +1028,12 @@ BOOST_FIXTURE_TEST_CASE(testPersistence, CTestFixture) { // The traverser expects the state json in a embedded document std::stringstream origJsonStrm{"{\"topLevel\" : " + origJson.str() + "}"}; core::CJsonStateRestoreTraverser traverser(origJsonStrm); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, {}, 0, 0}; - CDataGatherer restoredDataGatherer(model_t::E_PopulationMetric, - model_t::E_None, params, EMPTY_STRING, - EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, - EMPTY_STRING, {}, searchKey, traverser); + CDataGatherer restoredDataGatherer(model_t::E_PopulationMetric, model_t::E_None, + params, EMPTY_STRING, searchKey, + bucketGathererInitData, traverser); // The JSON representation of the new data gatherer should be the same as the // original diff --git a/lib/model/unittest/CModelTestFixtureBase.h b/lib/model/unittest/CModelTestFixtureBase.h index c78a96b36..da8881dbb 100644 --- a/lib/model/unittest/CModelTestFixtureBase.h +++ b/lib/model/unittest/CModelTestFixtureBase.h @@ -243,7 +243,7 @@ class CModelTestFixtureBase { if (sampleCount) { initData.s_SampleOverrideCount = *sampleCount; } - gatherer.reset(m_Factory->makeDataGatherer(initData)); + gatherer = m_Factory->makeDataGatherer(initData); model.reset(m_Factory->makeModel({gatherer})); BOOST_TEST_REQUIRE(model); diff --git a/lib/model/unittest/CResourceLimitTest.cc b/lib/model/unittest/CResourceLimitTest.cc index 6d9253d49..853325399 100644 --- a/lib/model/unittest/CResourceLimitTest.cc +++ b/lib/model/unittest/CResourceLimitTest.cc @@ -292,7 +292,7 @@ TAddPersonDataFunc createModel(model_t::EModelType modelType, features.push_back(model_t::E_IndividualCountByBucketAndPerson); factory->features(features); - gatherer.reset(factory->makeDataGatherer(firstTime)); + gatherer = factory->makeDataGatherer(firstTime); const maths::common::CMultinomialConjugate conjugate; std::shared_ptr model_ = std::make_shared( @@ -323,7 +323,7 @@ TAddPersonDataFunc createModel(model_t::EModelType modelType, features.push_back(model_t::E_IndividualMaxByPerson); factory->features(features); - gatherer.reset(factory->makeDataGatherer(firstTime)); + gatherer = factory->makeDataGatherer(firstTime); std::shared_ptr model_ = std::make_shared( factory->modelParams(), gatherer, diff --git a/lib/model/unittest/ModelTestHelpers.h b/lib/model/unittest/ModelTestHelpers.h index ba474c719..69554cac3 100644 --- a/lib/model/unittest/ModelTestHelpers.h +++ b/lib/model/unittest/ModelTestHelpers.h @@ -45,9 +45,11 @@ static void testPersistence(const SModelParams& params, std::istringstream origJsonStrm{"{\"topLevel\" : " + origJson.str() + "}"}; core::CJsonStateRestoreTraverser traverser(origJsonStrm); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, {}, 0, 0}; + CDataGatherer restoredGatherer(category, model_t::E_None, params, EMPTY_STRING, - EMPTY_STRING, EMPTY_STRING, EMPTY_STRING, - EMPTY_STRING, {}, KEY, traverser); + KEY, bucketGathererInitData, traverser); BOOST_REQUIRE_EQUAL(origGatherer.checksum(), restoredGatherer.checksum()); @@ -96,27 +98,31 @@ class CDataGathererBuilder { m_SearchKey(searchKey), m_GathererType(gathererType) {} CDataGatherer build() const { - return {m_GathererType, - m_SummaryMode, - m_Params, - m_SummaryCountFieldName, - m_PartitionFieldValue, - m_PersonFieldName, - m_AttributeFieldName, - m_ValueFieldName, - m_InfluenceFieldNames, - m_SearchKey, - m_Features, - m_StartTime, - m_SampleCountOverride}; + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + m_AttributeFieldName, + m_ValueFieldName, + m_InfluenceFieldNames, + m_StartTime, + static_cast(m_SampleCountOverride)}; + return {m_GathererType, m_SummaryMode, m_Params, + m_PartitionFieldValue, m_SearchKey, m_Features, + bucketGathererInitData}; } std::shared_ptr buildSharedPtr() const { - return std::make_shared( - m_GathererType, m_SummaryMode, m_Params, m_SummaryCountFieldName, - m_PartitionFieldValue, m_PersonFieldName, m_AttributeFieldName, - m_ValueFieldName, m_InfluenceFieldNames, m_SearchKey, m_Features, - m_StartTime, m_SampleCountOverride); + CBucketGatherer::SBucketGathererInitData bucketGathererInitData{ + m_SummaryCountFieldName, + m_PersonFieldName, + m_AttributeFieldName, + m_ValueFieldName, + m_InfluenceFieldNames, + m_StartTime, + static_cast(m_SampleCountOverride)}; + return std::make_shared(m_GathererType, m_SummaryMode, m_Params, + m_PartitionFieldValue, m_SearchKey, + m_Features, bucketGathererInitData); } CDataGathererBuilder& partitionFieldValue(std::string_view partitionFieldValue) {