blob: 87104a34c009ec88696dea790351b139c270accc [file] [log] [blame]
Yao Chencaf339d2017-10-06 16:01:10 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yao Chen5110bed2017-10-23 12:50:02 -070017#define DEBUG false // STOPSHIP if true
Joe Onorato9fc9edf2017-10-15 20:08:52 -070018#include "Log.h"
Yao Chencaf339d2017-10-06 16:01:10 -070019
20#include "SimpleConditionTracker.h"
Yao Chenb3561512017-11-21 18:07:17 -080021#include "guardrail/StatsdStats.h"
Joe Onorato9fc9edf2017-10-15 20:08:52 -070022
Joe Onorato9fc9edf2017-10-15 20:08:52 -070023namespace android {
24namespace os {
25namespace statsd {
26
Yao Chen729093d2017-10-16 10:33:26 -070027using std::map;
Yao Chencaf339d2017-10-06 16:01:10 -070028using std::string;
29using std::unique_ptr;
30using std::unordered_map;
31using std::vector;
32
Yao Chencaf339d2017-10-06 16:01:10 -070033SimpleConditionTracker::SimpleConditionTracker(
Yangster-mac94e197c2018-01-02 16:03:03 -080034 const ConfigKey& key, const int64_t& id, const int index,
Stefan Lafon12d01fa2017-12-04 20:56:09 -080035 const SimplePredicate& simplePredicate,
Yangster-mac94e197c2018-01-02 16:03:03 -080036 const unordered_map<int64_t, int>& trackerNameIndexMap)
Yangster13fb7e42018-03-07 17:30:49 -080037 : ConditionTracker(id, index), mConfigKey(key), mContainANYPositionInInternalDimensions(false) {
Yangster-mac94e197c2018-01-02 16:03:03 -080038 VLOG("creating SimpleConditionTracker %lld", (long long)mConditionId);
Stefan Lafon12d01fa2017-12-04 20:56:09 -080039 mCountNesting = simplePredicate.count_nesting();
Yao Chencaf339d2017-10-06 16:01:10 -070040
Stefan Lafon12d01fa2017-12-04 20:56:09 -080041 if (simplePredicate.has_start()) {
42 auto pair = trackerNameIndexMap.find(simplePredicate.start());
Yao Chencaf339d2017-10-06 16:01:10 -070043 if (pair == trackerNameIndexMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -080044 ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
Yao Chencaf339d2017-10-06 16:01:10 -070045 return;
46 }
47 mStartLogMatcherIndex = pair->second;
48 mTrackerIndex.insert(mStartLogMatcherIndex);
49 } else {
50 mStartLogMatcherIndex = -1;
51 }
52
Stefan Lafon12d01fa2017-12-04 20:56:09 -080053 if (simplePredicate.has_stop()) {
54 auto pair = trackerNameIndexMap.find(simplePredicate.stop());
Yao Chencaf339d2017-10-06 16:01:10 -070055 if (pair == trackerNameIndexMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -080056 ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
Yao Chencaf339d2017-10-06 16:01:10 -070057 return;
58 }
59 mStopLogMatcherIndex = pair->second;
Yao Chen4b146852017-10-10 15:34:42 -070060 mTrackerIndex.insert(mStopLogMatcherIndex);
Yao Chencaf339d2017-10-06 16:01:10 -070061 } else {
62 mStopLogMatcherIndex = -1;
63 }
64
Stefan Lafon12d01fa2017-12-04 20:56:09 -080065 if (simplePredicate.has_stop_all()) {
66 auto pair = trackerNameIndexMap.find(simplePredicate.stop_all());
Yao Chencaf339d2017-10-06 16:01:10 -070067 if (pair == trackerNameIndexMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -080068 ALOGW("Stop all matcher %lld found in the config", (long long)simplePredicate.stop_all());
Yao Chencaf339d2017-10-06 16:01:10 -070069 return;
70 }
71 mStopAllLogMatcherIndex = pair->second;
72 mTrackerIndex.insert(mStopAllLogMatcherIndex);
73 } else {
74 mStopAllLogMatcherIndex = -1;
75 }
76
Yao Chen8a8d16c2018-02-08 14:50:40 -080077 if (simplePredicate.has_dimensions()) {
78 translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
79 if (mOutputDimensions.size() > 0) {
80 mSliced = true;
81 mDimensionTag = mOutputDimensions[0].mMatcher.getTag();
82 }
Yangster13fb7e42018-03-07 17:30:49 -080083 mContainANYPositionInInternalDimensions = HasPositionANY(simplePredicate.dimensions());
Yao Chen5154a3792017-10-30 22:57:06 -070084 }
85
Stefan Lafon12d01fa2017-12-04 20:56:09 -080086 if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
Yao Chen967b2052017-11-07 16:36:43 -080087 mInitialValue = ConditionState::kFalse;
88 } else {
89 mInitialValue = ConditionState::kUnknown;
90 }
91
92 mNonSlicedConditionState = mInitialValue;
93
Yangster13fb7e42018-03-07 17:30:49 -080094 if (!mSliced) {
95 mUnSlicedPart = mInitialValue;
96 }
97
Yao Chencaf339d2017-10-06 16:01:10 -070098 mInitialized = true;
99}
100
101SimpleConditionTracker::~SimpleConditionTracker() {
102 VLOG("~SimpleConditionTracker()");
103}
104
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800105bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
Yao Chencaf339d2017-10-06 16:01:10 -0700106 const vector<sp<ConditionTracker>>& allConditionTrackers,
Yangster-mac94e197c2018-01-02 16:03:03 -0800107 const unordered_map<int64_t, int>& conditionIdIndexMap,
Yao Chencaf339d2017-10-06 16:01:10 -0700108 vector<bool>& stack) {
109 // SimpleConditionTracker does not have dependency on other conditions, thus we just return
110 // if the initialization was successful.
111 return mInitialized;
112}
113
Yao Chen580ea3212018-02-26 14:21:54 -0800114void SimpleConditionTracker::dumpState() {
115 VLOG("%lld DUMP:", (long long)mConditionId);
116 for (const auto& pair : mSlicedConditionState) {
Yangster13fb7e42018-03-07 17:30:49 -0800117 VLOG("\t%s : %d", pair.first.toString().c_str(), pair.second);
Yao Chen729093d2017-10-16 10:33:26 -0700118 }
Yao Chen580ea3212018-02-26 14:21:54 -0800119
120 VLOG("Changed to true keys: \n");
121 for (const auto& key : mLastChangedToTrueDimensions) {
122 VLOG("%s", key.toString().c_str());
123 }
124 VLOG("Changed to false keys: \n");
125 for (const auto& key : mLastChangedToFalseDimensions) {
126 VLOG("%s", key.toString().c_str());
127 }
Yao Chen729093d2017-10-16 10:33:26 -0700128}
129
Yao Chen967b2052017-11-07 16:36:43 -0800130void SimpleConditionTracker::handleStopAll(std::vector<ConditionState>& conditionCache,
131 std::vector<bool>& conditionChangedCache) {
132 // Unless the default condition is false, and there was nothing started, otherwise we have
133 // triggered a condition change.
134 conditionChangedCache[mIndex] =
135 (mInitialValue == ConditionState::kFalse && mSlicedConditionState.empty()) ? false
136 : true;
137
Yao Chen580ea3212018-02-26 14:21:54 -0800138 for (const auto& cond : mSlicedConditionState) {
139 if (cond.second > 0) {
140 mLastChangedToFalseDimensions.insert(cond.first);
141 }
142 }
143
Yao Chen967b2052017-11-07 16:36:43 -0800144 // After StopAll, we know everything has stopped. From now on, default condition is false.
145 mInitialValue = ConditionState::kFalse;
146 mSlicedConditionState.clear();
147 conditionCache[mIndex] = ConditionState::kFalse;
Yangster13fb7e42018-03-07 17:30:49 -0800148 if (!mSliced) {
149 mUnSlicedPart = ConditionState::kFalse;
150 }
Yao Chen967b2052017-11-07 16:36:43 -0800151}
152
Yao Chenb3561512017-11-21 18:07:17 -0800153bool SimpleConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
154 if (!mSliced || mSlicedConditionState.find(newKey) != mSlicedConditionState.end()) {
155 // if the condition is not sliced or the key is not new, we are good!
156 return false;
157 }
158 // 1. Report the tuple count if the tuple count > soft limit
159 if (mSlicedConditionState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
160 size_t newTupleCount = mSlicedConditionState.size() + 1;
Yangster-mac94e197c2018-01-02 16:03:03 -0800161 StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount);
Yao Chenb3561512017-11-21 18:07:17 -0800162 // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
163 if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800164 ALOGE("Predicate %lld dropping data for dimension key %s",
Yangster13fb7e42018-03-07 17:30:49 -0800165 (long long)mConditionId, newKey.toString().c_str());
Yao Chenb3561512017-11-21 18:07:17 -0800166 return true;
167 }
168 }
169 return false;
170}
171
Yao Chen967b2052017-11-07 16:36:43 -0800172void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800173 bool matchStart, ConditionState* conditionCache,
174 bool* conditionChangedCache) {
Yao Chen967b2052017-11-07 16:36:43 -0800175 bool changed = false;
176 auto outputIt = mSlicedConditionState.find(outputKey);
177 ConditionState newCondition;
Yao Chenb3561512017-11-21 18:07:17 -0800178 if (hitGuardRail(outputKey)) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800179 (*conditionChangedCache) = false;
Yao Chenb3561512017-11-21 18:07:17 -0800180 // Tells the caller it's evaluated.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800181 (*conditionCache) = ConditionState::kUnknown;
Yao Chenb3561512017-11-21 18:07:17 -0800182 return;
183 }
Yao Chen967b2052017-11-07 16:36:43 -0800184 if (outputIt == mSlicedConditionState.end()) {
185 // We get a new output key.
186 newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
187 if (matchStart && mInitialValue != ConditionState::kTrue) {
Yangster13fb7e42018-03-07 17:30:49 -0800188 mSlicedConditionState[outputKey] = 1;
Yao Chen967b2052017-11-07 16:36:43 -0800189 changed = true;
Yao Chen580ea3212018-02-26 14:21:54 -0800190 mLastChangedToTrueDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800191 } else if (mInitialValue != ConditionState::kFalse) {
192 // it's a stop and we don't have history about it.
193 // If the default condition is not false, it means this stop is valuable to us.
Yangster13fb7e42018-03-07 17:30:49 -0800194 mSlicedConditionState[outputKey] = 0;
Yao Chen580ea3212018-02-26 14:21:54 -0800195 mLastChangedToFalseDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800196 changed = true;
197 }
198 } else {
199 // we have history about this output key.
200 auto& startedCount = outputIt->second;
201 // assign the old value first.
202 newCondition = startedCount > 0 ? ConditionState::kTrue : ConditionState::kFalse;
203 if (matchStart) {
204 if (startedCount == 0) {
Yao Chen580ea3212018-02-26 14:21:54 -0800205 mLastChangedToTrueDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800206 // This condition for this output key will change from false -> true
207 changed = true;
208 }
209
210 // it's ok to do ++ here, even if we don't count nesting. The >1 counts will be treated
211 // as 1 if not counting nesting.
212 startedCount++;
213 newCondition = ConditionState::kTrue;
214 } else {
215 // This is a stop event.
216 if (startedCount > 0) {
217 if (mCountNesting) {
218 startedCount--;
219 if (startedCount == 0) {
220 newCondition = ConditionState::kFalse;
221 }
222 } else {
223 // not counting nesting, so ignore the number of starts, stop now.
224 startedCount = 0;
225 newCondition = ConditionState::kFalse;
226 }
227 // if everything has stopped for this output key, condition true -> false;
228 if (startedCount == 0) {
Yao Chen580ea3212018-02-26 14:21:54 -0800229 mLastChangedToFalseDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800230 changed = true;
231 }
232 }
233
234 // if default condition is false, it means we don't need to keep the false values.
235 if (mInitialValue == ConditionState::kFalse && startedCount == 0) {
236 mSlicedConditionState.erase(outputIt);
Yangster13fb7e42018-03-07 17:30:49 -0800237 VLOG("erase key %s", outputKey.toString().c_str());
Yao Chen967b2052017-11-07 16:36:43 -0800238 }
239 }
240 }
241
242 // dump all dimensions for debugging
243 if (DEBUG) {
Yao Chen580ea3212018-02-26 14:21:54 -0800244 dumpState();
Yao Chen967b2052017-11-07 16:36:43 -0800245 }
246
Yao Chen8a8d16c2018-02-08 14:50:40 -0800247 (*conditionChangedCache) = changed;
248 (*conditionCache) = newCondition;
Yangster13fb7e42018-03-07 17:30:49 -0800249
Yangster-mac94e197c2018-01-02 16:03:03 -0800250 VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
Yao Chen967b2052017-11-07 16:36:43 -0800251 conditionChangedCache[mIndex] == true);
252}
253
Yangster-mac93694462018-01-22 20:49:31 -0800254void SimpleConditionTracker::evaluateCondition(
255 const LogEvent& event,
256 const vector<MatchingState>& eventMatcherValues,
257 const vector<sp<ConditionTracker>>& mAllConditions,
258 vector<ConditionState>& conditionCache,
259 vector<bool>& conditionChangedCache) {
Yao Chencaf339d2017-10-06 16:01:10 -0700260 if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
261 // it has been evaluated.
Yangster-mac94e197c2018-01-02 16:03:03 -0800262 VLOG("Yes, already evaluated, %lld %d",
263 (long long)mConditionId, conditionCache[mIndex]);
Yao Chen967b2052017-11-07 16:36:43 -0800264 return;
Yao Chencaf339d2017-10-06 16:01:10 -0700265 }
Yao Chen580ea3212018-02-26 14:21:54 -0800266 mLastChangedToTrueDimensions.clear();
267 mLastChangedToFalseDimensions.clear();
Yao Chencaf339d2017-10-06 16:01:10 -0700268
David Chenc18abed2017-11-22 16:47:59 -0800269 if (mStopAllLogMatcherIndex >= 0 && mStopAllLogMatcherIndex < int(eventMatcherValues.size()) &&
Yao Chen967b2052017-11-07 16:36:43 -0800270 eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
271 handleStopAll(conditionCache, conditionChangedCache);
272 return;
273 }
Yao Chen729093d2017-10-16 10:33:26 -0700274
Yao Chen967b2052017-11-07 16:36:43 -0800275 int matchedState = -1;
Yao Chencaf339d2017-10-06 16:01:10 -0700276 // Note: The order to evaluate the following start, stop, stop_all matters.
277 // The priority of overwrite is stop_all > stop > start.
278 if (mStartLogMatcherIndex >= 0 &&
279 eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
Yao Chen967b2052017-11-07 16:36:43 -0800280 matchedState = 1;
Yao Chencaf339d2017-10-06 16:01:10 -0700281 }
282
283 if (mStopLogMatcherIndex >= 0 &&
284 eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
Yao Chen967b2052017-11-07 16:36:43 -0800285 matchedState = 0;
Yao Chencaf339d2017-10-06 16:01:10 -0700286 }
287
Yao Chen967b2052017-11-07 16:36:43 -0800288 if (matchedState < 0) {
Yao Chend41c4222017-11-15 19:26:14 -0800289 // The event doesn't match this condition. So we just report existing condition values.
Yao Chen967b2052017-11-07 16:36:43 -0800290 conditionChangedCache[mIndex] = false;
Yao Chend41c4222017-11-15 19:26:14 -0800291 if (mSliced) {
Yao Chen427d3722018-03-22 15:21:52 -0700292 // if the condition result is sliced. The overall condition is true if any of the sliced
293 // condition is true
Yangster-mac93694462018-01-22 20:49:31 -0800294 conditionCache[mIndex] = mInitialValue;
Yao Chen427d3722018-03-22 15:21:52 -0700295 for (const auto& slicedCondition : mSlicedConditionState) {
296 if (slicedCondition.second > 0) {
297 conditionCache[mIndex] = ConditionState::kTrue;
298 break;
299 }
300 }
Yao Chend41c4222017-11-15 19:26:14 -0800301 } else {
Yangster7c334a12017-11-22 14:24:24 -0800302 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
303 if (itr == mSlicedConditionState.end()) {
304 // condition not sliced, but we haven't seen the matched start or stop yet. so
305 // return initial value.
306 conditionCache[mIndex] = mInitialValue;
307 } else {
308 // return the cached condition.
309 conditionCache[mIndex] =
310 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
311 }
Yangster13fb7e42018-03-07 17:30:49 -0800312 mUnSlicedPart = conditionCache[mIndex];
Yao Chend41c4222017-11-15 19:26:14 -0800313 }
Yangster7c334a12017-11-22 14:24:24 -0800314
Yao Chen967b2052017-11-07 16:36:43 -0800315 return;
Yao Chen729093d2017-10-16 10:33:26 -0700316 }
317
Yao Chen8a8d16c2018-02-08 14:50:40 -0800318 ConditionState overallState = mInitialValue;
319 bool overallChanged = false;
320
321 if (mOutputDimensions.size() == 0) {
322 handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
323 &overallChanged);
Yangster13fb7e42018-03-07 17:30:49 -0800324 } else if (!mContainANYPositionInInternalDimensions) {
325 HashableDimensionKey outputValue;
326 filterValues(mOutputDimensions, event.getValues(), &outputValue);
327
328 // If this event has multiple nodes in the attribution chain, this log event probably will
329 // generate multiple dimensions. If so, we will find if the condition changes for any
330 // dimension and ask the corresponding metric producer to verify whether the actual sliced
331 // condition has changed or not.
332 // A high level assumption is that a predicate is either sliced or unsliced. We will never
333 // have both sliced and unsliced version of a predicate.
334 handleConditionEvent(outputValue, matchedState == 1, &overallState, &overallChanged);
Yangster-mac20877162017-12-22 17:19:39 -0800335 } else {
Yangster-mace06cfd72018-03-10 23:22:59 -0800336 ALOGE("The condition tracker should not be sliced by ANY position matcher.");
Yangster-mac20877162017-12-22 17:19:39 -0800337 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800338 conditionCache[mIndex] = overallState;
339 conditionChangedCache[mIndex] = overallChanged;
Yangster13fb7e42018-03-07 17:30:49 -0800340 if (!mSliced) {
341 mUnSlicedPart = overallState;
342 }
Yao Chen729093d2017-10-16 10:33:26 -0700343}
344
345void SimpleConditionTracker::isConditionMet(
Yao Chen8a8d16c2018-02-08 14:50:40 -0800346 const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
Yangster13fb7e42018-03-07 17:30:49 -0800347 const vector<Matcher>& dimensionFields,
348 const bool isSubOutputDimensionFields,
349 const bool isPartialLink,
350 vector<ConditionState>& conditionCache,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800351 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
352
Yangster-mac93694462018-01-22 20:49:31 -0800353 if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
354 // it has been evaluated.
355 VLOG("Yes, already evaluated, %lld %d",
356 (long long)mConditionId, conditionCache[mIndex]);
Yao Chen729093d2017-10-16 10:33:26 -0700357 return;
358 }
Yangster-mac93694462018-01-22 20:49:31 -0800359 const auto pair = conditionParameters.find(mConditionId);
360
361 if (pair == conditionParameters.end()) {
362 ConditionState conditionState = ConditionState::kNotEvaluated;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800363 if (dimensionFields.size() > 0 && dimensionFields[0].mMatcher.getTag() == mDimensionTag) {
Yangster-mac93694462018-01-22 20:49:31 -0800364 conditionState = conditionState | getMetConditionDimension(
Yangster13fb7e42018-03-07 17:30:49 -0800365 allConditions, dimensionFields, isSubOutputDimensionFields, dimensionsKeySet);
Yangster-mac93694462018-01-22 20:49:31 -0800366 } else {
367 conditionState = conditionState | mInitialValue;
368 if (!mSliced) {
369 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
370 if (itr != mSlicedConditionState.end()) {
371 ConditionState sliceState =
372 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
373 conditionState = conditionState | sliceState;
374 }
375 }
376 }
377 conditionCache[mIndex] = conditionState;
378 return;
379 }
Yao Chen729093d2017-10-16 10:33:26 -0700380
Yangster-mac20877162017-12-22 17:19:39 -0800381 ConditionState conditionState = ConditionState::kNotEvaluated;
Yangster13fb7e42018-03-07 17:30:49 -0800382 const HashableDimensionKey& key = pair->second;
383 if (isPartialLink) {
384 // For unseen key, check whether the require dimensions are subset of sliced condition
385 // output.
386 conditionState = conditionState | mInitialValue;
387 for (const auto& slice : mSlicedConditionState) {
388 ConditionState sliceState =
389 slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
390 if (slice.first.contains(key)) {
391 conditionState = conditionState | sliceState;
392 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
393 if (isSubOutputDimensionFields) {
394 HashableDimensionKey dimensionKey;
395 filterValues(dimensionFields, slice.first.getValues(), &dimensionKey);
396 dimensionsKeySet.insert(dimensionKey);
397 } else {
398 dimensionsKeySet.insert(slice.first);
399 }
400 }
401 }
402 }
403 } else {
Yangster-mac20877162017-12-22 17:19:39 -0800404 auto startedCountIt = mSlicedConditionState.find(key);
Yangster13fb7e42018-03-07 17:30:49 -0800405 conditionState = conditionState | mInitialValue;
Yangster-mac20877162017-12-22 17:19:39 -0800406 if (startedCountIt != mSlicedConditionState.end()) {
Yangster-mac93694462018-01-22 20:49:31 -0800407 ConditionState sliceState =
408 startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
409 conditionState = conditionState | sliceState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800410 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
Yangster13fb7e42018-03-07 17:30:49 -0800411 if (isSubOutputDimensionFields) {
412 HashableDimensionKey dimensionKey;
413 filterValues(dimensionFields, startedCountIt->first.getValues(), &dimensionKey);
414 dimensionsKeySet.insert(dimensionKey);
415 } else {
416 dimensionsKeySet.insert(startedCountIt->first);
Yangster-mac5503f5c2018-01-15 23:20:44 -0800417 }
Yangster-mac5503f5c2018-01-15 23:20:44 -0800418 }
Yangster-mac20877162017-12-22 17:19:39 -0800419 }
Yangster13fb7e42018-03-07 17:30:49 -0800420
421 }
Yangster-mac20877162017-12-22 17:19:39 -0800422 conditionCache[mIndex] = conditionState;
Yangster-mac94e197c2018-01-02 16:03:03 -0800423 VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
Yao Chencaf339d2017-10-06 16:01:10 -0700424}
425
Yangster-mac93694462018-01-22 20:49:31 -0800426ConditionState SimpleConditionTracker::getMetConditionDimension(
427 const std::vector<sp<ConditionTracker>>& allConditions,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800428 const vector<Matcher>& dimensionFields,
Yangster13fb7e42018-03-07 17:30:49 -0800429 const bool isSubOutputDimensionFields,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800430 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
Yangster-mac93694462018-01-22 20:49:31 -0800431 ConditionState conditionState = mInitialValue;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800432 if (dimensionFields.size() == 0 || mOutputDimensions.size() == 0 ||
433 dimensionFields[0].mMatcher.getTag() != mOutputDimensions[0].mMatcher.getTag()) {
Yangster-mac93694462018-01-22 20:49:31 -0800434 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
435 if (itr != mSlicedConditionState.end()) {
436 ConditionState sliceState =
437 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
438 conditionState = conditionState | sliceState;
439 }
440 return conditionState;
441 }
442
443 for (const auto& slice : mSlicedConditionState) {
444 ConditionState sliceState =
445 slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
Yangster-mac93694462018-01-22 20:49:31 -0800446 conditionState = conditionState | sliceState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800447
448 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
Yangster13fb7e42018-03-07 17:30:49 -0800449 if (isSubOutputDimensionFields) {
450 HashableDimensionKey dimensionKey;
451 filterValues(dimensionFields, slice.first.getValues(), &dimensionKey);
452 dimensionsKeySet.insert(dimensionKey);
453 } else {
454 dimensionsKeySet.insert(slice.first);
455 }
Yangster-mac93694462018-01-22 20:49:31 -0800456 }
457 }
458 return conditionState;
459}
460
Yao Chencaf339d2017-10-06 16:01:10 -0700461} // namespace statsd
462} // namespace os
463} // namespace android