Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 496f5347 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor determine metric update status"

parents d1c01628 13264fbb
Loading
Loading
Loading
Loading
+73 −33
Original line number Diff line number Diff line
@@ -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 @@ bool metricActivationDepsChange(const StatsdConfig& config,
    return false;
}

bool determineEventMetricUpdateStatus(const StatsdConfig& config, const EventMetric& metric,
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,
                                      UpdateStatus& updateStatus) {
    int64_t id = metric.id();
        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 @@ bool determineEventMetricUpdateStatus(const StatsdConfig& config, const EventMet

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

    if (metric.has_condition()) {
        if (replacedConditions.find(metric.condition()) != replacedConditions.end()) {
    set_intersection(conditionDependencies.begin(), conditionDependencies.end(),
                     replacedConditions.begin(), replacedConditions.end(),
                     inserter(intersection, intersection.begin()));
    if (intersection.size() > 0) {
        updateStatus = UPDATE_REPLACE;
        return true;
    }
    }

    if (metricActivationDepsChange(config, metricToActivationMap, id, replacedMatchers)) {
    set_intersection(stateDependencies.begin(), stateDependencies.end(), replacedStates.begin(),
                     replacedStates.end(), inserter(intersection, intersection.begin()));
    if (intersection.size() > 0) {
        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 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64
    }

    vector<UpdateStatus> metricsToUpdate(allMetricsCount, UPDATE_UNKNOWN);
    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])) {
    if (!determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                          metricToActivationMap, replacedMatchers,
                                          replacedConditions, replacedStates, metricsToUpdate)) {
        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;
    int metricIndex = 0;
    for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
        newMetricProducerMap[config.event_metric(i).id()] = metricIndex;
        const EventMetric& metric = config.event_metric(i);
        switch (metricsToUpdate[metricIndex]) {
            case UPDATE_PRESERVE: {
+9 −7
Original line number Diff line number Diff line
@@ -125,23 +125,25 @@ bool updateConditions(const ConfigKey& key, const StatsdConfig& config,
                      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:
+36 −42
Original line number Diff line number Diff line
@@ -920,14 +920,13 @@ TEST_F(ConfigUpdateTest, TestEventMetricPreserve) {
    // 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 @@ TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
    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 @@ TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
    // 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 @@ TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
    // 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 @@ TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
    // 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 @@ TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
    // 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) {