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;
33e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-macconst int32_t kClearAllPositionMatcherMask = 0xffff00ff;
348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
35f520492279ce5c0a029c36b5251031a66f1413fbYangster-macenum Type { UNKNOWN, INT, LONG, FLOAT, STRING };
368a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
374c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Chenint32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth);
388a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
394c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Chenint32_t encodeMatcherMask(int32_t mask[], int32_t depth);
408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
418a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen// Get the encoded field for a leaf with a [field] number at depth 0;
424c959cb99eb7e71e5417a61f5429c5fa0073e826Yao Cheninline int32_t getSimpleField(size_t field) {
438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    return ((int32_t)field << 8 * 2);
448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}
45580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen
468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom
488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * proto.
498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [mTag]: the atom id.
508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [mField]: encoded path from the root (atom) to leaf.
518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * For example:
538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * WakeLockStateChanged {
548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    repeated AttributionNode = 1;
558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    int state = 2;
568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    string tag = 3;
578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * }
588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Read from logd, the items are structured as below:
598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [[[1000, "tag"], [2000, "tag2"],], 2,"hello"]
608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
618a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * When we read through the list, we will encode each field in a 32bit integer.
628a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * 8bit segments   |--------|--------|--------|--------|
638a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *                    Depth   field0 [L]field1 [L]field1
648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The first 8 bits are the depth of the field. for example, the uid 1000 has depth 2.
668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The following 3 8-bit are for the item's position at each level.
678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The first bit of each 8bits field is reserved to mark if the item is the last item at that level
688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  this is to make matching easier later.
698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  The above wakelock event is translated into FieldValue pairs.
718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02010101->1000
728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02010182->tag
738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02018201->2000
748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x02018282->tag2
758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x00020000->2
768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  0x00030000->"hello"
778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  This encoding is the building block for the later operations.
798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *  Please see the definition for Matcher below to see how the matching is done.
808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Field {
828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenprivate:
838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    int32_t mTag;
848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    int32_t mField;
858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenpublic:
87f520492279ce5c0a029c36b5251031a66f1413fbYangster-mac    Field() {}
88f520492279ce5c0a029c36b5251031a66f1413fbYangster-mac
898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(int32_t tag, int32_t pos[], int32_t depth) : mTag(tag) {
908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField = getEncodedField(pos, depth, true);
918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(const Field& from) : mTag(from.getTag()), mField(from.getField()) {
948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field(int32_t tag, int32_t field) : mTag(tag), mField(field){};
978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void setField(int32_t field) {
998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField = field;
1008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void setTag(int32_t tag) {
1038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mTag = tag;
1048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline void decorateLastPos(int32_t depth) {
1078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
1088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        mField |= mask;
1098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getTag() const {
1128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mTag;
1138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getDepth() const {
1168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (mField >> 24);
1178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPath(int32_t depth) const {
1208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (depth > 2 || depth < 0) return 0;
1218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = 0xffffffff;
1248a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & (mask << 8 * (kMaxLogDepth - depth)));
1258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1268a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1278a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPrefix(int32_t depth) const {
1288a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (depth == 0) return 0;
1298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getPath(depth - 1);
1308a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1318a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getField() const {
1338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField;
1348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1358a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1368a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getRawPosAtDepth(int32_t depth) const {
1378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1388a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t shift = 8 * (kMaxLogDepth - depth);
1398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = 0xff << shift;
1408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1418a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & mask) >> shift;
1428a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline int32_t getPosAtDepth(int32_t depth) const {
1458a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getRawPosAtDepth(depth) & kClearLastBitDeco;
1468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // Check if the first bit of the 8-bit segment for depth is 1
1498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isLastPos(int32_t depth) const {
1508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t field = (mField & 0x00ffffff);
1518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t mask = kLastBitMask << 8 * (kMaxLogDepth - depth);
1528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return (field & mask) != 0;
1538a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1548a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1558a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // if the 8-bit segment is all 0's
1568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isAnyPosMatcher(int32_t depth) const {
1578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getDepth() >= depth && getRawPosAtDepth(depth) == 0;
1588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    // if the 8bit is 0x80 (1000 0000)
1608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    inline bool isLastPosMatcher(int32_t depth) const {
1618a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return getDepth() >= depth && getRawPosAtDepth(depth) == kLastBitMask;
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    inline bool operator!=(const Field& that) const {
1698a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mTag != that.getTag() || mField != that.getField();
1708a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    };
1718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const Field& that) const {
1738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mTag != that.getTag()) {
1748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mTag < that.getTag();
1758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
1768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mField != that.getField()) {
1788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mField < that.getField();
1798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
1808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
1828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
1838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool matches(const Matcher& that) const;
1848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
1858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
1868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
1878a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Matcher represents a leaf matcher in the FieldMatcher in statsd_config.
1888a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
1898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * It contains all information needed to match one or more leaf node.
1908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * All information is encoded in a Field(2 ints) and a bit mask(1 int).
1918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
1928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * For example, to match the first/any/last uid field in attribution chain in Atom 10,
1938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * we have the following FieldMatcher in statsd_config
1948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *    FieldMatcher {
1958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *        field:10
1968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *         FieldMatcher {
1978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              field:1
1988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              position: any/last/first
1998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              FieldMatcher {
2008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *                  field:1
2018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *              }
2028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *          }
2038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *     }
2048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * We translate the FieldMatcher into a Field, and mask
206580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen * First: [Matcher Field] 0x02010101  [Mask]0xff7f7f7f
207580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen * Last:  [Matcher Field] 0x02018001  [Mask]0xff7f807f
208580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen * Any:   [Matcher Field] 0x02010001  [Mask]0xff7f007f
209e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac * All:   [Matcher Field] 0x02010001  [Mask]0xff7f7f7f
2108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
2128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
2138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * equal. Nothing can beat the performance of this matching algorithm.
2148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * TODO: ADD EXAMPLE HERE.
2168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
2178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Matcher {
2188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
2198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    const Field mMatcher;
2218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    const int32_t mMask;
2228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
223539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    inline const Field& getMatcher() const {
224539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        return mMatcher;
225539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
226539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
227539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    inline int32_t getMask() const {
228539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        return mMask;
229539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    }
230539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
231e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    inline int32_t getRawMaskAtDepth(int32_t depth) const {
232e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        int32_t field = (mMask & 0x00ffffff);
233e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        int32_t shift = 8 * (kMaxLogDepth - depth);
234e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        int32_t mask = 0xff << shift;
235e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac
236e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        return (field & mask) >> shift;
237e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    }
238e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac
239e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    bool hasAllPositionMatcher() const {
240e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
241e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac    }
242e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac
2438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool hasAnyPositionMatcher(int* prefix) const {
244e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac        if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
245e06cfd777a501eca17f8dd796b32ad61002c5875Yangster-mac            (*prefix) = mMatcher.getPrefix(1);
2468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return true;
2478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
2488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
2498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
250539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac
251539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac    inline bool operator!=(const Matcher& that) const {
252539288806fe5ae3733ef7883eb8ec01cce293988Yangster-mac        return mMatcher != that.getMatcher() || mMask != that.getMask();
253580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen    }
254580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen
255580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen    inline bool operator==(const Matcher& that) const {
256580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen        return mMatcher == that.mMatcher && mMask == that.mMask;
257580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen    }
2588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
2598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
260580ea321b16c71ddec515553761d6f37359bd3a0Yao Cheninline Matcher getSimpleMatcher(int32_t tag, size_t field) {
261580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen    return Matcher(Field(tag, getSimpleField(field)), 0xff7f0000);
262580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen}
263580ea321b16c71ddec515553761d6f37359bd3a0Yao Chen
2648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
2658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * A wrapper for a union type to contain multiple types of values.
2668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen *
2678a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
2688a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct Value {
269f520492279ce5c0a029c36b5251031a66f1413fbYangster-mac    Value() : type(UNKNOWN) {}
270f520492279ce5c0a029c36b5251031a66f1413fbYangster-mac
2718a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(int32_t v) {
2728a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int_value = v;
2738a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = INT;
2748a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2758a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2768a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(int64_t v) {
2778a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        long_value = v;
2788a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = LONG;
2798a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2808a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2818a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(float v) {
2828a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        float_value = v;
2838a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = FLOAT;
2848a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2858a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2868a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(const std::string& v) {
2878a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        str_value = v;
2888a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = STRING;
2898a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2908a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2918a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    void setInt(int32_t v) {
2928a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int_value = v;
2938a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = INT;
2948a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
2958a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
2968a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    void setLong(int64_t v) {
2978a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        long_value = v;
2988a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        type = LONG;
2998a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3008a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3018a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    union {
3028a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int32_t int_value;
3038a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        int64_t long_value;
3048a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        float float_value;
3058a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    };
3068a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    std::string str_value;
3078a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3088a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Type type;
3098a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3108a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    std::string toString() const;
3118a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3128a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Type getType() const {
3138a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return type;
3148a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3158a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3168a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value(const Value& from);
3178a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3188a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator==(const Value& that) const;
3198a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator!=(const Value& that) const;
3208a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3218a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const Value& that) const;
3228a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
3238a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3248a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen/**
3258a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen * Represents a log item, or a dimension item (They are essentially the same).
3268a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen */
3278a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenstruct FieldValue {
328f520492279ce5c0a029c36b5251031a66f1413fbYangster-mac    FieldValue() {}
3298a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    FieldValue(const Field& field, const Value& value) : mField(field), mValue(value) {
3308a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3318a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator==(const FieldValue& that) const {
3328a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField == that.mField && mValue == that.mValue;
3338a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3348a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator!=(const FieldValue& that) const {
3358a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return mField != that.mField || mValue != that.mValue;
3368a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3378a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    bool operator<(const FieldValue& that) const {
3388a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mField != that.mField) {
3398a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mField < that.mField;
3408a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
3418a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3428a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        if (mValue != that.mValue) {
3438a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen            return mValue < that.mValue;
3448a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        }
3458a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3468a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen        return false;
3478a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    }
3488a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3498a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Field mField;
3508a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen    Value mValue;
3518a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen};
3528a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
35313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangsterbool HasPositionANY(const FieldMatcher& matcher);
3549def8e3995b1034d943a0fd22b6e512bfacdab77Yangster-macbool HasPositionALL(const FieldMatcher& matcher);
35513fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
3568a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenbool isAttributionUidField(const FieldValue& value);
3578a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3588a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenvoid translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
3598a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen
3608a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chenbool isAttributionUidField(const Field& field, const Value& value);
36113fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster
36213fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangsterbool equalDimensions(const std::vector<Matcher>& dimension_a,
36313fb7e4eeaf7aee408821afe7ee55a5167e49e59Yangster                     const std::vector<Matcher>& dimension_b);
3648a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace statsd
3658a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace os
3668a8d16ceea1e5b7a2f8c41e17b5d993035f50f5dYao Chen}  // namespace android
367