blob: 9e27a8b51a996c695aa5be9b210f90ed5d7d2648 [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)
37 : ConditionTracker(id, index), mConfigKey(key) {
38 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 }
Yao Chen5154a3792017-10-30 22:57:06 -070083 }
84
Stefan Lafon12d01fa2017-12-04 20:56:09 -080085 if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) {
Yao Chen967b2052017-11-07 16:36:43 -080086 mInitialValue = ConditionState::kFalse;
87 } else {
88 mInitialValue = ConditionState::kUnknown;
89 }
90
91 mNonSlicedConditionState = mInitialValue;
92
Yao Chencaf339d2017-10-06 16:01:10 -070093 mInitialized = true;
94}
95
96SimpleConditionTracker::~SimpleConditionTracker() {
97 VLOG("~SimpleConditionTracker()");
98}
99
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800100bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
Yao Chencaf339d2017-10-06 16:01:10 -0700101 const vector<sp<ConditionTracker>>& allConditionTrackers,
Yangster-mac94e197c2018-01-02 16:03:03 -0800102 const unordered_map<int64_t, int>& conditionIdIndexMap,
Yao Chencaf339d2017-10-06 16:01:10 -0700103 vector<bool>& stack) {
104 // SimpleConditionTracker does not have dependency on other conditions, thus we just return
105 // if the initialization was successful.
106 return mInitialized;
107}
108
Yao Chen580ea3212018-02-26 14:21:54 -0800109void SimpleConditionTracker::dumpState() {
110 VLOG("%lld DUMP:", (long long)mConditionId);
111 for (const auto& pair : mSlicedConditionState) {
Yao Chen967b2052017-11-07 16:36:43 -0800112 VLOG("\t%s : %d", pair.first.c_str(), pair.second);
Yao Chen729093d2017-10-16 10:33:26 -0700113 }
Yao Chen580ea3212018-02-26 14:21:54 -0800114
115 VLOG("Changed to true keys: \n");
116 for (const auto& key : mLastChangedToTrueDimensions) {
117 VLOG("%s", key.toString().c_str());
118 }
119 VLOG("Changed to false keys: \n");
120 for (const auto& key : mLastChangedToFalseDimensions) {
121 VLOG("%s", key.toString().c_str());
122 }
Yao Chen729093d2017-10-16 10:33:26 -0700123}
124
Yao Chen967b2052017-11-07 16:36:43 -0800125void SimpleConditionTracker::handleStopAll(std::vector<ConditionState>& conditionCache,
126 std::vector<bool>& conditionChangedCache) {
127 // Unless the default condition is false, and there was nothing started, otherwise we have
128 // triggered a condition change.
129 conditionChangedCache[mIndex] =
130 (mInitialValue == ConditionState::kFalse && mSlicedConditionState.empty()) ? false
131 : true;
132
Yao Chen580ea3212018-02-26 14:21:54 -0800133 for (const auto& cond : mSlicedConditionState) {
134 if (cond.second > 0) {
135 mLastChangedToFalseDimensions.insert(cond.first);
136 }
137 }
138
Yao Chen967b2052017-11-07 16:36:43 -0800139 // After StopAll, we know everything has stopped. From now on, default condition is false.
140 mInitialValue = ConditionState::kFalse;
141 mSlicedConditionState.clear();
142 conditionCache[mIndex] = ConditionState::kFalse;
143}
144
Yao Chenb3561512017-11-21 18:07:17 -0800145bool SimpleConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) {
146 if (!mSliced || mSlicedConditionState.find(newKey) != mSlicedConditionState.end()) {
147 // if the condition is not sliced or the key is not new, we are good!
148 return false;
149 }
150 // 1. Report the tuple count if the tuple count > soft limit
151 if (mSlicedConditionState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) {
152 size_t newTupleCount = mSlicedConditionState.size() + 1;
Yangster-mac94e197c2018-01-02 16:03:03 -0800153 StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount);
Yao Chenb3561512017-11-21 18:07:17 -0800154 // 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
155 if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800156 ALOGE("Predicate %lld dropping data for dimension key %s",
157 (long long)mConditionId, newKey.c_str());
Yao Chenb3561512017-11-21 18:07:17 -0800158 return true;
159 }
160 }
161 return false;
162}
163
Yao Chen967b2052017-11-07 16:36:43 -0800164void SimpleConditionTracker::handleConditionEvent(const HashableDimensionKey& outputKey,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800165 bool matchStart, ConditionState* conditionCache,
166 bool* conditionChangedCache) {
Yao Chen967b2052017-11-07 16:36:43 -0800167 bool changed = false;
168 auto outputIt = mSlicedConditionState.find(outputKey);
169 ConditionState newCondition;
Yao Chenb3561512017-11-21 18:07:17 -0800170 if (hitGuardRail(outputKey)) {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800171 (*conditionChangedCache) = false;
Yao Chenb3561512017-11-21 18:07:17 -0800172 // Tells the caller it's evaluated.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800173 (*conditionCache) = ConditionState::kUnknown;
Yao Chenb3561512017-11-21 18:07:17 -0800174 return;
175 }
Yao Chen967b2052017-11-07 16:36:43 -0800176 if (outputIt == mSlicedConditionState.end()) {
177 // We get a new output key.
178 newCondition = matchStart ? ConditionState::kTrue : ConditionState::kFalse;
179 if (matchStart && mInitialValue != ConditionState::kTrue) {
Yangster-mac5503f5c2018-01-15 23:20:44 -0800180 mSlicedConditionState.insert(std::make_pair(outputKey, 1));
Yao Chen967b2052017-11-07 16:36:43 -0800181 changed = true;
Yao Chen580ea3212018-02-26 14:21:54 -0800182 mLastChangedToTrueDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800183 } else if (mInitialValue != ConditionState::kFalse) {
184 // it's a stop and we don't have history about it.
185 // If the default condition is not false, it means this stop is valuable to us.
Yangster-mac5503f5c2018-01-15 23:20:44 -0800186 mSlicedConditionState.insert(std::make_pair(outputKey, 0));
Yao Chen580ea3212018-02-26 14:21:54 -0800187 mLastChangedToFalseDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800188 changed = true;
189 }
190 } else {
191 // we have history about this output key.
192 auto& startedCount = outputIt->second;
193 // assign the old value first.
194 newCondition = startedCount > 0 ? ConditionState::kTrue : ConditionState::kFalse;
195 if (matchStart) {
196 if (startedCount == 0) {
Yao Chen580ea3212018-02-26 14:21:54 -0800197 mLastChangedToTrueDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800198 // This condition for this output key will change from false -> true
199 changed = true;
200 }
201
202 // it's ok to do ++ here, even if we don't count nesting. The >1 counts will be treated
203 // as 1 if not counting nesting.
204 startedCount++;
205 newCondition = ConditionState::kTrue;
206 } else {
207 // This is a stop event.
208 if (startedCount > 0) {
209 if (mCountNesting) {
210 startedCount--;
211 if (startedCount == 0) {
212 newCondition = ConditionState::kFalse;
213 }
214 } else {
215 // not counting nesting, so ignore the number of starts, stop now.
216 startedCount = 0;
217 newCondition = ConditionState::kFalse;
218 }
219 // if everything has stopped for this output key, condition true -> false;
220 if (startedCount == 0) {
Yao Chen580ea3212018-02-26 14:21:54 -0800221 mLastChangedToFalseDimensions.insert(outputKey);
Yao Chen967b2052017-11-07 16:36:43 -0800222 changed = true;
223 }
224 }
225
226 // if default condition is false, it means we don't need to keep the false values.
227 if (mInitialValue == ConditionState::kFalse && startedCount == 0) {
228 mSlicedConditionState.erase(outputIt);
229 VLOG("erase key %s", outputKey.c_str());
230 }
231 }
232 }
233
234 // dump all dimensions for debugging
235 if (DEBUG) {
Yao Chen580ea3212018-02-26 14:21:54 -0800236 dumpState();
Yao Chen967b2052017-11-07 16:36:43 -0800237 }
238
Yao Chen8a8d16c2018-02-08 14:50:40 -0800239 (*conditionChangedCache) = changed;
240 (*conditionCache) = newCondition;
Yangster-mac94e197c2018-01-02 16:03:03 -0800241 VLOG("SimplePredicate %lld nonSlicedChange? %d", (long long)mConditionId,
Yao Chen967b2052017-11-07 16:36:43 -0800242 conditionChangedCache[mIndex] == true);
243}
244
Yangster-mac93694462018-01-22 20:49:31 -0800245void SimpleConditionTracker::evaluateCondition(
246 const LogEvent& event,
247 const vector<MatchingState>& eventMatcherValues,
248 const vector<sp<ConditionTracker>>& mAllConditions,
249 vector<ConditionState>& conditionCache,
250 vector<bool>& conditionChangedCache) {
Yao Chencaf339d2017-10-06 16:01:10 -0700251 if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
252 // it has been evaluated.
Yangster-mac94e197c2018-01-02 16:03:03 -0800253 VLOG("Yes, already evaluated, %lld %d",
254 (long long)mConditionId, conditionCache[mIndex]);
Yao Chen967b2052017-11-07 16:36:43 -0800255 return;
Yao Chencaf339d2017-10-06 16:01:10 -0700256 }
Yao Chen580ea3212018-02-26 14:21:54 -0800257 mLastChangedToTrueDimensions.clear();
258 mLastChangedToFalseDimensions.clear();
Yao Chencaf339d2017-10-06 16:01:10 -0700259
David Chenc18abed2017-11-22 16:47:59 -0800260 if (mStopAllLogMatcherIndex >= 0 && mStopAllLogMatcherIndex < int(eventMatcherValues.size()) &&
Yao Chen967b2052017-11-07 16:36:43 -0800261 eventMatcherValues[mStopAllLogMatcherIndex] == MatchingState::kMatched) {
262 handleStopAll(conditionCache, conditionChangedCache);
263 return;
264 }
Yao Chen729093d2017-10-16 10:33:26 -0700265
Yao Chen967b2052017-11-07 16:36:43 -0800266 int matchedState = -1;
Yao Chencaf339d2017-10-06 16:01:10 -0700267 // Note: The order to evaluate the following start, stop, stop_all matters.
268 // The priority of overwrite is stop_all > stop > start.
269 if (mStartLogMatcherIndex >= 0 &&
270 eventMatcherValues[mStartLogMatcherIndex] == MatchingState::kMatched) {
Yao Chen967b2052017-11-07 16:36:43 -0800271 matchedState = 1;
Yao Chencaf339d2017-10-06 16:01:10 -0700272 }
273
274 if (mStopLogMatcherIndex >= 0 &&
275 eventMatcherValues[mStopLogMatcherIndex] == MatchingState::kMatched) {
Yao Chen967b2052017-11-07 16:36:43 -0800276 matchedState = 0;
Yao Chencaf339d2017-10-06 16:01:10 -0700277 }
278
Yao Chen967b2052017-11-07 16:36:43 -0800279 if (matchedState < 0) {
Yao Chend41c4222017-11-15 19:26:14 -0800280 // The event doesn't match this condition. So we just report existing condition values.
Yao Chen967b2052017-11-07 16:36:43 -0800281 conditionChangedCache[mIndex] = false;
Yao Chend41c4222017-11-15 19:26:14 -0800282 if (mSliced) {
283 // if the condition result is sliced. metrics won't directly get value from the
284 // cache, so just set any value other than kNotEvaluated.
Yangster-mac93694462018-01-22 20:49:31 -0800285 conditionCache[mIndex] = mInitialValue;
Yao Chend41c4222017-11-15 19:26:14 -0800286 } else {
Yangster7c334a12017-11-22 14:24:24 -0800287 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
288 if (itr == mSlicedConditionState.end()) {
289 // condition not sliced, but we haven't seen the matched start or stop yet. so
290 // return initial value.
291 conditionCache[mIndex] = mInitialValue;
292 } else {
293 // return the cached condition.
294 conditionCache[mIndex] =
295 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
296 }
Yao Chend41c4222017-11-15 19:26:14 -0800297 }
Yangster7c334a12017-11-22 14:24:24 -0800298
Yao Chen967b2052017-11-07 16:36:43 -0800299 return;
Yao Chen729093d2017-10-16 10:33:26 -0700300 }
301
Yao Chen8a8d16c2018-02-08 14:50:40 -0800302 ConditionState overallState = mInitialValue;
303 bool overallChanged = false;
304
305 if (mOutputDimensions.size() == 0) {
306 handleConditionEvent(DEFAULT_DIMENSION_KEY, matchedState == 1, &overallState,
307 &overallChanged);
Yangster-mac20877162017-12-22 17:19:39 -0800308 } else {
Yao Chen8a8d16c2018-02-08 14:50:40 -0800309 std::vector<HashableDimensionKey> outputValues;
310 filterValues(mOutputDimensions, event.getValues(), &outputValues);
311
Yangster-mac20877162017-12-22 17:19:39 -0800312 // If this event has multiple nodes in the attribution chain, this log event probably will
313 // generate multiple dimensions. If so, we will find if the condition changes for any
314 // dimension and ask the corresponding metric producer to verify whether the actual sliced
315 // condition has changed or not.
316 // A high level assumption is that a predicate is either sliced or unsliced. We will never
317 // have both sliced and unsliced version of a predicate.
Yao Chen8a8d16c2018-02-08 14:50:40 -0800318 for (const HashableDimensionKey& outputValue : outputValues) {
Yao Chen580ea3212018-02-26 14:21:54 -0800319 ConditionState tempState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800320 bool tempChanged = false;
321 handleConditionEvent(outputValue, matchedState == 1, &tempState, &tempChanged);
322 if (tempChanged) {
323 overallChanged = true;
324 }
Yao Chen580ea3212018-02-26 14:21:54 -0800325 // ConditionState's | operator is overridden
326 overallState = overallState | tempState;
Yangster-mac20877162017-12-22 17:19:39 -0800327 }
328 }
Yao Chen8a8d16c2018-02-08 14:50:40 -0800329 conditionCache[mIndex] = overallState;
330 conditionChangedCache[mIndex] = overallChanged;
Yao Chen729093d2017-10-16 10:33:26 -0700331}
332
333void SimpleConditionTracker::isConditionMet(
Yao Chen8a8d16c2018-02-08 14:50:40 -0800334 const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
335 const vector<Matcher>& dimensionFields, vector<ConditionState>& conditionCache,
336 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
337
Yangster-mac93694462018-01-22 20:49:31 -0800338 if (conditionCache[mIndex] != ConditionState::kNotEvaluated) {
339 // it has been evaluated.
340 VLOG("Yes, already evaluated, %lld %d",
341 (long long)mConditionId, conditionCache[mIndex]);
Yao Chen729093d2017-10-16 10:33:26 -0700342 return;
343 }
Yangster-mac93694462018-01-22 20:49:31 -0800344 const auto pair = conditionParameters.find(mConditionId);
345
346 if (pair == conditionParameters.end()) {
347 ConditionState conditionState = ConditionState::kNotEvaluated;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800348 if (dimensionFields.size() > 0 && dimensionFields[0].mMatcher.getTag() == mDimensionTag) {
Yangster-mac93694462018-01-22 20:49:31 -0800349 conditionState = conditionState | getMetConditionDimension(
350 allConditions, dimensionFields, dimensionsKeySet);
351 } else {
352 conditionState = conditionState | mInitialValue;
353 if (!mSliced) {
354 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
355 if (itr != mSlicedConditionState.end()) {
356 ConditionState sliceState =
357 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
358 conditionState = conditionState | sliceState;
359 }
360 }
361 }
362 conditionCache[mIndex] = conditionState;
363 return;
364 }
365 std::vector<HashableDimensionKey> defaultKeys = { DEFAULT_DIMENSION_KEY };
Yangster-mac20877162017-12-22 17:19:39 -0800366 const std::vector<HashableDimensionKey> &keys =
367 (pair == conditionParameters.end()) ? defaultKeys : pair->second;
Yao Chen729093d2017-10-16 10:33:26 -0700368
Yangster-mac20877162017-12-22 17:19:39 -0800369 ConditionState conditionState = ConditionState::kNotEvaluated;
Yangster-mac93694462018-01-22 20:49:31 -0800370 for (size_t i = 0; i < keys.size(); ++i) {
371 const HashableDimensionKey& key = keys[i];
Yangster-mac20877162017-12-22 17:19:39 -0800372 auto startedCountIt = mSlicedConditionState.find(key);
373 if (startedCountIt != mSlicedConditionState.end()) {
Yangster-mac93694462018-01-22 20:49:31 -0800374 ConditionState sliceState =
375 startedCountIt->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
376 conditionState = conditionState | sliceState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800377 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
378 vector<HashableDimensionKey> dimensionKeys;
379 filterValues(dimensionFields, startedCountIt->first.getValues(), &dimensionKeys);
380 dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
Yangster-mac93694462018-01-22 20:49:31 -0800381 }
Yangster-mac20877162017-12-22 17:19:39 -0800382 } else {
Yangster-mac5503f5c2018-01-15 23:20:44 -0800383 // For unseen key, check whether the require dimensions are subset of sliced condition
384 // output.
Yangster-mac93694462018-01-22 20:49:31 -0800385 conditionState = conditionState | mInitialValue;
Yangster-mac5503f5c2018-01-15 23:20:44 -0800386 for (const auto& slice : mSlicedConditionState) {
Yangster-mac93694462018-01-22 20:49:31 -0800387 ConditionState sliceState =
388 slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800389 if (slice.first.contains(key)) {
Yangster-mac93694462018-01-22 20:49:31 -0800390 conditionState = conditionState | sliceState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800391 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
392 vector<HashableDimensionKey> dimensionKeys;
393 filterValues(dimensionFields, slice.first.getValues(), &dimensionKeys);
394
395 dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
396 }
Yangster-mac93694462018-01-22 20:49:31 -0800397 }
Yangster-mac5503f5c2018-01-15 23:20:44 -0800398 }
Yangster-mac5503f5c2018-01-15 23:20:44 -0800399 }
Yangster-mac20877162017-12-22 17:19:39 -0800400 }
Yangster-mac20877162017-12-22 17:19:39 -0800401 conditionCache[mIndex] = conditionState;
Yangster-mac94e197c2018-01-02 16:03:03 -0800402 VLOG("Predicate %lld return %d", (long long)mConditionId, conditionCache[mIndex]);
Yao Chencaf339d2017-10-06 16:01:10 -0700403}
404
Yangster-mac93694462018-01-22 20:49:31 -0800405ConditionState SimpleConditionTracker::getMetConditionDimension(
406 const std::vector<sp<ConditionTracker>>& allConditions,
Yao Chen8a8d16c2018-02-08 14:50:40 -0800407 const vector<Matcher>& dimensionFields,
408 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const {
Yangster-mac93694462018-01-22 20:49:31 -0800409 ConditionState conditionState = mInitialValue;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800410 if (dimensionFields.size() == 0 || mOutputDimensions.size() == 0 ||
411 dimensionFields[0].mMatcher.getTag() != mOutputDimensions[0].mMatcher.getTag()) {
Yangster-mac93694462018-01-22 20:49:31 -0800412 const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
413 if (itr != mSlicedConditionState.end()) {
414 ConditionState sliceState =
415 itr->second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
416 conditionState = conditionState | sliceState;
417 }
418 return conditionState;
419 }
420
421 for (const auto& slice : mSlicedConditionState) {
422 ConditionState sliceState =
423 slice.second > 0 ? ConditionState::kTrue : ConditionState::kFalse;
Yangster-mac93694462018-01-22 20:49:31 -0800424 conditionState = conditionState | sliceState;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800425
426 if (sliceState == ConditionState::kTrue && dimensionFields.size() > 0) {
427 vector<HashableDimensionKey> dimensionKeys;
428 filterValues(dimensionFields, slice.first.getValues(), &dimensionKeys);
429
430 dimensionsKeySet.insert(dimensionKeys.begin(), dimensionKeys.end());
Yangster-mac93694462018-01-22 20:49:31 -0800431 }
432 }
433 return conditionState;
434}
435
Yao Chencaf339d2017-10-06 16:01:10 -0700436} // namespace statsd
437} // namespace os
438} // namespace android