FieldValue.h revision 4c959cb99eb7e71e5417a61f5429c5fa0073e826
18a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/*
28a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Copyright (C) 2018 The Android Open Source Project
38a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
48a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Licensed under the Apache License, Version 2.0 (the "License");
58a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * you may not use this file except in compliance with the License.
68a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * You may obtain a copy of the License at
78a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
88a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *      http://www.apache.org/licenses/LICENSE-2.0
98a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Unless required by applicable law or agreed to in writing, software
118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * distributed under the License is distributed on an "AS IS" BASIS,
128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * See the License for the specific language governing permissions and
148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * limitations under the License.
158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen#pragma once
178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chennamespace android {
218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chennamespace os {
228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chennamespace statsd {
238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
248a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenclass HashableDimensionKey;
258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Matcher;
268a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Field;
278a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct FieldValue;
288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenconst int32_t kAttributionField = 1;
308a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenconst int32_t kMaxLogDepth = 2;
318a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenconst int32_t kLastBitMask = 0x80;
328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenconst int32_t kClearLastBitDeco = 0x7f;
338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenenum Type { INT, LONG, FLOAT, STRING };
358a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
364c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Chenint32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
384c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Chenint32_t encodeMatcherMask(int32_t mask[], int32_t depth);
398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen// Get the encoded field for a leaf with a [field] number at depth 0;
414c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Cheninline int32_t getSimpleField(size_t field) {
428a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    return ((int32_t)field << 8 * 2);
438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
458a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * proto.
478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [mTag]: the atom id.
488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [mField]: encoded path from the root (atom) to leaf.
498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * For example:
518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * WakeLockStateChanged {
528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    repeated AttributionNode = 1;
538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    int state = 2;
548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    string tag = 3;
558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * }
568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Read from logd, the items are structured as below:
578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * When we read through the list, we will encode each field in a 32bit integer.
608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * 8bit segments   |--------|--------|--------|--------|
618a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *                    Depth   field0 [L]field1 [L]field1
628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The following 3 8-bit are for the item's position at each level.
658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The first bit of each 8bits field is reserved to mark if the item is the last item at that level
668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  this is to make matching easier later.
678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The above wakelock event is translated into FieldValue pairs.
698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02010101->1000
708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02010182->tag
718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02018201->2000
728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02018282->tag2
738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x00020000->2
748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x00030000->"hello"
758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  This encoding is the building block for the later operations.
778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  Please see the definition for Matcher below to see how the matching is done.
788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Field {
808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenprivate:
818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    int32_t mTag;
828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    int32_t mField;
838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenpublic:
858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField = getEncodedField(pos, depth, true);
878a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
888a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void setField(int32_t field) {
958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField = field;
968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void setTag(int32_t tag) {
998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mTag = tag;
1008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void decorateLastPos(int32_t depth) {
1038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
1048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField |= mask;
1058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getTag() const {
1088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mTag;
1098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getDepth() const {
1128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (mField >> 24);
1138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPath(int32_t depth) const {
1168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (depth > 2 || depth < 0) return 0;
1178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = 0xffffffff;
1208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & (mask << 8 * (kMaxLogDepth - depth)));
1218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPrefix(int32_t depth) const {
1248a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (depth == 0) return 0;
1258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getPath(depth - 1);
1268a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1278a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getField() const {
1298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField;
1308a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1318a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getRawPosAtDepth(int32_t depth) const {
1338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t shift = 8 * (kMaxLogDepth - depth);
1358a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = 0xff << shift;
1368a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & mask) >> shift;
1388a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPosAtDepth(int32_t depth) const {
1418a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getRawPosAtDepth(depth) & kClearLastBitDeco;
1428a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // Check if the first bit of the 8-bit segment for depth is 1
1458a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isLastPos(int32_t depth) const {
1468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
1488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & mask) != 0;
1498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // if the 8-bit segment is all 0's
1528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isAnyPosMatcher(int32_t depth) const {
1538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
1548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // if the 8bit is 0x80 (1000 0000)
1568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isLastPosMatcher(int32_t depth) const {
1578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
1588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool operator==(const Field& that) const {
1618a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mTag == that.getTag() && mField == that.getField();
1628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    };
1638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool operator!=(const Field& that) const {
1658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mTag != that.getTag() || mField != that.getField();
1668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    };
1678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const Field& that) const {
1698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mTag != that.getTag()) {
1708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mTag < that.getTag();
1718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
1728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mField != that.getField()) {
1748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mField < that.getField();
1758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
1768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
1788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool matches(const Matcher& that) const;
1808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
1818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
1838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
1848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
1858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * It contains all information needed to match one or more leaf node.
1868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * All information is encoded in a Field(2 ints) and a bit mask(1 int).
1878a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
1888a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * For example, to match the first/any/last uid field in attribution chain in Atom 10,
1898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * we have the following FieldMatcher in statsd_config
1908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    FieldMatcher {
1918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *        field:10
1928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *         FieldMatcher {
1938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              field:1
1948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              position: any/last/first
1958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              FieldMatcher {
1968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *                  field:1
1978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              }
1988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *          }
1998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *     }
2008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * We translate the FieldMatcher into a Field, and mask
2028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * First: [Matcher Field] 0x02010101  [Mask]0xffff7fff
2038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Last:  [Matcher Field] 0x02018001  [Mask]0xffff80ff
2048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Any:   [Matcher Field] 0x02010001  [Mask]0xffff00ff
2058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
2078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
2088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * equal. Nothing can beat the performance of this matching algorithm.
2098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * TODO: ADD EXAMPLE HERE.
2118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
2128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Matcher {
2138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
2148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    const Field mMatcher;
2168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    const int32_t mMask;
2178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool hasAnyPositionMatcher(int* prefix) const {
2198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(2) == 0) {
2208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            (*prefix) = mMatcher.getPrefix(2);
2218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return true;
2228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
2238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
2248a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
2268a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2278a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
2288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * A wrapper for a union type to contain multiple types of values.
2298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2308a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
2318a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Value {
2328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(int32_t v) {
2338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int_value = v;
2348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = INT;
2358a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2368a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(int64_t v) {
2388a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        long_value = v;
2398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = LONG;
2408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2418a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2428a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(float v) {
2438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        float_value = v;
2448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = FLOAT;
2458a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(const std::string& v) {
2488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        str_value = v;
2498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = STRING;
2508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    void setInt(int32_t v) {
2538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int_value = v;
2548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = INT;
2558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    void setLong(int64_t v) {
2588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        long_value = v;
2598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = LONG;
2608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2618a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    union {
2638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t int_value;
2648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int64_t long_value;
2658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        float float_value;
2668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    };
2678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    std::string str_value;
2688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Type type;
2708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    std::string toString() const;
2728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Type getType() const {
2748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return type;
2758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(const Value& from);
2788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator==(const Value& that) const;
2808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator!=(const Value& that) const;
2818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const Value& that) const;
2838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenprivate:
2858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(){};
2868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
2878a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2888a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
2898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Represents a log item, or a dimension item (They are essentially the same).
2908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
2918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct FieldValue {
2928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
2938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator==(const FieldValue& that) const {
2958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField == that.mField && mValue == that.mValue;
2968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator!=(const FieldValue& that) const {
2988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField != that.mField || mValue != that.mValue;
2998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const FieldValue& that) const {
3018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mField != that.mField) {
3028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mField < that.mField;
3038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
3048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mValue != that.mValue) {
3068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mValue < that.mValue;
3078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
3088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
3108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field mField;
3138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value mValue;
3148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
3158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenbool isAttributionUidField(const FieldValue& value);
3178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenvoid translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
3198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenbool isAttributionUidField(const Field& field, const Value& value);
3218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace statsd
3228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace os
3238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace android
324