blob: 80ed80776829b6965c53466689a4593e717c37ee [file] [log] [blame]
Yao Chen8a8d16c2018-02-08 14:50:40 -08001/*
2 * Copyright (C) 2018 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
17#define DEBUG false
18#include "Log.h"
19#include "FieldValue.h"
20#include "HashableDimensionKey.h"
Chenjie Yuc715b9e2018-10-19 07:52:12 -070021#include "math.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080022
23namespace android {
24namespace os {
25namespace statsd {
26
Yao Chen4c959cb2018-02-13 13:27:48 -080027int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
28 int32_t field = 0;
29 for (int32_t i = 0; i <= depth; i++) {
30 int32_t shiftBits = 8 * (kMaxLogDepth - i);
31 field |= (pos[i] << shiftBits);
32 }
33
34 if (includeDepth) {
35 field |= (depth << 24);
36 }
37 return field;
38}
39
40int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
41 return getEncodedField(mask, depth, false) | 0xff000000;
42}
43
Yao Chen8a8d16c2018-02-08 14:50:40 -080044bool Field::matches(const Matcher& matcher) const {
45 if (mTag != matcher.mMatcher.getTag()) {
46 return false;
47 }
48 if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
49 return true;
50 }
51
Yangster-mace06cfd72018-03-10 23:22:59 -080052 if (matcher.hasAllPositionMatcher() &&
53 (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
54 return true;
55 }
56
Yao Chen8a8d16c2018-02-08 14:50:40 -080057 return false;
Yao Chen4c959cb2018-02-13 13:27:48 -080058}
Yao Chen8a8d16c2018-02-08 14:50:40 -080059
60void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
61 std::vector<Matcher>* output) {
62 if (depth > kMaxLogDepth) {
63 ALOGE("depth > 2");
64 return;
65 }
66
67 pos[depth] = matcher.field();
68 mask[depth] = 0x7f;
69
70 if (matcher.has_position()) {
71 depth++;
72 if (depth > 2) {
73 return;
74 }
75 switch (matcher.position()) {
Yangster-mace06cfd72018-03-10 23:22:59 -080076 case Position::ALL:
77 pos[depth] = 0x00;
78 mask[depth] = 0x7f;
79 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -080080 case Position::ANY:
81 pos[depth] = 0;
82 mask[depth] = 0;
83 break;
84 case Position::FIRST:
85 pos[depth] = 1;
86 mask[depth] = 0x7f;
87 break;
88 case Position::LAST:
89 pos[depth] = 0x80;
90 mask[depth] = 0x80;
91 break;
92 case Position::POSITION_UNKNOWN:
93 pos[depth] = 0;
94 mask[depth] = 0;
95 break;
96 }
97 }
98
99 if (matcher.child_size() == 0) {
100 output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
Yao Chen8a8d16c2018-02-08 14:50:40 -0800101 } else {
102 for (const auto& child : matcher.child()) {
103 translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
104 }
105 }
106}
107
108void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
109 int pos[] = {1, 1, 1};
110 int mask[] = {0x7f, 0x7f, 0x7f};
111 int tag = matcher.field();
112 for (const auto& child : matcher.child()) {
113 translateFieldMatcher(tag, child, 0, pos, mask, output);
114 }
115}
116
117bool isAttributionUidField(const FieldValue& value) {
118 int field = value.mField.getField() & 0xff007f;
119 if (field == 0x10001 && value.mValue.getType() == INT) {
120 return true;
121 }
122 return false;
123}
124
125bool isAttributionUidField(const Field& field, const Value& value) {
126 int f = field.getField() & 0xff007f;
127 if (f == 0x10001 && value.getType() == INT) {
128 return true;
129 }
130 return false;
131}
132
133Value::Value(const Value& from) {
134 type = from.getType();
135 switch (type) {
136 case INT:
137 int_value = from.int_value;
138 break;
139 case LONG:
140 long_value = from.long_value;
141 break;
142 case FLOAT:
143 float_value = from.float_value;
144 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700145 case DOUBLE:
146 double_value = from.double_value;
147 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800148 case STRING:
149 str_value = from.str_value;
150 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700151 case STORAGE:
152 storage_value = from.storage_value;
153 break;
Yangster-macf5204922018-02-23 13:08:03 -0800154 default:
155 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800156 }
157}
158
159std::string Value::toString() const {
160 switch (type) {
161 case INT:
162 return std::to_string(int_value) + "[I]";
163 case LONG:
164 return std::to_string(long_value) + "[L]";
165 case FLOAT:
166 return std::to_string(float_value) + "[F]";
Chenjie Yua0f02242018-07-06 16:14:34 -0700167 case DOUBLE:
168 return std::to_string(double_value) + "[D]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800169 case STRING:
170 return str_value + "[S]";
Chenjie Yu12e5e672018-09-14 15:54:59 -0700171 case STORAGE:
172 return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
Yangster-macf5204922018-02-23 13:08:03 -0800173 default:
174 return "[UNKNOWN]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800175 }
176}
177
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700178bool Value::isZero() const {
179 switch (type) {
180 case INT:
181 return int_value == 0;
182 case LONG:
183 return long_value == 0;
184 case FLOAT:
185 return fabs(float_value) <= std::numeric_limits<float>::epsilon();
186 case DOUBLE:
187 return fabs(double_value) <= std::numeric_limits<double>::epsilon();
188 case STRING:
189 return str_value.size() == 0;
190 case STORAGE:
191 return storage_value.size() == 0;
192 default:
193 return false;
194 }
195}
196
Yao Chen8a8d16c2018-02-08 14:50:40 -0800197bool Value::operator==(const Value& that) const {
198 if (type != that.getType()) return false;
199
200 switch (type) {
201 case INT:
202 return int_value == that.int_value;
203 case LONG:
204 return long_value == that.long_value;
205 case FLOAT:
206 return float_value == that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700207 case DOUBLE:
208 return double_value == that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800209 case STRING:
210 return str_value == that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700211 case STORAGE:
212 return storage_value == that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800213 default:
214 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800215 }
216}
217
218bool Value::operator!=(const Value& that) const {
219 if (type != that.getType()) return true;
220 switch (type) {
221 case INT:
222 return int_value != that.int_value;
223 case LONG:
224 return long_value != that.long_value;
225 case FLOAT:
226 return float_value != that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700227 case DOUBLE:
228 return double_value != that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800229 case STRING:
230 return str_value != that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700231 case STORAGE:
232 return storage_value != that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800233 default:
234 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800235 }
236}
237
238bool Value::operator<(const Value& that) const {
239 if (type != that.getType()) return type < that.getType();
240
241 switch (type) {
242 case INT:
243 return int_value < that.int_value;
244 case LONG:
245 return long_value < that.long_value;
246 case FLOAT:
247 return float_value < that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700248 case DOUBLE:
249 return double_value < that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800250 case STRING:
251 return str_value < that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700252 case STORAGE:
253 return storage_value < that.storage_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800254 default:
255 return false;
256 }
257}
258
Chenjie Yua0f02242018-07-06 16:14:34 -0700259bool Value::operator>(const Value& that) const {
260 if (type != that.getType()) return type > that.getType();
261
262 switch (type) {
263 case INT:
264 return int_value > that.int_value;
265 case LONG:
266 return long_value > that.long_value;
267 case FLOAT:
268 return float_value > that.float_value;
269 case DOUBLE:
270 return double_value > that.double_value;
271 case STRING:
272 return str_value > that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700273 case STORAGE:
274 return storage_value > that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700275 default:
276 return false;
277 }
278}
279
280bool Value::operator>=(const Value& that) const {
281 if (type != that.getType()) return type >= that.getType();
282
283 switch (type) {
284 case INT:
285 return int_value >= that.int_value;
286 case LONG:
287 return long_value >= that.long_value;
288 case FLOAT:
289 return float_value >= that.float_value;
290 case DOUBLE:
291 return double_value >= that.double_value;
292 case STRING:
293 return str_value >= that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700294 case STORAGE:
295 return storage_value >= that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700296 default:
297 return false;
298 }
299}
300
301Value Value::operator-(const Value& that) const {
302 Value v;
303 if (type != that.type) {
304 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
305 return v;
306 }
307 if (type == STRING) {
308 ALOGE("Can't operate on string value type");
309 return v;
310 }
311
Chenjie Yu12e5e672018-09-14 15:54:59 -0700312 if (type == STORAGE) {
313 ALOGE("Can't operate on storage value type");
314 return v;
315 }
316
Chenjie Yua0f02242018-07-06 16:14:34 -0700317 switch (type) {
318 case INT:
319 v.setInt(int_value - that.int_value);
320 break;
321 case LONG:
322 v.setLong(long_value - that.long_value);
323 break;
324 case FLOAT:
325 v.setFloat(float_value - that.float_value);
326 break;
327 case DOUBLE:
328 v.setDouble(double_value - that.double_value);
329 break;
330 default:
331 break;
332 }
333 return v;
334}
335
336Value& Value::operator=(const Value& that) {
337 type = that.type;
338 switch (type) {
339 case INT:
340 int_value = that.int_value;
341 break;
342 case LONG:
343 long_value = that.long_value;
344 break;
345 case FLOAT:
346 float_value = that.float_value;
347 break;
348 case DOUBLE:
349 double_value = that.double_value;
350 break;
351 case STRING:
352 str_value = that.str_value;
353 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700354 case STORAGE:
355 storage_value = that.storage_value;
356 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700357 default:
358 break;
359 }
360 return *this;
361}
362
363Value& Value::operator+=(const Value& that) {
364 if (type != that.type) {
365 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
366 return *this;
367 }
368 if (type == STRING) {
369 ALOGE("Can't operate on string value type");
370 return *this;
371 }
Chenjie Yu12e5e672018-09-14 15:54:59 -0700372 if (type == STORAGE) {
373 ALOGE("Can't operate on storage value type");
374 return *this;
375 }
Chenjie Yua0f02242018-07-06 16:14:34 -0700376
377 switch (type) {
378 case INT:
379 int_value += that.int_value;
380 break;
381 case LONG:
382 long_value += that.long_value;
383 break;
384 case FLOAT:
385 float_value += that.float_value;
386 break;
387 case DOUBLE:
388 double_value += that.double_value;
389 break;
390 default:
391 break;
392 }
393 return *this;
394}
395
396double Value::getDouble() const {
397 switch (type) {
398 case INT:
399 return int_value;
400 case LONG:
401 return long_value;
402 case FLOAT:
403 return float_value;
404 case DOUBLE:
405 return double_value;
406 default:
407 return 0;
408 }
409}
410
Yangster13fb7e42018-03-07 17:30:49 -0800411bool equalDimensions(const std::vector<Matcher>& dimension_a,
412 const std::vector<Matcher>& dimension_b) {
413 bool eq = dimension_a.size() == dimension_b.size();
414 for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
415 if (dimension_b[i] != dimension_a[i]) {
416 eq = false;
417 }
418 }
419 return eq;
420}
421
422bool HasPositionANY(const FieldMatcher& matcher) {
423 if (matcher.has_position() && matcher.position() == Position::ANY) {
424 return true;
425 }
426 for (const auto& child : matcher.child()) {
427 if (HasPositionANY(child)) {
428 return true;
429 }
430 }
431 return false;
432}
433
Yangster-mac9def8e32018-04-17 13:55:51 -0700434bool HasPositionALL(const FieldMatcher& matcher) {
435 if (matcher.has_position() && matcher.position() == Position::ALL) {
436 return true;
437 }
438 for (const auto& child : matcher.child()) {
439 if (HasPositionALL(child)) {
440 return true;
441 }
442 }
443 return false;
444}
445
Yao Chen8a8d16c2018-02-08 14:50:40 -0800446} // namespace statsd
447} // namespace os
448} // namespace android