Refactor determine metric update status
Refactor and create a generic determineMetricUpdateStatus() function
that works for all metrics. Will simplify the process of determining
if a metric needs an update for all future metric types.
Test: atest statsd_test
Bug: 168863134
Bug: 176249205
Bug: 176248686
Merged-In: I751e2c7c8bbbd819f216821cbf4f0ec315c4563b
Change-Id: If89e1625cf7536406fbd168aca63193d5e9a908f
diff --git a/bin/src/metrics/parsing_utils/config_update_utils.cpp b/bin/src/metrics/parsing_utils/config_update_utils.cpp
index 5dbf16d..2ae5763 100644
--- a/bin/src/metrics/parsing_utils/config_update_utils.cpp
+++ b/bin/src/metrics/parsing_utils/config_update_utils.cpp
@@ -24,6 +24,8 @@
#include "matchers/EventMatcherWizard.h"
#include "metrics_manager_util.h"
+using google::protobuf::MessageLite;
+
namespace android {
namespace os {
namespace statsd {
@@ -419,16 +421,19 @@
return false;
}
-bool determineEventMetricUpdateStatus(const StatsdConfig& config, const EventMetric& metric,
- const unordered_map<int64_t, int>& oldMetricProducerMap,
- const vector<sp<MetricProducer>>& oldMetricProducers,
- const unordered_map<int64_t, int>& metricToActivationMap,
- const set<int64_t>& replacedMatchers,
- const set<int64_t>& replacedConditions,
- UpdateStatus& updateStatus) {
- int64_t id = metric.id();
+bool determineMetricUpdateStatus(
+ const StatsdConfig& config, const MessageLite& metric, const int64_t metricId,
+ const MetricType metricType, const set<int64_t>& matcherDependencies,
+ const set<int64_t>& conditionDependencies,
+ const ::google::protobuf::RepeatedField<int64_t>& stateDependencies,
+ const ::google::protobuf::RepeatedPtrField<MetricConditionLink>& conditionLinks,
+ const unordered_map<int64_t, int>& oldMetricProducerMap,
+ const vector<sp<MetricProducer>>& oldMetricProducers,
+ const unordered_map<int64_t, int>& metricToActivationMap,
+ const set<int64_t>& replacedMatchers, const set<int64_t>& replacedConditions,
+ const set<int64_t>& replacedStates, UpdateStatus& updateStatus) {
// Check if new metric
- const auto& oldMetricProducerIt = oldMetricProducerMap.find(id);
+ const auto& oldMetricProducerIt = oldMetricProducerMap.find(metricId);
if (oldMetricProducerIt == oldMetricProducerMap.end()) {
updateStatus = UPDATE_NEW;
return true;
@@ -436,44 +441,85 @@
// This is an existing metric, check if it has changed.
uint64_t metricHash;
- if (!getMetricProtoHash(config, metric, id, metricToActivationMap, metricHash)) {
+ if (!getMetricProtoHash(config, metric, metricId, metricToActivationMap, metricHash)) {
return false;
}
const sp<MetricProducer> oldMetricProducer = oldMetricProducers[oldMetricProducerIt->second];
- if (oldMetricProducer->getMetricType() != METRIC_TYPE_EVENT ||
+ if (oldMetricProducer->getMetricType() != metricType ||
oldMetricProducer->getProtoHash() != metricHash) {
updateStatus = UPDATE_REPLACE;
return true;
}
- // Metric type and definition are the same. Need to check dependencies to see if they changed.
- if (replacedMatchers.find(metric.what()) != replacedMatchers.end()) {
+ // Take intersections of the matchers/predicates/states that the metric
+ // depends on with those that have been replaced. If a metric depends on any
+ // replaced component, it too must be replaced.
+ set<int64_t> intersection;
+ set_intersection(matcherDependencies.begin(), matcherDependencies.end(),
+ replacedMatchers.begin(), replacedMatchers.end(),
+ inserter(intersection, intersection.begin()));
+ if (intersection.size() > 0) {
+ updateStatus = UPDATE_REPLACE;
+ return true;
+ }
+ set_intersection(conditionDependencies.begin(), conditionDependencies.end(),
+ replacedConditions.begin(), replacedConditions.end(),
+ inserter(intersection, intersection.begin()));
+ if (intersection.size() > 0) {
+ updateStatus = UPDATE_REPLACE;
+ return true;
+ }
+ set_intersection(stateDependencies.begin(), stateDependencies.end(), replacedStates.begin(),
+ replacedStates.end(), inserter(intersection, intersection.begin()));
+ if (intersection.size() > 0) {
updateStatus = UPDATE_REPLACE;
return true;
}
- if (metric.has_condition()) {
- if (replacedConditions.find(metric.condition()) != replacedConditions.end()) {
- updateStatus = UPDATE_REPLACE;
- return true;
- }
- }
-
- if (metricActivationDepsChange(config, metricToActivationMap, id, replacedMatchers)) {
- updateStatus = UPDATE_REPLACE;
- return true;
- }
-
- for (const auto& metricConditionLink : metric.links()) {
+ for (const auto& metricConditionLink : conditionLinks) {
if (replacedConditions.find(metricConditionLink.condition()) != replacedConditions.end()) {
updateStatus = UPDATE_REPLACE;
return true;
}
}
+
+ if (metricActivationDepsChange(config, metricToActivationMap, metricId, replacedMatchers)) {
+ updateStatus = UPDATE_REPLACE;
+ return true;
+ }
+
updateStatus = UPDATE_PRESERVE;
return true;
}
+bool determineAllMetricUpdateStatuses(const StatsdConfig& config,
+ const unordered_map<int64_t, int>& oldMetricProducerMap,
+ const vector<sp<MetricProducer>>& oldMetricProducers,
+ const unordered_map<int64_t, int>& metricToActivationMap,
+ const set<int64_t>& replacedMatchers,
+ const set<int64_t>& replacedConditions,
+ const set<int64_t>& replacedStates,
+ vector<UpdateStatus>& metricsToUpdate) {
+ int metricIndex = 0;
+ for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
+ const EventMetric& metric = config.event_metric(i);
+ set<int64_t> conditionDependencies;
+ if (metric.has_condition()) {
+ conditionDependencies.insert(metric.condition());
+ }
+ if (!determineMetricUpdateStatus(
+ config, metric, metric.id(), METRIC_TYPE_EVENT, {metric.what()},
+ conditionDependencies, ::google::protobuf::RepeatedField<int64_t>(),
+ metric.links(), oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
+ replacedMatchers, replacedConditions, replacedStates,
+ metricsToUpdate[metricIndex])) {
+ return false;
+ }
+ }
+ // TODO: determine update status for count, gauge, value, duration metrics.
+ return true;
+}
+
bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
@@ -518,22 +564,16 @@
}
vector<UpdateStatus> metricsToUpdate(allMetricsCount, UPDATE_UNKNOWN);
+ if (!determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
+ metricToActivationMap, replacedMatchers,
+ replacedConditions, replacedStates, metricsToUpdate)) {
+ return false;
+ }
+
+ // Now, perform the update. Must iterate the metric types in the same order
int metricIndex = 0;
for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
newMetricProducerMap[config.event_metric(i).id()] = metricIndex;
- if (!determineEventMetricUpdateStatus(config, config.event_metric(i), oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions,
- metricsToUpdate[metricIndex])) {
- return false;
- }
- }
-
- // TODO: determine update status for count, gauge, value, duration metrics.
-
- // Now, perform the update. Must iterate the metric types in the same order
- metricIndex = 0;
- for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
const EventMetric& metric = config.event_metric(i);
switch (metricsToUpdate[metricIndex]) {
case UPDATE_PRESERVE: {
diff --git a/bin/src/metrics/parsing_utils/config_update_utils.h b/bin/src/metrics/parsing_utils/config_update_utils.h
index 1cd0ce5..34d7e9c 100644
--- a/bin/src/metrics/parsing_utils/config_update_utils.h
+++ b/bin/src/metrics/parsing_utils/config_update_utils.h
@@ -125,23 +125,25 @@
std::vector<ConditionState>& conditionCache,
std::set<int64_t>& replacedConditions);
-// Function to determine if an event metric needs to be updated. Populates updateStatus.
+// Function to determine the update status (preserve/replace/new) of all metrics in the config.
// [config]: the input StatsdConfig
-// [metric]: the current metric to be updated
// [oldMetricProducerMap]: metric id to index mapping in the existing MetricsManager
// [oldMetricProducers]: stores the existing MetricProducers
-// [metricToActivationMap]: map from metric id to metric activation index.
-// [replacedMatchers]: set of replaced matcher ids. conditions using these matchers must be replaced
+// [metricToActivationMap]: map from metric id to metric activation index
+// [replacedMatchers]: set of replaced matcher ids. metrics using these matchers must be replaced
+// [replacedConditions]: set of replaced conditions. metrics using these conditions must be replaced
+// [replacedStates]: set of replaced state ids. metrics using these states must be replaced
// output:
-// [updateStatus]: update status for the metric. Will be changed from UPDATE_UNKNOWN after this call
+// [metricsToUpdate]: update status of each metric. Will be changed from UPDATE_UNKNOWN
// Returns whether the function was successful or not.
-bool determineEventMetricUpdateStatus(const StatsdConfig& config, const EventMetric& metric,
+bool determineAllMetricUpdateStatuses(const StatsdConfig& config,
const unordered_map<int64_t, int>& oldMetricProducerMap,
const vector<sp<MetricProducer>>& oldMetricProducers,
const unordered_map<int64_t, int>& metricToActivationMap,
const set<int64_t>& replacedMatchers,
const set<int64_t>& replacedConditions,
- UpdateStatus& updateStatus);
+ const set<int64_t>& replacedStates,
+ vector<UpdateStatus>& metricsToUpdate);
// Update MetricProducers.
// input:
diff --git a/bin/tests/metrics/parsing_utils/config_update_utils_test.cpp b/bin/tests/metrics/parsing_utils/config_update_utils_test.cpp
index 5d0f6c4..b2b0879 100644
--- a/bin/tests/metrics/parsing_utils/config_update_utils_test.cpp
+++ b/bin/tests/metrics/parsing_utils/config_update_utils_test.cpp
@@ -920,14 +920,13 @@
// Create an initial config.
EXPECT_TRUE(initConfig(config));
- set<int64_t> replacedMatchers;
- set<int64_t> replacedConditions;
unordered_map<int64_t, int> metricToActivationMap;
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_PRESERVE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
+ metricToActivationMap,
+ /*replacedMatchers*/ {}, /*replacedConditions=*/{},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}
TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
@@ -957,14 +956,13 @@
eventActivation->set_atom_matcher_id(startMatcher.id());
eventActivation->set_ttl_seconds(5);
- set<int64_t> replacedMatchers;
- set<int64_t> replacedConditions;
unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_REPLACE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
+ metricToActivationMap,
+ /*replacedMatchers*/ {}, /*replacedConditions=*/{},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}
TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
@@ -987,14 +985,13 @@
// Create an initial config.
EXPECT_TRUE(initConfig(config));
- set<int64_t> replacedMatchers = {whatMatcher.id()};
- set<int64_t> replacedConditions;
unordered_map<int64_t, int> metricToActivationMap;
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_REPLACE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(
+ config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
+ /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}
TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
@@ -1017,14 +1014,13 @@
// Create an initial config.
EXPECT_TRUE(initConfig(config));
- set<int64_t> replacedMatchers;
- set<int64_t> replacedConditions = {predicate.id()};
unordered_map<int64_t, int> metricToActivationMap;
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_REPLACE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(
+ config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
+ /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}
TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
@@ -1054,14 +1050,13 @@
// Create an initial config.
EXPECT_TRUE(initConfig(config));
- set<int64_t> replacedMatchers;
- set<int64_t> replacedConditions = {linkPredicate.id()};
unordered_map<int64_t, int> metricToActivationMap;
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_REPLACE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(
+ config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
+ /*replacedMatchers*/ {}, /*replacedConditions=*/{linkPredicate.id()},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}
TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
@@ -1090,14 +1085,13 @@
// Create an initial config.
EXPECT_TRUE(initConfig(config));
- set<int64_t> replacedMatchers = {startMatcher.id()}; // The activation matcher is replaced.
- set<int64_t> replacedConditions;
unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
- UpdateStatus status = UPDATE_UNKNOWN;
- EXPECT_TRUE(determineEventMetricUpdateStatus(config, *metric, oldMetricProducerMap,
- oldMetricProducers, metricToActivationMap,
- replacedMatchers, replacedConditions, status));
- EXPECT_EQ(status, UPDATE_REPLACE);
+ vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
+ EXPECT_TRUE(determineAllMetricUpdateStatuses(
+ config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
+ /*replacedMatchers*/ {startMatcher.id()}, /*replacedConditions=*/{},
+ /*replacedStates=*/{}, metricsToUpdate));
+ EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}
TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) {