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

Commit 90f95bb3 authored by tsaichristine's avatar tsaichristine
Browse files

Refactor ValueMetricProducer

Major changes are unnesting conditional statements in
onConditionChangedLocked.

Test: bit statsd_test:*
&& atest ValueMetricsTests

Change-Id: Ie6882f008ad393e4081443acfab9ea85404b6ca9
parent e63c1594
Loading
Loading
Loading
Loading
+76 −69
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ ValueMetricProducer::ValueMetricProducer(
    if (metric.has_dimensions_in_what()) {
        translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
        mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
        mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
    }

    if (metric.links().size() > 0) {
@@ -142,8 +143,6 @@ ValueMetricProducer::ValueMetricProducer(
        mConditionSliced = true;
    }

    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());

    int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs);
    mCurrentBucketNum += numBucketsForward;

@@ -366,7 +365,7 @@ void ValueMetricProducer::resetBase() {
// - ConditionTimer tracks changes based on AND of condition and active state.
void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
    if (ConditionState::kTrue == mCondition && isEventTooLate) {
    if (isEventTooLate) {
        // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
        invalidateCurrentBucket();
    }
@@ -401,54 +400,62 @@ void ValueMetricProducer::onConditionChangedLocked(const bool condition,
    ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;

    if (mIsActive) {
    // If the config is not active, skip the event.
    if (!mIsActive) {
        mCondition = isEventTooLate ? ConditionState::kUnknown : newCondition;
        return;
    }

    // If the event arrived late, mark the bucket as invalid and skip the event.
    if (isEventTooLate) {
        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
             (long long)mCurrentBucketStartTimeNs);
        StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
        invalidateCurrentBucket();
        } else {
            if (mCondition == ConditionState::kUnknown) {
                // If the condition was unknown, we mark the bucket as invalid since the bucket will
                // contain partial data. For instance, the condition change might happen close to
                // the end of the bucket and we might miss lots of data.
        mCondition = ConditionState::kUnknown;
        mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
        return;
    }

    // If the previous condition was unknown, mark the bucket as invalid
    // because the bucket will contain partial data. For example, the condition
    // change might happen close to the end of the bucket and we might miss a
    // lot of data.
    //
    // We still want to pull to set the base.
    if (mCondition == ConditionState::kUnknown) {
        invalidateCurrentBucket();
    }

            // Pull on condition changes.
            bool conditionChanged =
                    (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)
                    || (mCondition == ConditionState::kFalse &&
                            newCondition == ConditionState::kTrue);
            // We do not need to pull when we go from unknown to false.
    // Pull and match for the following condition change cases:
    // unknown/false -> true - condition changed
    // true -> false - condition changed
    // true -> true - old condition was true so we can flush the bucket at the
    // end if needed.
    //
            // We also pull if the condition was already true in order to be able to flush the
            // bucket at the end if needed.
    // We don’t need to pull for unknown -> false or false -> false.
    //
            // onConditionChangedLocked might happen on bucket boundaries if this is called before
            // #onDataPulled.
            if (mIsPulled && (conditionChanged || condition)) {
    // onConditionChangedLocked might happen on bucket boundaries if this is
    // called before #onDataPulled.
    if (mIsPulled &&
        (newCondition == ConditionState::kTrue || mCondition == ConditionState::kTrue)) {
        pullAndMatchEventsLocked(eventTimeNs, newCondition);
    }

            // When condition change from true to false, clear diff base but don't
            // reset other counters as we may accumulate more value in the bucket.
            if (mUseDiff && mCondition == ConditionState::kTrue
                    && newCondition == ConditionState::kFalse) {
    // For metrics that use diff, when condition changes from true to false,
    // clear diff base but don't reset other counts because we may accumulate
    // more value in the bucket.
    if (mUseDiff &&
        (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)) {
        resetBase();
    }
        }
    }

    mCondition = isEventTooLate ? initialCondition(mConditionTrackerIndex) : newCondition;
    // Update condition state after pulling.
    mCondition = newCondition;

    if (mIsActive) {
    flushIfNeededLocked(eventTimeNs);
    mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
}
}

void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs,
        ConditionState condition) {
@@ -821,7 +828,7 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(const size_t matcherIn
void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
    int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
    if (eventTimeNs < currentBucketEndTimeNs) {
        VLOG("eventTime is %lld, less than next bucket start time %lld", (long long)eventTimeNs,
        VLOG("eventTime is %lld, less than current bucket end time %lld", (long long)eventTimeNs,
             (long long)(currentBucketEndTimeNs));
        return;
    }