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

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

Merge "Perform partial update for count metric"

parents 1b3ce3d0 ef6cd7f5
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <stdlib.h>

#include "guardrail/StatsdStats.h"
#include "metrics/parsing_utils/metrics_manager_util.h"
#include "stats_log_util.h"
#include "stats_util.h"

@@ -122,6 +123,47 @@ CountMetricProducer::~CountMetricProducer() {
    VLOG("~CountMetricProducer() called");
}

bool CountMetricProducer::onConfigUpdatedLocked(
        const StatsdConfig& config, const int configIndex, const int metricIndex,
        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
        const sp<EventMatcherWizard>& matcherWizard,
        const vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
        const unordered_map<int64_t, int>& metricToActivationMap,
        unordered_map<int, vector<int>>& trackerToMetricMap,
        unordered_map<int, vector<int>>& conditionToMetricMap,
        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
        vector<int>& metricsWithActivation) {
    if (!MetricProducer::onConfigUpdatedLocked(
                config, configIndex, metricIndex, allAtomMatchingTrackers,
                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
        return false;
    }

    const CountMetric& metric = config.count_metric(configIndex);
    int trackerIndex;
    // Update appropriate indices, specifically mConditionIndex and MetricsManager maps.
    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                              trackerToMetricMap, trackerIndex)) {
        return false;
    }

    if (metric.has_condition() &&
        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
                                    conditionToMetricMap)) {
        return false;
    }
    return true;
}

void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
                                         const HashableDimensionKey& primaryKey,
                                         const FieldValue& oldState, const FieldValue& newState) {
+16 −0
Original line number Diff line number Diff line
@@ -97,6 +97,22 @@ private:
    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
                                  const int64_t& nextBucketStartTimeNs) override;

    bool onConfigUpdatedLocked(
            const StatsdConfig& config, const int configIndex, const int metricIndex,
            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
            const sp<EventMatcherWizard>& matcherWizard,
            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
            const std::unordered_map<int64_t, int>& conditionTrackerMap,
            const sp<ConditionWizard>& wizard,
            const std::unordered_map<int64_t, int>& metricToActivationMap,
            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
            std::vector<int>& metricsWithActivation) override;

    std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;

    // The current bucket (may be a partial bucket).
+2 −0
Original line number Diff line number Diff line
@@ -566,7 +566,9 @@ protected:
    FRIEND_TEST(MetricsManagerTest, TestInitialConditions);

    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricActivations);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateCountMetrics);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateEventMetrics);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricsMultipleTypes);
};

}  // namespace statsd
+45 −0
Original line number Diff line number Diff line
@@ -587,6 +587,51 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64

    // Now, perform the update. Must iterate the metric types in the same order
    int metricIndex = 0;
    for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
        newMetricProducerMap[config.count_metric(i).id()] = metricIndex;
        const CountMetric& metric = config.count_metric(i);
        switch (metricsToUpdate[metricIndex]) {
            case UPDATE_PRESERVE: {
                const auto& oldMetricProducerIt = oldMetricProducerMap.find(metric.id());
                if (oldMetricProducerIt == oldMetricProducerMap.end()) {
                    ALOGE("Could not find Metric %lld in the previous config, but expected it "
                          "to be there",
                          (long long)metric.id());
                    return false;
                }
                const int oldIndex = oldMetricProducerIt->second;
                sp<MetricProducer> producer = oldMetricProducers[oldIndex];
                producer->onConfigUpdated(
                        config, i, metricIndex, allAtomMatchingTrackers, oldAtomMatchingTrackerMap,
                        newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers,
                        conditionTrackerMap, wizard, metricToActivationMap, trackerToMetricMap,
                        conditionToMetricMap, activationAtomTrackerToMetricMap,
                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
                newMetricProducers.push_back(producer);
                break;
            }
            case UPDATE_REPLACE:
            case UPDATE_NEW: {
                sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata(
                        key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
                        conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                        allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
                        conditionToMetricMap, activationAtomTrackerToMetricMap,
                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
                if (producer == nullptr) {
                    return false;
                }
                newMetricProducers.push_back(producer);
                break;
            }
            default: {
                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
                      (long long)metric.id());
                return false;
            }
        }
    }
    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);
+84 −57
Original line number Diff line number Diff line
@@ -348,6 +348,81 @@ bool handleMetricActivationOnConfigUpdate(
    return true;
}

sp<MetricProducer> createCountMetricProducerAndUpdateMetadata(
        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
        const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
        vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& conditionTrackerMap,
        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
        const unordered_map<int64_t, int>& stateAtomIdMap,
        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
        const unordered_map<int64_t, int>& metricToActivationMap,
        unordered_map<int, vector<int>>& trackerToMetricMap,
        unordered_map<int, vector<int>>& conditionToMetricMap,
        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
        vector<int>& metricsWithActivation) {
    if (!metric.has_id() || !metric.has_what()) {
        ALOGW("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
        return nullptr;
    }
    int trackerIndex;
    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
                                              metric.has_dimensions_in_what(),
                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
                                              trackerToMetricMap, trackerIndex)) {
        return nullptr;
    }

    int conditionIndex = -1;
    if (metric.has_condition()) {
        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                        metric.links(), allConditionTrackers, conditionIndex,
                                        conditionToMetricMap)) {
            return nullptr;
        }
    } else {
        if (metric.links_size() > 0) {
            ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
            return nullptr;
        }
    }

    std::vector<int> slicedStateAtoms;
    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
    if (metric.slice_by_state_size() > 0) {
        if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
                                    allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
            return nullptr;
        }
    } else {
        if (metric.state_link_size() > 0) {
            ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
            return nullptr;
        }
    }

    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
                                atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
                                deactivationAtomTrackerToMetricMap, metricsWithActivation,
                                eventActivationMap, eventDeactivationMap)) {
        return nullptr;
    }

    uint64_t metricHash;
    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
        return nullptr;
    }

    return new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
                                   metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
                                   eventDeactivationMap, slicedStateAtoms, stateGroupMap);
}

sp<MetricProducer> createEventMetricProducerAndUpdateMetadata(
        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
        const EventMetric& metric, const int metricIndex,
@@ -550,68 +625,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
    // Build MetricProducers for each metric defined in config.
    // build CountMetricProducer
    for (int i = 0; i < config.count_metric_size(); i++) {
        const CountMetric& metric = config.count_metric(i);
        if (!metric.has_what()) {
            ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
            return false;
        }

        int metricIndex = allMetricProducers.size();
        const CountMetric& metric = config.count_metric(i);
        metricMap.insert({metric.id(), metricIndex});
        int trackerIndex;
        if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
                                                  metric.has_dimensions_in_what(),
                                                  allAtomMatchingTrackers, atomMatchingTrackerMap,
                                                  trackerToMetricMap, trackerIndex)) {
            return false;
        }

        int conditionIndex = -1;
        if (metric.has_condition()) {
            if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                            metric.links(), allConditionTrackers, conditionIndex,
                                            conditionToMetricMap)) {
                return false;
            }
        } else {
            if (metric.links_size() > 0) {
                ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
                return false;
            }
        }

        std::vector<int> slicedStateAtoms;
        unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
        if (metric.slice_by_state_size() > 0) {
            if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
                return false;
            }
        } else {
            if (metric.state_link_size() > 0) {
                ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
                return false;
            }
        }

        unordered_map<int, shared_ptr<Activation>> eventActivationMap;
        unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
        bool success = handleMetricActivation(
                config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
        sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata(
                key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
                conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
                metricsWithActivation, eventActivationMap, eventDeactivationMap);
        if (!success) return false;

        uint64_t metricHash;
        if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
                metricsWithActivation);
        if (producer == nullptr) {
            return false;
        }

        sp<MetricProducer> countProducer = new CountMetricProducer(
                key, metric, conditionIndex, initialConditionCache, wizard, metricHash,
                timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
                slicedStateAtoms, stateGroupMap);
        allMetricProducers.push_back(countProducer);
        allMetricProducers.push_back(producer);
    }

    // build DurationMetricProducer
Loading