Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d644b24 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove the hacky HashableDimensionKey."

parents 64b9589f d5aa01b3
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ statsd_common_src := \
    src/storage/StorageManager.cpp \
    src/StatsLogProcessor.cpp \
    src/StatsService.cpp \
    src/stats_util.cpp \
    src/HashableDimensionKey.cpp \
    src/guardrail/MemoryLeakTrackUtil.cpp \
    src/guardrail/StatsdStats.cpp

@@ -174,7 +174,8 @@ LOCAL_SRC_FILES := \
    tests/metrics/EventMetricProducer_test.cpp \
    tests/metrics/ValueMetricProducer_test.cpp \
    tests/metrics/GaugeMetricProducer_test.cpp \
    tests/guardrail/StatsdStats_test.cpp
    tests/guardrail/StatsdStats_test.cpp \
    tests/metrics/metrics_test_helper.cpp

LOCAL_STATIC_LIBRARIES := \
    $(statsd_common_static_libraries) \
+110 −0
Original line number Diff line number Diff line
@@ -13,19 +13,17 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "stats_util.h"
#include "HashableDimensionKey.h"

namespace android {
namespace os {
namespace statsd {

// There is no existing hash function for the dimension key ("repeated KeyValuePair").
// Temporarily use a string concatenation as the hashable key.
// TODO: Find a better hash function for std::vector<KeyValuePair>.
HashableDimensionKey getHashableKey(std::vector<KeyValuePair> keys) {
    std::string flattened;
    for (const KeyValuePair& pair : keys) {
using std::string;

string HashableDimensionKey::toString() const {
    string flattened;
    for (const auto& pair : mKeyValuePairs) {
        flattened += std::to_string(pair.key());
        flattened += ":";
        switch (pair.value_case()) {
@@ -52,6 +50,61 @@ HashableDimensionKey getHashableKey(std::vector<KeyValuePair> keys) {
    return flattened;
}

bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
    const auto& keyValue2 = that.getKeyValuePairs();
    if (mKeyValuePairs.size() != keyValue2.size()) {
        return false;
    }

    for (size_t i = 0; i < keyValue2.size(); i++) {
        const auto& kv1 = mKeyValuePairs[i];
        const auto& kv2 = keyValue2[i];
        if (kv1.key() != kv2.key()) {
            return false;
        }

        if (kv1.value_case() != kv2.value_case()) {
            return false;
        }

        switch (kv1.value_case()) {
            case KeyValuePair::ValueCase::kValueStr:
                if (kv1.value_str() != kv2.value_str()) {
                    return false;
                }
                break;
            case KeyValuePair::ValueCase::kValueInt:
                if (kv1.value_int() != kv2.value_int()) {
                    return false;
                }
                break;
            case KeyValuePair::ValueCase::kValueLong:
                if (kv1.value_long() != kv2.value_long()) {
                    return false;
                }
                break;
            case KeyValuePair::ValueCase::kValueBool:
                if (kv1.value_bool() != kv2.value_bool()) {
                    return false;
                }
                break;
            case KeyValuePair::ValueCase::kValueFloat: {
                if (kv1.value_float() != kv2.value_float()) {
                    return false;
                }
                break;
            }
            case KeyValuePair::ValueCase::VALUE_NOT_SET:
                break;
        }
    }
    return true;
};

bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
    return toString().compare(that.toString()) < 0;
};

}  // namespace statsd
}  // namespace os
}  // namespace android
 No newline at end of file
+102 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <utils/JenkinsHash.h>
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"

namespace android {
namespace os {
namespace statsd {

class HashableDimensionKey {
public:
    explicit HashableDimensionKey(const std::vector<KeyValuePair>& keyValuePairs)
        : mKeyValuePairs(keyValuePairs){};

    HashableDimensionKey(){};

    HashableDimensionKey(const HashableDimensionKey& that)
        : mKeyValuePairs(that.getKeyValuePairs()){};

    HashableDimensionKey& operator=(const HashableDimensionKey& from) = default;

    std::string toString() const;

    inline const std::vector<KeyValuePair>& getKeyValuePairs() const {
        return mKeyValuePairs;
    }

    bool operator==(const HashableDimensionKey& that) const;

    bool operator<(const HashableDimensionKey& that) const;

    inline const char* c_str() const {
        return toString().c_str();
    }

private:
    std::vector<KeyValuePair> mKeyValuePairs;
};

}  // namespace statsd
}  // namespace os
}  // namespace android

namespace std {

using android::os::statsd::HashableDimensionKey;
using android::os::statsd::KeyValuePair;

template <>
struct hash<HashableDimensionKey> {
    std::size_t operator()(const HashableDimensionKey& key) const {
        android::hash_t hash = 0;
        for (const auto& pair : key.getKeyValuePairs()) {
            hash = android::JenkinsHashMix(hash, android::hash_type(pair.key()));
            hash = android::JenkinsHashMix(
                    hash, android::hash_type(static_cast<int32_t>(pair.value_case())));
            switch (pair.value_case()) {
                case KeyValuePair::ValueCase::kValueStr:
                    hash = android::JenkinsHashMix(
                            hash,
                            static_cast<uint32_t>(std::hash<std::string>()(pair.value_str())));
                    break;
                case KeyValuePair::ValueCase::kValueInt:
                    hash = android::JenkinsHashMix(hash, android::hash_type(pair.value_int()));
                    break;
                case KeyValuePair::ValueCase::kValueLong:
                    hash = android::JenkinsHashMix(
                            hash, android::hash_type(static_cast<int64_t>(pair.value_long())));
                    break;
                case KeyValuePair::ValueCase::kValueBool:
                    hash = android::JenkinsHashMix(hash, android::hash_type(pair.value_bool()));
                    break;
                case KeyValuePair::ValueCase::kValueFloat: {
                    float floatVal = pair.value_float();
                    hash = android::JenkinsHashMixBytes(hash, (uint8_t*)&floatVal, sizeof(float));
                    break;
                }
                case KeyValuePair::ValueCase::VALUE_NOT_SET:
                    break;
            }
        }
        return hash;
    }
};

}  // namespace std
+1 −1
Original line number Diff line number Diff line
@@ -279,7 +279,7 @@ void SimpleConditionTracker::evaluateCondition(const LogEvent& event,
    }

    // outputKey is the output key values. e.g, uid:1234
    const HashableDimensionKey outputKey = getHashableKey(getDimensionKey(event, mOutputDimension));
    const HashableDimensionKey outputKey(getDimensionKey(event, mOutputDimension));
    handleConditionEvent(outputKey, matchedState == 1, conditionCache, conditionChangedCache);
}

+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ HashableDimensionKey getDimensionKeyForCondition(const LogEvent& event,
        kv.set_key(link.key_in_condition(i).key());
    }

    return getHashableKey(dimensionKey);
    return HashableDimensionKey(dimensionKey);
}

}  // namespace statsd
Loading