1729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen/*
2729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Copyright (C) 2017 The Android Open Source Project
3729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen *
4729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Licensed under the Apache License, Version 2.0 (the "License");
5729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * you may not use this file except in compliance with the License.
6729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * You may obtain a copy of the License at
7729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen *
8729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen *      http://www.apache.org/licenses/LICENSE-2.0
9729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen *
10729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * Unless required by applicable law or agreed to in writing, software
11729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * distributed under the License is distributed on an "AS IS" BASIS,
12729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * See the License for the specific language governing permissions and
14729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen * limitations under the License.
15729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen */
16729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
173c0b95ceb520c6b23871da90c23f89c55b76b560Yao Chen#define DEBUG false
185154a379303ab90a2b2914676a4441917a329b5dYao Chen
19729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "Log.h"
205154a379303ab90a2b2914676a4441917a329b5dYao Chen#include "DurationMetricProducer.h"
21b356151e63140085cb96fa16804ee18b3862a4fcYao Chen#include "guardrail/StatsdStats.h"
22729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include "stats_util.h"
232087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac#include "stats_log_util.h"
24729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
25729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <limits.h>
26729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen#include <stdlib.h>
27729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
28b0378b093d9b937fe9a731a601d670d50f263078yrousing android::util::FIELD_COUNT_REPEATED;
292b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_BOOL;
302b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_FLOAT;
312b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT32;
322b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_INT64;
332b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::FIELD_TYPE_MESSAGE;
34d1815dc7b82f99259f6c41cfacc44972b867ef2dYangster-macusing android::util::FIELD_TYPE_STRING;
352b0f88678b2877a8e9f83cea60f097322b078367yrousing android::util::ProtoOutputStream;
36729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::string;
37729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::unordered_map;
38729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chenusing std::vector;
39729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
40729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace android {
41729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace os {
42729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chennamespace statsd {
43729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
442b0f88678b2877a8e9f83cea60f097322b078367yro// for StatsLogReport
4594e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-macconst int FIELD_ID_ID = 1;
462b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION_METRICS = 6;
479def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_TIME_BASE = 9;
489def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_BUCKET_SIZE = 10;
499def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_DIMENSION_PATH_IN_WHAT = 11;
509def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_DIMENSION_PATH_IN_CONDITION = 12;
512b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricDataWrapper
522b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DATA = 1;
532b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationMetricData
54468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_DIMENSION_IN_WHAT = 1;
55468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_DIMENSION_IN_CONDITION = 2;
56468ff04fd4cb43a384a3d4948cccd4438be7202aYangster-macconst int FIELD_ID_BUCKET_INFO = 3;
579def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
589def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_DIMENSION_LEAF_IN_CONDITION = 5;
592b0f88678b2877a8e9f83cea60f097322b078367yro// for DurationBucketInfo
602b0f88678b2877a8e9f83cea60f097322b078367yroconst int FIELD_ID_DURATION = 3;
619def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_BUCKET_NUM = 4;
629def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
639def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macconst int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
642b0f88678b2877a8e9f83cea60f097322b078367yro
65b356151e63140085cb96fa16804ee18b3862a4fcYao ChenDurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const DurationMetric& metric,
66729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                                               const int conditionIndex, const size_t startIndex,
67729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen                                               const size_t stopIndex, const size_t stopAllIndex,
680ea19901ef78de19437c08bbcbb7af6663ad6f4bYao Chen                                               const bool nesting,
695154a379303ab90a2b2914676a4441917a329b5dYao Chen                                               const sp<ConditionWizard>& wizard,
702087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac                                               const FieldMatcher& internalDimensions,
71b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                                               const int64_t startTimeNs)
7294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
73f09569f848ca0b81a21a74e9f4dd8bd9a886151aYao Chen      mAggregationType(metric.aggregation_type()),
74729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen      mStartIndex(startIndex),
75729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen      mStopIndex(stopIndex),
765154a379303ab90a2b2914676a4441917a329b5dYao Chen      mStopAllIndex(stopAllIndex),
7713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster      mNested(nesting),
7813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster      mContainANYPositionInInternalDimensions(false) {
79729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract
80729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // them in the base class, because the proto generated CountMetric, and DurationMetric are
81729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // not related. Maybe we should add a template in the future??
82b814481ad1f8d0e429d799b1571a6272e1a7f6c5Yangster-mac    if (metric.has_bucket()) {
8359cc24dbfda4148c1f5ef4de9c8763caa8672443yro        mBucketSizeNs =
8459cc24dbfda4148c1f5ef4de9c8763caa8672443yro                TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
85729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    } else {
86729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        mBucketSizeNs = LLONG_MAX;
87729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
88729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    if (metric.has_dimensions_in_what()) {
908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
9113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    if (internalDimensions.has_field()) {
958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        translateFieldMatcher(internalDimensions, &mInternalDimensions);
9613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mContainANYPositionInInternalDimensions = HasPositionANY(internalDimensions);
978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
98e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    if (mContainANYPositionInInternalDimensions) {
99e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        ALOGE("Position ANY in internal dimension not supported.");
100e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    }
101e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    if (mContainANYPositionInDimensionsInWhat) {
102e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        ALOGE("Position ANY in dimension_in_what not supported.");
103e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    }
1048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    if (metric.has_dimensions_in_condition()) {
1068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        translateFieldMatcher(metric.dimensions_in_condition(), &mDimensionsInCondition);
1078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
108729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
1099def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
1109def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            HasPositionALL(metric.dimensions_in_condition());
1119def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac
112729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    if (metric.links().size() > 0) {
1138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        for (const auto& link : metric.links()) {
1148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            Metric2Condition mc;
1158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            mc.conditionId = link.condition();
1168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            translateFieldMatcher(link.fields_in_what(), &mc.metricFields);
1178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            translateFieldMatcher(link.fields_in_condition(), &mc.conditionFields);
1188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            mMetric2ConditionLinks.push_back(mc);
1198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
120729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
1218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
12213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    mUnSlicedPartCondition = ConditionState::kUnknown;
12313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
12413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    mUseWhatDimensionAsInternalDimension = equalDimensions(mDimensionsInWhat, mInternalDimensions);
12513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (mWizard != nullptr && mConditionTrackerIndex >= 0) {
12613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mSameConditionDimensionsInTracker =
12713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            mWizard->equalOutputDimensions(mConditionTrackerIndex, mDimensionsInCondition);
12813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (mMetric2ConditionLinks.size() == 1) {
12913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            mHasLinksToAllConditionDimensionsInTracker =
13013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                mWizard->equalOutputDimensions(mConditionTrackerIndex,
13113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                               mMetric2ConditionLinks.begin()->conditionFields);
132539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
133539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
13494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
13515f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac         (long long)mBucketSizeNs, (long long)mTimeBaseNs);
136729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
137729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
138729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao ChenDurationMetricProducer::~DurationMetricProducer() {
139729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    VLOG("~DurationMetric() called");
140729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
141729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
142932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-macsp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
143932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
144857aaa520804d846a050e1eeb85d82977c983666Bookatz    std::lock_guard<std::mutex> lock(mMutex);
145423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz    if (mAggregationType == DurationMetric_AggregationType_SUM) {
146423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz        if (alert.trigger_if_sum_gt() > alert.num_buckets() * mBucketSizeNs) {
147423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz            ALOGW("invalid alert for SUM: threshold (%f) > possible recordable value (%d x %lld)",
148423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz                  alert.trigger_if_sum_gt(), alert.num_buckets(), (long long)mBucketSizeNs);
149423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz            return nullptr;
150423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz        }
151423f753ea3c304805d278e0ccbcbf2ef5da311e9Bookatz    }
152932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac    sp<DurationAnomalyTracker> anomalyTracker =
153932ececa1674c59a8da9f3e32d2651e781b86fc4Yangster-mac        new DurationAnomalyTracker(alert, mConfigKey, anomalyAlarmMonitor);
154857aaa520804d846a050e1eeb85d82977c983666Bookatz    if (anomalyTracker != nullptr) {
155857aaa520804d846a050e1eeb85d82977c983666Bookatz        mAnomalyTrackers.push_back(anomalyTracker);
156857aaa520804d846a050e1eeb85d82977c983666Bookatz    }
157857aaa520804d846a050e1eeb85d82977c983666Bookatz    return anomalyTracker;
158450099db169d386077584d93486908c3bae1244eBookatz}
159450099db169d386077584d93486908c3bae1244eBookatz
1605154a379303ab90a2b2914676a4441917a329b5dYao Chenunique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
1619369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac        const MetricDimensionKey& eventKey) const {
162f09569f848ca0b81a21a74e9f4dd8bd9a886151aYao Chen    switch (mAggregationType) {
163cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon        case DurationMetric_AggregationType_SUM:
164b356151e63140085cb96fa16804ee18b3862a4fcYao Chen            return make_unique<OringDurationTracker>(
1659369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac                    mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex,
16627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                    mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
16715f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac                    mTimeBaseNs, mBucketSizeNs, mConditionSliced,
16813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
169cfed20bce8a66bde6ad0d74a44fc0a2764b2886dStefan Lafon        case DurationMetric_AggregationType_MAX_SPARSE:
170b356151e63140085cb96fa16804ee18b3862a4fcYao Chen            return make_unique<MaxDurationTracker>(
1719369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac                    mConfigKey, mMetricId, eventKey, mWizard, mConditionTrackerIndex,
17227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen                    mDimensionsInCondition, mNested, mCurrentBucketStartTimeNs, mCurrentBucketNum,
17315f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac                    mTimeBaseNs, mBucketSizeNs, mConditionSliced,
17413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    mHasLinksToAllConditionDimensionsInTracker, mAnomalyTrackers);
17513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
17613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster}
17713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
17813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// SlicedConditionChange optimization case 1:
17913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// 1. If combination condition, logical operation is AND, only one sliced child predicate.
18013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// 2. No condition in dimension
18113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// 3. The links covers all dimension fields in the sliced child condition predicate.
182427d372552490a2c5ac4041fe345b15f69451f57Yao Chenvoid DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
183b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                                                                   const int64_t eventTime) {
18413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (mMetric2ConditionLinks.size() != 1 ||
18513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        !mHasLinksToAllConditionDimensionsInTracker ||
18613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        !mDimensionsInCondition.empty()) {
18713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
18813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
18913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
19013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    bool  currentUnSlicedPartCondition = true;
19113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
19213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        ConditionState unslicedPartState =
19313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
19413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // When the unsliced part is still false, return directly.
19513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (mUnSlicedPartCondition == ConditionState::kFalse &&
19613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            unslicedPartState == ConditionState::kFalse) {
19713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            return;
19813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
19913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mUnSlicedPartCondition = unslicedPartState;
20013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
20113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
20213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
20313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
20413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
20513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
20613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    // The condition change is from the unsliced predicates.
20713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    // We need to find out the true dimensions from the sliced predicate and flip their condition
20813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    // state based on the new unsliced condition state.
20913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
21013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
21113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        std::set<HashableDimensionKey> trueConditionDimensions;
21213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &trueConditionDimensions);
21313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
21413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            HashableDimensionKey linkedConditionDimensionKey;
21513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            getDimensionForCondition(whatIt.first.getValues(),
21613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                     mMetric2ConditionLinks[0],
21713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                     &linkedConditionDimensionKey);
21813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            if (trueConditionDimensions.find(linkedConditionDimensionKey) !=
21913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    trueConditionDimensions.end()) {
22013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                for (auto& condIt : whatIt.second) {
22113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    condIt.second->onConditionChanged(
22213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        currentUnSlicedPartCondition, eventTime);
22313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
22413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
22513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
22613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    } else {
22713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // Handle the condition change from the sliced predicate.
22813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (currentUnSlicedPartCondition) {
22913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
23013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                HashableDimensionKey linkedConditionDimensionKey;
23113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                getDimensionForCondition(whatIt.first.getValues(),
23213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                         mMetric2ConditionLinks[0],
23313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                         &linkedConditionDimensionKey);
23413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                if (dimensionsChangedToTrue->find(linkedConditionDimensionKey) !=
23513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        dimensionsChangedToTrue->end()) {
23613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    for (auto& condIt : whatIt.second) {
23713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        condIt.second->onConditionChanged(true, eventTime);
23813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    }
23913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
24013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                if (dimensionsChangedToFalse->find(linkedConditionDimensionKey) !=
24113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        dimensionsChangedToFalse->end()) {
24213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    for (auto& condIt : whatIt.second) {
24313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        condIt.second->onConditionChanged(false, eventTime);
24413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    }
24513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
24613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
24713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
24813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
24913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster}
25013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
25113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
25213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// SlicedConditionChange optimization case 2:
25313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// 1. If combination condition, logical operation is AND, only one sliced child predicate.
25413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster// 2. Has dimensions_in_condition and it equals to the output dimensions of the sliced predicate.
255427d372552490a2c5ac4041fe345b15f69451f57Yao Chenvoid DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool condition,
256b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                                                                   const int64_t eventTime) {
25713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) {
25813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
25913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
26013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
26113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    auto dimensionsChangedToTrue = mWizard->getChangedToTrueDimensions(mConditionTrackerIndex);
26213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    auto dimensionsChangedToFalse = mWizard->getChangedToFalseDimensions(mConditionTrackerIndex);
26313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
26413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    bool  currentUnSlicedPartCondition = true;
26513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (!mWizard->IsSimpleCondition(mConditionTrackerIndex)) {
26613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        ConditionState unslicedPartState =
26713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            mWizard->getUnSlicedPartConditionState(mConditionTrackerIndex);
26813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // When the unsliced part is still false, return directly.
26913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (mUnSlicedPartCondition == ConditionState::kFalse &&
27013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            unslicedPartState == ConditionState::kFalse) {
27113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            return;
27213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
27313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mUnSlicedPartCondition = unslicedPartState;
27413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        currentUnSlicedPartCondition = mUnSlicedPartCondition > 0;
27513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
27613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
27713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    const std::set<HashableDimensionKey>* trueDimensionsToProcess = nullptr;
27813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    const std::set<HashableDimensionKey>* falseDimensionsToProcess = nullptr;
27913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
28013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    std::set<HashableDimensionKey> currentTrueConditionDimensions;
28113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
28213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
28313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &currentTrueConditionDimensions);
28413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        trueDimensionsToProcess = &currentTrueConditionDimensions;
28513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    } else if (currentUnSlicedPartCondition) {
28613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // Handles the condition change from the sliced predicate. If the unsliced condition state
28713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // is not true, not need to do anything.
28813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        trueDimensionsToProcess = dimensionsChangedToTrue;
28913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        falseDimensionsToProcess = dimensionsChangedToFalse;
29013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
29113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
29213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (trueDimensionsToProcess == nullptr && falseDimensionsToProcess == nullptr) {
29313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
29413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
29513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
29613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
29713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (falseDimensionsToProcess != nullptr) {
29813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (const auto& changedDim : *falseDimensionsToProcess) {
29913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                auto condIt = whatIt.second.find(changedDim);
30013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                if (condIt != whatIt.second.end()) {
30113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    condIt->second->onConditionChanged(false, eventTime);
30213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
30313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
30413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
30513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (trueDimensionsToProcess != nullptr) {
30613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            HashableDimensionKey linkedConditionDimensionKey;
30713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            if (!trueDimensionsToProcess->empty() && mMetric2ConditionLinks.size() == 1) {
30813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                getDimensionForCondition(whatIt.first.getValues(),
30913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                         mMetric2ConditionLinks[0],
31013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                         &linkedConditionDimensionKey);
31113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
31213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (auto& trueDim : *trueDimensionsToProcess) {
31313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                auto condIt = whatIt.second.find(trueDim);
31413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                if (condIt != whatIt.second.end()) {
31513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    condIt->second->onConditionChanged(
31613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        currentUnSlicedPartCondition, eventTime);
31713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                } else {
31813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    if (mMetric2ConditionLinks.size() == 0 ||
31913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        trueDim.contains(linkedConditionDimensionKey)) {
32013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        if (!whatIt.second.empty()) {
321306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                            auto newEventKey = MetricDimensionKey(whatIt.first, trueDim);
322306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                            if (hitGuardRailLocked(newEventKey)) {
323306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                                continue;
324306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                            }
32513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                            unique_ptr<DurationTracker> newTracker =
32613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                whatIt.second.begin()->second->clone(eventTime);
32713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                            if (newTracker != nullptr) {
328306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                                newTracker->setEventKey(newEventKey);
32913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                newTracker->onConditionChanged(true, eventTime);
33013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                whatIt.second[trueDim] = std::move(newTracker);
33113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                            }
33213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        }
33313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    }
33413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
33513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
33613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
3375154a379303ab90a2b2914676a4441917a329b5dYao Chen    }
3385154a379303ab90a2b2914676a4441917a329b5dYao Chen}
3395154a379303ab90a2b2914676a4441917a329b5dYao Chen
340427d372552490a2c5ac4041fe345b15f69451f57Yao Chenvoid DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
341b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                                                              const int64_t eventTime) {
34294e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
343f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    flushIfNeededLocked(eventTime);
3449369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac
34513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (!mConditionSliced) {
34613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
34713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
34813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
34913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
35013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
35113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mDimensionsInCondition.empty()) {
352427d372552490a2c5ac4041fe345b15f69451f57Yao Chen        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTime);
35313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
35413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
35513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
35613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (changeDimTrackable && mSameConditionDimensionsInTracker &&
35713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        mMetric2ConditionLinks.size() <= 1) {
358427d372552490a2c5ac4041fe345b15f69451f57Yao Chen        onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTime);
35913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
36013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
36113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
362729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // Now for each of the on-going event, check if the condition has changed for them.
363539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
364539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (auto& pair : whatIt.second) {
365427d372552490a2c5ac4041fe345b15f69451f57Yao Chen            pair.second->onSlicedConditionMayChange(overallCondition, eventTime);
366539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
367729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
3689369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac
369539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    if (mDimensionsInCondition.empty()) {
370539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        return;
3719369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac    }
372539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
373539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    if (mMetric2ConditionLinks.empty()) {
374539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet;
375539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition,
37613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                                          !mSameConditionDimensionsInTracker,
377539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                                          &conditionDimensionsKeySet);
378539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
379539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            for (const auto& pair : whatIt.second) {
380539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                conditionDimensionsKeySet.erase(pair.first);
381539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
382539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
383539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (const auto& conditionDimension : conditionDimensionsKeySet) {
384539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
385539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                if (!whatIt.second.empty()) {
386306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
387306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    if (hitGuardRailLocked(newEventKey)) {
388306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                        continue;
389306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    }
390539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                    unique_ptr<DurationTracker> newTracker =
391539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                        whatIt.second.begin()->second->clone(eventTime);
39213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    if (newTracker != nullptr) {
393306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                        newTracker->setEventKey(MetricDimensionKey(newEventKey));
394427d372552490a2c5ac4041fe345b15f69451f57Yao Chen                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
39513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        whatIt.second[conditionDimension] = std::move(newTracker);
39613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    }
397539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                }
398539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
399539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
400539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    } else {
401539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
402539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            ConditionKey conditionKey;
403539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            for (const auto& link : mMetric2ConditionLinks) {
404539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                getDimensionForCondition(whatIt.first.getValues(), link,
405539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                                         &conditionKey[link.conditionId]);
406539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
407539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            std::unordered_set<HashableDimensionKey> conditionDimensionsKeys;
408539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
40913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                           !mSameConditionDimensionsInTracker,
41013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                           !mHasLinksToAllConditionDimensionsInTracker,
411539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                           &conditionDimensionsKeys);
412539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
413539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            for (const auto& conditionDimension : conditionDimensionsKeys) {
414539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                if (!whatIt.second.empty() &&
415539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                    whatIt.second.find(conditionDimension) == whatIt.second.end()) {
416306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    auto newEventKey = MetricDimensionKey(whatIt.first, conditionDimension);
417306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    if (hitGuardRailLocked(newEventKey)) {
418306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                        continue;
419306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    }
420539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                    auto newTracker = whatIt.second.begin()->second->clone(eventTime);
42113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    if (newTracker != nullptr) {
422306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                        newTracker->setEventKey(newEventKey);
423427d372552490a2c5ac4041fe345b15f69451f57Yao Chen                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
42413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        whatIt.second[conditionDimension] = std::move(newTracker);
42513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    }
426539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                }
4279369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac            }
4289369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac        }
4299369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac    }
430729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
431729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
432f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
433b142cc8add29c8c97f6134d35873d23db666027cYangster-mac                                                      const int64_t eventTime) {
43494e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
435729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    mCondition = conditionMet;
436f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangster    flushIfNeededLocked(eventTime);
437729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // TODO: need to populate the condition change time from the event which triggers the condition
438729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    // change, instead of using current time.
439539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
440539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (auto& pair : whatIt.second) {
441539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            pair.second->onConditionChanged(conditionMet, eventTime);
442539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
443729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
444729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
445729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
446b142cc8add29c8c97f6134d35873d23db666027cYangster-macvoid DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
44706dba5d79c096b02d3ba6fb73e64451ff12e388dYao Chen    flushIfNeededLocked(dropTimeNs);
44806dba5d79c096b02d3ba6fb73e64451ff12e388dYao Chen    mPastBuckets.clear();
44906dba5d79c096b02d3ba6fb73e64451ff12e388dYao Chen}
45006dba5d79c096b02d3ba6fb73e64451ff12e388dYao Chen
451a802d73da625ac72f6a0211aab017f365139112dYangster-macvoid DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
452a802d73da625ac72f6a0211aab017f365139112dYangster-mac    flushIfNeededLocked(dumpTimeNs);
453a802d73da625ac72f6a0211aab017f365139112dYangster-mac    mPastBuckets.clear();
454a802d73da625ac72f6a0211aab017f365139112dYangster-mac}
455a802d73da625ac72f6a0211aab017f365139112dYangster-mac
456b142cc8add29c8c97f6134d35873d23db666027cYangster-macvoid DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
457e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac                                                const bool include_current_partial_bucket,
4589def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                                std::set<string> *str_set,
459288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen                                                ProtoOutputStream* protoOutput) {
460e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac    if (include_current_partial_bucket) {
461e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac        flushLocked(dumpTimeNs);
462e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac    } else {
463e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac        flushIfNeededLocked(dumpTimeNs);
464e68f3a5811209eeab71976bc583c6075d9a5979aYangster-mac    }
465635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac    if (mPastBuckets.empty()) {
4668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        VLOG(" Duration metric, empty return");
467635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac        return;
468635b4b37210bd61b73aebf19298e38b8fb382e85Yangster-mac    }
469288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen
47094e197cceb2ba7df13ff8de04f60bfeec64015d9Yangster-mac    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)mMetricId);
4719def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
4729def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
4739def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac
4749def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    if (!mSliceByPositionALL) {
4759def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        if (!mDimensionsInWhat.empty()) {
4769def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            uint64_t dimenPathToken = protoOutput->start(
4779def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
4789def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
4799def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            protoOutput->end(dimenPathToken);
4809def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        }
4819def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        if (!mDimensionsInCondition.empty()) {
4829def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            uint64_t dimenPathToken = protoOutput->start(
4839def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
4849def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
4859def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            protoOutput->end(dimenPathToken);
4869def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        }
4879def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac    }
4889def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac
4895ee0787024cc446a21008ff5710dec19c6afc834Yi Jin    uint64_t protoToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DURATION_METRICS);
4906a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen
4918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    VLOG("Duration metric %lld dump report now...", (long long)mMetricId);
4926a8c799d901cbd166aa6463d7dea231bcf594a1eYao Chen
493729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    for (const auto& pair : mPastBuckets) {
4949369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac        const MetricDimensionKey& dimensionKey = pair.first;
49513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        VLOG("  dimension key %s", dimensionKey.toString().c_str());
4961ff4f4325882d812ded4f75ee6c2b6d352a85c9eYao Chen
4975ee0787024cc446a21008ff5710dec19c6afc834Yi Jin        uint64_t wrapperToken =
498288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen                protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
4992b0f88678b2877a8e9f83cea60f097322b078367yro
5002087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac        // First fill dimension.
5019def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        if (mSliceByPositionALL) {
5029def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            uint64_t dimensionToken = protoOutput->start(
5039def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                    FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
5049def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
5059def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            protoOutput->end(dimensionToken);
5069def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac
5079def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            if (dimensionKey.hasDimensionKeyInCondition()) {
5089def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                uint64_t dimensionInConditionToken = protoOutput->start(
5099def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                        FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
5109def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(),
5119def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                      str_set, protoOutput);
5129def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                protoOutput->end(dimensionInConditionToken);
5139def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            }
5149def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac        } else {
5159def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInWhat(),
5169def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                           FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
5179def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            if (dimensionKey.hasDimensionKeyInCondition()) {
5189def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInCondition(),
5199def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                               FIELD_ID_DIMENSION_LEAF_IN_CONDITION,
5209def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                               str_set, protoOutput);
5219def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            }
5229369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac        }
5232b0f88678b2877a8e9f83cea60f097322b078367yro        // Then fill bucket_info (DurationBucketInfo).
5242b0f88678b2877a8e9f83cea60f097322b078367yro        for (const auto& bucket : pair.second) {
5255ee0787024cc446a21008ff5710dec19c6afc834Yi Jin            uint64_t bucketInfoToken = protoOutput->start(
526288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_BUCKET_INFO);
5279def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            if (bucket.mBucketEndNs - bucket.mBucketStartNs != mBucketSizeNs) {
5289def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_START_BUCKET_ELAPSED_MILLIS,
5299def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                   (long long)NanoToMillis(bucket.mBucketStartNs));
5309def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_END_BUCKET_ELAPSED_MILLIS,
5319def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                   (long long)NanoToMillis(bucket.mBucketEndNs));
5329def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            } else {
5339def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
5349def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac                                   (long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
5359def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-mac            }
536288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen            protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DURATION, (long long)bucket.mDuration);
537288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen            protoOutput->end(bucketInfoToken);
5382b0f88678b2877a8e9f83cea60f097322b078367yro            VLOG("\t bucket [%lld - %lld] duration: %lld", (long long)bucket.mBucketStartNs,
5392b0f88678b2877a8e9f83cea60f097322b078367yro                 (long long)bucket.mBucketEndNs, (long long)bucket.mDuration);
5402b0f88678b2877a8e9f83cea60f097322b078367yro        }
5412b0f88678b2877a8e9f83cea60f097322b078367yro
542288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen        protoOutput->end(wrapperToken);
543729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
5442b0f88678b2877a8e9f83cea60f097322b078367yro
545288c60001330a5a924a47c0eebd6097ae3ee5d67Yao Chen    protoOutput->end(protoToken);
546f60e0bad5908c51c954ca8dc763c8efd394c56dcYao Chen    mPastBuckets.clear();
5472b0f88678b2877a8e9f83cea60f097322b078367yro}
548729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
549b142cc8add29c8c97f6134d35873d23db666027cYangster-macvoid DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
550b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
55127785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
55227785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    if (currentBucketEndTimeNs > eventTimeNs) {
553729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        return;
554729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
5555154a379303ab90a2b2914676a4441917a329b5dYao Chen    VLOG("flushing...........");
556539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
557539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
558539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
559539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            if (it->second->flushIfNeeded(eventTimeNs, &mPastBuckets)) {
56013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                VLOG("erase bucket for key %s %s",
56113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                     whatIt->first.toString().c_str(), it->first.toString().c_str());
562539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                it = whatIt->second.erase(it);
563539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            } else {
564539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                ++it;
565539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
566539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
567539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        if (whatIt->second.empty()) {
568539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
569d41c4220d06875cea2d19a7991c3227bd56ea611Yao Chen        } else {
570539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt++;
571729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen        }
572729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen    }
573729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
57427785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    int numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
57527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
576e2cd6d509b17894b95d14523ae3e7c4c7a9a74e3Yangster-mac    mCurrentBucketNum += numBucketsForward;
577729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}
578729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen
579b142cc8add29c8c97f6134d35873d23db666027cYangster-macvoid DurationMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
580539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
581539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt != mCurrentSlicedDurationTrackerMap.end();) {
582539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
583539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            if (it->second->flushCurrentBucket(eventTimeNs, &mPastBuckets)) {
58413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                VLOG("erase bucket for key %s %s", whatIt->first.toString().c_str(),
58513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                     it->first.toString().c_str());
586539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                it = whatIt->second.erase(it);
587539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            } else {
588539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                ++it;
589539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
590539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
591539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        if (whatIt->second.empty()) {
592539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt = mCurrentSlicedDurationTrackerMap.erase(whatIt);
59327785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen        } else {
594539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            whatIt++;
59527785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen        }
59627785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen    }
59727785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen}
59827785a8a4a684c831c18f7189a6fa1b98c3573e6David Chen
599884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chenvoid DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
6009369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac    if (mCurrentSlicedDurationTrackerMap.size() == 0) {
601884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen        return;
602884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    }
603884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen
604884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
6059369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac            (unsigned long)mCurrentSlicedDurationTrackerMap.size());
606884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    if (verbose) {
607539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        for (const auto& whatIt : mCurrentSlicedDurationTrackerMap) {
608539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            for (const auto& slice : whatIt.second) {
60913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                fprintf(out, "\t(what)%s\t(condition)%s\n", whatIt.first.toString().c_str(),
61013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        slice.first.toString().c_str());
611539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                slice.second->dumpStates(out, verbose);
612539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
613884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen        }
614884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen    }
615884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen}
616884c8c130fde0d02ada1316f7c27f0f55e7e48b9Yao Chen
6179369446f0b04945d6674550728ae81196d6fb5c2Yangster-macbool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
618306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac    auto whatIt = mCurrentSlicedDurationTrackerMap.find(newKey.getDimensionKeyInWhat());
619306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac    if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
620306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        auto condIt = whatIt->second.find(newKey.getDimensionKeyInCondition());
621306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        if (condIt != whatIt->second.end()) {
622306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            return false;
623306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        }
624306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        if (whatIt->second.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
625306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            size_t newTupleCount = whatIt->second.size() + 1;
626306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            StatsdStats::getInstance().noteMetricDimensionInConditionSize(
627306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    mConfigKey, mMetricId, newTupleCount);
628306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
629306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
630306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                ALOGE("DurationMetric %lld dropping data for condition dimension key %s",
631306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    (long long)mMetricId, newKey.getDimensionKeyInCondition().toString().c_str());
632306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                return true;
633306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            }
634306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        }
635306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac    } else {
636306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        // 1. Report the tuple count if the tuple count > soft limit
637306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac        if (mCurrentSlicedDurationTrackerMap.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
638306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            size_t newTupleCount = mCurrentSlicedDurationTrackerMap.size() + 1;
639306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            StatsdStats::getInstance().noteMetricDimensionSize(
640306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    mConfigKey, mMetricId, newTupleCount);
641306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
642306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
643306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                ALOGE("DurationMetric %lld dropping data for what dimension key %s",
644306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                    (long long)mMetricId, newKey.getDimensionKeyInWhat().toString().c_str());
645306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac                return true;
646306ccc2d6bbb396e53f1a250da32003989a24b42Yangster-mac            }
647b356151e63140085cb96fa16804ee18b3862a4fcYao Chen        }
648b356151e63140085cb96fa16804ee18b3862a4fcYao Chen    }
649b356151e63140085cb96fa16804ee18b3862a4fcYao Chen    return false;
650b356151e63140085cb96fa16804ee18b3862a4fcYao Chen}
651b356151e63140085cb96fa16804ee18b3862a4fcYao Chen
652539288806fe5ae3733ef7883eb8ec01cce293988Yangster-macvoid DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
653539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                                              const ConditionKey& conditionKeys,
654539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                                              bool condition, const LogEvent& event) {
655539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    const auto& whatKey = eventKey.getDimensionKeyInWhat();
656539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    const auto& condKey = eventKey.getDimensionKeyInCondition();
657539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
658539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
659539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
660539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        if (hitGuardRailLocked(eventKey)) {
661539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            return;
662539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
663539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey);
664539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    } else {
665539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        if (whatIt->second.find(condKey) == whatIt->second.end()) {
666539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            if (hitGuardRailLocked(eventKey)) {
667539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                return;
668539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            }
669539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac            mCurrentSlicedDurationTrackerMap[whatKey][condKey] = createDurationTracker(eventKey);
670539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        }
671539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
672539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
673539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    auto it = mCurrentSlicedDurationTrackerMap.find(whatKey)->second.find(condKey);
674539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    if (mUseWhatDimensionAsInternalDimension) {
675539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        it->second->noteStart(whatKey, condition,
676539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                              event.GetElapsedTimestampNs(), conditionKeys);
677539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        return;
678539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
679539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
68013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (mInternalDimensions.empty()) {
681539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
682539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac                              event.GetElapsedTimestampNs(), conditionKeys);
683539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    } else {
684e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        HashableDimensionKey dimensionKey = DEFAULT_DIMENSION_KEY;
685e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        filterValues(mInternalDimensions, event.getValues(), &dimensionKey);
686e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        it->second->noteStart(
687e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac            dimensionKey, condition, event.GetElapsedTimestampNs(), conditionKeys);
688539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
689539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
690539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac}
691539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
692f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstervoid DurationMetricProducer::onMatchedLogEventInternalLocked(
6939369446f0b04945d6674550728ae81196d6fb5c2Yangster-mac        const size_t matcherIndex, const MetricDimensionKey& eventKey,
6942087716f2bdca90c7c3034d556ac12911bd8018eYangster-mac        const ConditionKey& conditionKeys, bool condition,
695a7259abde4e89fd91404b14b4845113cd313d1ecChenjie Yu        const LogEvent& event) {
696539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    ALOGW("Not used in duration tracker.");
697539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac}
698539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
699e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-macvoid DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
700e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac                                                     const LogEvent& event) {
701b142cc8add29c8c97f6134d35873d23db666027cYangster-mac    int64_t eventTimeNs = event.GetElapsedTimestampNs();
70215f6bbc24f4d7a3d4481d90a18df33d402ddacbaYangster-mac    if (eventTimeNs < mTimeBaseNs) {
70313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
70413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
70513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
70613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    flushIfNeededLocked(event.GetElapsedTimestampNs());
70713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
70813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    // Handles Stopall events.
70913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (matcherIndex == mStopAllIndex) {
71013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
71113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (auto& pair : whatIt.second) {
71213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                pair.second->noteStopAll(event.GetElapsedTimestampNs());
71313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
71413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
71513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
71613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
71713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
71813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    HashableDimensionKey dimensionInWhat;
71913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (!mDimensionsInWhat.empty()) {
72013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
72113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    } else {
72213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster       dimensionInWhat = DEFAULT_DIMENSION_KEY;
72313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
72413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
72513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    // Handles Stop events.
72613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (matcherIndex == mStopIndex) {
72713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (mUseWhatDimensionAsInternalDimension) {
72813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
72913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
73013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                for (const auto& condIt : whatIt->second) {
73113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    condIt.second->noteStop(dimensionInWhat, event.GetElapsedTimestampNs(), false);
73213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                }
73313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
73413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            return;
73513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
73613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
73713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        HashableDimensionKey internalDimensionKey = DEFAULT_DIMENSION_KEY;
73813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (!mInternalDimensions.empty()) {
73913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            filterValues(mInternalDimensions, event.getValues(), &internalDimensionKey);
74013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
74113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
74213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
74313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
74413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (const auto& condIt : whatIt->second) {
74513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                condIt.second->noteStop(
74613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    internalDimensionKey, event.GetElapsedTimestampNs(), false);
74713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
74813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
74913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        return;
75013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
75113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
75213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    bool condition;
75313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    ConditionKey conditionKey;
75413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
75513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (mConditionSliced) {
75613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        for (const auto& link : mMetric2ConditionLinks) {
75713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
75813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
75913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
76013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        auto conditionState =
76113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            mWizard->query(mConditionTrackerIndex, conditionKey, mDimensionsInCondition,
76213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                           !mSameConditionDimensionsInTracker,
76313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                           !mHasLinksToAllConditionDimensionsInTracker,
76413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                           &dimensionKeysInCondition);
76513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        condition = (conditionState == ConditionState::kTrue);
76613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (mDimensionsInCondition.empty() && condition) {
76713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
76813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
76913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    } else {
77013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        condition = mCondition;
77113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (condition) {
77213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            dimensionKeysInCondition.insert(DEFAULT_DIMENSION_KEY);
77313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
77413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
77513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
77613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    if (dimensionKeysInCondition.empty()) {
77713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY),
77813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                         conditionKey, condition, event);
77913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    } else {
78013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
78113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // If the what dimension is already there, we should update all the trackers even
78213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        // the condition is false.
78313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
78413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            for (const auto& condIt : whatIt->second) {
78513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                const bool cond = dimensionKeysInCondition.find(condIt.first) !=
78613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                        dimensionKeysInCondition.end();
78713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                handleStartEvent(MetricDimensionKey(dimensionInWhat, condIt.first),
78813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                    conditionKey, cond, event);
78913fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                dimensionKeysInCondition.erase(condIt.first);
79013fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            }
79113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
79213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        for (const auto& conditionDimension : dimensionKeysInCondition) {
79313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster            handleStartEvent(MetricDimensionKey(dimensionInWhat, conditionDimension), conditionKey,
79413fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                             condition, event);
79513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster        }
79613fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster    }
79713fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster}
79813fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
799f2bee6fec965fd42ab223f1a3aa705f07ba79aeaYangstersize_t DurationMetricProducer::byteSizeLocked() const {
8007c334a129e93e405a72e8299a1cd928af079d14fYangster    size_t totalSize = 0;
8017c334a129e93e405a72e8299a1cd928af079d14fYangster    for (const auto& pair : mPastBuckets) {
8027c334a129e93e405a72e8299a1cd928af079d14fYangster        totalSize += pair.second.size() * kBucketSize;
8037c334a129e93e405a72e8299a1cd928af079d14fYangster    }
8047c334a129e93e405a72e8299a1cd928af079d14fYangster    return totalSize;
80569007c82625dd8b19bd68d1031191e2ff83b5f49yro}
80669007c82625dd8b19bd68d1031191e2ff83b5f49yro
807729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}  // namespace statsd
808729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}  // namespace os
809729093df0dd7d7038ad43b16ecdb59a1404f3b50Yao Chen}  // namespace android
810