Loading cmds/statsd/src/metrics/ValueMetricProducer.cpp +76 −69 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -142,8 +143,6 @@ ValueMetricProducer::ValueMetricProducer( mConditionSliced = true; } mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs); mCurrentBucketNum += numBucketsForward; Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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; } Loading Loading
cmds/statsd/src/metrics/ValueMetricProducer.cpp +76 −69 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -142,8 +143,6 @@ ValueMetricProducer::ValueMetricProducer( mConditionSliced = true; } mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()); int64_t numBucketsForward = calcBucketsForwardCount(startTimeNs); mCurrentBucketNum += numBucketsForward; Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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; } Loading