Home | History | Annotate | Download | only in src
      1 /*
      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 
     17 #pragma once
     18 
     19 #include <utils/JenkinsHash.h>
     20 #include <vector>
     21 #include "FieldValue.h"
     22 #include "android-base/stringprintf.h"
     23 #include "logd/LogEvent.h"
     24 
     25 namespace android {
     26 namespace os {
     27 namespace statsd {
     28 
     29 using android::base::StringPrintf;
     30 
     31 struct Metric2Condition {
     32     int64_t conditionId;
     33     std::vector<Matcher> metricFields;
     34     std::vector<Matcher> conditionFields;
     35 };
     36 
     37 class HashableDimensionKey {
     38 public:
     39     explicit HashableDimensionKey(const std::vector<FieldValue>& values) {
     40         mValues = values;
     41     }
     42 
     43     HashableDimensionKey() {};
     44 
     45     HashableDimensionKey(const HashableDimensionKey& that) : mValues(that.getValues()){};
     46 
     47     inline void addValue(const FieldValue& value) {
     48         mValues.push_back(value);
     49     }
     50 
     51     inline const std::vector<FieldValue>& getValues() const {
     52         return mValues;
     53     }
     54 
     55     inline std::vector<FieldValue>* mutableValues() {
     56         return &mValues;
     57     }
     58 
     59     inline FieldValue* mutableValue(size_t i) {
     60         if (i >= 0 && i < mValues.size()) {
     61             return &(mValues[i]);
     62         }
     63         return nullptr;
     64     }
     65 
     66     std::string toString() const;
     67 
     68     bool operator==(const HashableDimensionKey& that) const;
     69 
     70     bool operator<(const HashableDimensionKey& that) const;
     71 
     72     bool contains(const HashableDimensionKey& that) const;
     73 
     74 private:
     75     std::vector<FieldValue> mValues;
     76 };
     77 
     78 class MetricDimensionKey {
     79  public:
     80     explicit MetricDimensionKey(const HashableDimensionKey& dimensionKeyInWhat,
     81                                 const HashableDimensionKey& dimensionKeyInCondition)
     82         : mDimensionKeyInWhat(dimensionKeyInWhat),
     83           mDimensionKeyInCondition(dimensionKeyInCondition) {};
     84 
     85     MetricDimensionKey(){};
     86 
     87     MetricDimensionKey(const MetricDimensionKey& that)
     88         : mDimensionKeyInWhat(that.getDimensionKeyInWhat()),
     89           mDimensionKeyInCondition(that.getDimensionKeyInCondition()) {};
     90 
     91     MetricDimensionKey& operator=(const MetricDimensionKey& from) = default;
     92 
     93     std::string toString() const;
     94 
     95     inline const HashableDimensionKey& getDimensionKeyInWhat() const {
     96         return mDimensionKeyInWhat;
     97     }
     98 
     99     inline const HashableDimensionKey& getDimensionKeyInCondition() const {
    100         return mDimensionKeyInCondition;
    101     }
    102 
    103     inline void setDimensionKeyInCondition(const HashableDimensionKey& key) {
    104         mDimensionKeyInCondition = key;
    105     }
    106 
    107     bool hasDimensionKeyInCondition() const {
    108         return mDimensionKeyInCondition.getValues().size() > 0;
    109     }
    110 
    111     bool operator==(const MetricDimensionKey& that) const;
    112 
    113     bool operator<(const MetricDimensionKey& that) const;
    114 
    115   private:
    116       HashableDimensionKey mDimensionKeyInWhat;
    117       HashableDimensionKey mDimensionKeyInCondition;
    118 };
    119 
    120 android::hash_t hashDimension(const HashableDimensionKey& key);
    121 
    122 /**
    123  * Creating HashableDimensionKeys from FieldValues using matcher.
    124  *
    125  * This function may make modifications to the Field if the matcher has Position=FIRST,LAST or ALL
    126  * in it. This is because: for example, when we create dimension from last uid in attribution chain,
    127  * In one event, uid 1000 is at position 5 and it's the last
    128  * In another event, uid 1000 is at position 6, and it's the last
    129  * these 2 events should be mapped to the same dimension.  So we will remove the original position
    130  * from the dimension key for the uid field (by applying 0x80 bit mask).
    131  */
    132 bool filterValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values,
    133                   HashableDimensionKey* output);
    134 
    135 /**
    136  * Filter the values from FieldValues using the matchers.
    137  *
    138  * In contrast to the above function, this function will not do any modification to the original
    139  * data. Considering it as taking a snapshot on the atom event.
    140  */
    141 void filterGaugeValues(const std::vector<Matcher>& matchers, const std::vector<FieldValue>& values,
    142                        std::vector<FieldValue>* output);
    143 
    144 void getDimensionForCondition(const std::vector<FieldValue>& eventValues,
    145                               const Metric2Condition& links,
    146                               HashableDimensionKey* conditionDimension);
    147 
    148 }  // namespace statsd
    149 }  // namespace os
    150 }  // namespace android
    151 
    152 namespace std {
    153 
    154 using android::os::statsd::HashableDimensionKey;
    155 using android::os::statsd::MetricDimensionKey;
    156 
    157 template <>
    158 struct hash<HashableDimensionKey> {
    159     std::size_t operator()(const HashableDimensionKey& key) const {
    160         return hashDimension(key);
    161     }
    162 };
    163 
    164 template <>
    165 struct hash<MetricDimensionKey> {
    166     std::size_t operator()(const MetricDimensionKey& key) const {
    167         android::hash_t hash = hashDimension(key.getDimensionKeyInWhat());
    168         hash = android::JenkinsHashMix(hash, hashDimension(key.getDimensionKeyInCondition()));
    169         return android::JenkinsHashWhiten(hash);
    170     }
    171 };
    172 }  // namespace std