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

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

Merge "Partial config update: predicates"

parents 1be64f8a cc970146
Loading
Loading
Loading
Loading
+46 −2
Original line number Diff line number Diff line
@@ -25,8 +25,9 @@ namespace statsd {
using std::unordered_map;
using std::vector;

CombinationConditionTracker::CombinationConditionTracker(const int64_t& id, const int index)
    : ConditionTracker(id, index) {
CombinationConditionTracker::CombinationConditionTracker(const int64_t& id, const int index,
                                                         const uint64_t protoHash)
    : ConditionTracker(id, index, protoHash) {
    VLOG("creating CombinationConditionTracker %lld", (long long)mConditionId);
}

@@ -122,6 +123,49 @@ bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConf
    return true;
}

bool CombinationConditionTracker::onConfigUpdated(
        const vector<Predicate>& allConditionProtos, const int index,
        const vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
        const unordered_map<int64_t, int>& conditionTrackerMap) {
    ConditionTracker::onConfigUpdated(allConditionProtos, index, allConditionTrackers,
                                      atomMatchingTrackerMap, conditionTrackerMap);
    mTrackerIndex.clear();
    mChildren.clear();
    mUnSlicedChildren.clear();
    mSlicedChildren.clear();
    Predicate_Combination combinationCondition = allConditionProtos[mIndex].combination();

    for (const int64_t child : combinationCondition.predicate()) {
        const auto& it = conditionTrackerMap.find(child);

        if (it == conditionTrackerMap.end()) {
            ALOGW("Predicate %lld not found in the config", (long long)child);
            return false;
        }

        int childIndex = it->second;
        const sp<ConditionTracker>& childTracker = allConditionTrackers[childIndex];

        // Ensures that the child's tracker indices are updated.
        if (!childTracker->onConfigUpdated(allConditionProtos, childIndex, allConditionTrackers,
                                           atomMatchingTrackerMap, conditionTrackerMap)) {
            ALOGW("Child update failed %lld ", (long long)child);
            return false;
        }

        if (allConditionTrackers[childIndex]->isSliced()) {
            mSlicedChildren.push_back(childIndex);
        } else {
            mUnSlicedChildren.push_back(childIndex);
        }
        mChildren.push_back(childIndex);
        mTrackerIndex.insert(childTracker->getAtomMatchingTrackerIndex().begin(),
                             childTracker->getAtomMatchingTrackerIndex().end());
    }
    return true;
}

void CombinationConditionTracker::isConditionMet(
        const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions,
        const bool isPartialLink,
+8 −2
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ namespace android {
namespace os {
namespace statsd {

class CombinationConditionTracker : public virtual ConditionTracker {
class CombinationConditionTracker : public ConditionTracker {
public:
    CombinationConditionTracker(const int64_t& id, const int index);
    CombinationConditionTracker(const int64_t& id, const int index, const uint64_t protoHash);

    ~CombinationConditionTracker();

@@ -35,6 +35,11 @@ public:
              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
              std::vector<ConditionState>& conditionCache) override;

    bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
                         const std::vector<sp<ConditionTracker>>& allConditionTrackers,
                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
                         const std::unordered_map<int64_t, int>& conditionTrackerMap) override;

    void evaluateCondition(const LogEvent& event,
                           const std::vector<MatchingState>& eventMatcherValues,
                           const std::vector<sp<ConditionTracker>>& mAllConditions,
@@ -102,6 +107,7 @@ private:
    std::vector<int> mSlicedChildren;
    std::vector<int> mUnSlicedChildren;

    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
};

}  // namespace statsd
+35 −6
Original line number Diff line number Diff line
@@ -31,18 +31,17 @@ namespace statsd {

class ConditionTracker : public virtual RefBase {
public:
    ConditionTracker(const int64_t& id, const int index)
    ConditionTracker(const int64_t& id, const int index, const uint64_t protoHash)
        : mConditionId(id),
          mIndex(index),
          mInitialized(false),
          mTrackerIndex(),
          mUnSlicedPartCondition(ConditionState::kUnknown),
          mSliced(false){};
          mSliced(false),
          mProtoHash(protoHash){};

    virtual ~ConditionTracker(){};

    inline const int64_t& getId() { return mConditionId; }

    // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
    // be done in the constructor, but we do it separately because (1) easy to return a bool to
    // indicate whether the initialization is successful. (2) makes unit test easier.
@@ -50,7 +49,7 @@ public:
    // fill the condition cache with the current condition.
    // allConditionConfig: the list of all Predicate config from statsd_config.
    // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
    //                       need to call init() on children conditions)
    //                       need to call init() on child conditions)
    // conditionIdIndexMap: the mapping from condition id to its index.
    // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
    // conditionCache: tracks initial conditions of all ConditionTrackers. returns the
@@ -60,6 +59,26 @@ public:
                      const std::unordered_map<int64_t, int>& conditionIdIndexMap,
                      std::vector<bool>& stack, std::vector<ConditionState>& conditionCache) = 0;

    // Update appropriate state on config updates. Primarily, all indices need to be updated.
    // This predicate and all of its children are guaranteed to be preserved across the update.
    // This function is recursive and will call onConfigUpdated on child conditions. It does not
    // manage cycle detection since all preserved conditions should not have any cycles.
    //
    // allConditionProtos: the new predicates.
    // index: the new index of this tracker in allConditionProtos and allConditionTrackers.
    // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
    //                       need to call onConfigUpdated() on child conditions)
    // [atomMatchingTrackerMap]: map of atom matcher id to index after the config update
    // [conditionTrackerMap]: map of condition tracker id to index after the config update.
    // returns whether or not the update is successful
    virtual bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
                                 const std::vector<sp<ConditionTracker>>& allConditionTrackers,
                                 const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
                                 const std::unordered_map<int64_t, int>& conditionTrackerMap) {
        mIndex = index;
        return true;
    }

    // evaluate current condition given the new event.
    // event: the new log event
    // eventMatcherValues: the results of the AtomMatchingTrackers. AtomMatchingTrackers always
@@ -112,6 +131,10 @@ public:
        return mConditionId;
    }

    inline uint64_t getProtoHash() const {
        return mProtoHash;
    }

    virtual void getTrueSlicedDimensions(
        const std::vector<sp<ConditionTracker>>& allConditions,
        std::set<HashableDimensionKey>* dimensions) const = 0;
@@ -133,7 +156,7 @@ protected:
    const int64_t mConditionId;

    // the index of this condition in the manager's condition list.
    const int mIndex;
    int mIndex;

    // if it's properly initialized.
    bool mInitialized;
@@ -151,6 +174,12 @@ protected:
    ConditionState mUnSlicedPartCondition;

    bool mSliced;

    // Hash of the Predicate's proto bytes from StatsdConfig.
    // Used to determine if the definition of this condition has changed across a config update.
    const uint64_t mProtoHash;

    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
};

}  // namespace statsd
+59 −39
Original line number Diff line number Diff line
@@ -27,54 +27,21 @@ namespace statsd {
using std::unordered_map;

SimpleConditionTracker::SimpleConditionTracker(
        const ConfigKey& key, const int64_t& id, const int index,
        const ConfigKey& key, const int64_t& id, const uint64_t protoHash, const int index,
        const SimplePredicate& simplePredicate,
        const unordered_map<int64_t, int>& trackerNameIndexMap)
    : ConditionTracker(id, index), mConfigKey(key), mContainANYPositionInInternalDimensions(false) {
        const unordered_map<int64_t, int>& atomMatchingTrackerMap)
    : ConditionTracker(id, index, protoHash),
      mConfigKey(key),
      mContainANYPositionInInternalDimensions(false) {
    VLOG("creating SimpleConditionTracker %lld", (long long)mConditionId);
    mCountNesting = simplePredicate.count_nesting();

    if (simplePredicate.has_start()) {
        auto pair = trackerNameIndexMap.find(simplePredicate.start());
        if (pair == trackerNameIndexMap.end()) {
            ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
            return;
        }
        mStartLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStartLogMatcherIndex);
    } else {
        mStartLogMatcherIndex = -1;
    }

    if (simplePredicate.has_stop()) {
        auto pair = trackerNameIndexMap.find(simplePredicate.stop());
        if (pair == trackerNameIndexMap.end()) {
            ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
            return;
        }
        mStopLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStopLogMatcherIndex);
    } else {
        mStopLogMatcherIndex = -1;
    }

    if (simplePredicate.has_stop_all()) {
        auto pair = trackerNameIndexMap.find(simplePredicate.stop_all());
        if (pair == trackerNameIndexMap.end()) {
            ALOGW("Stop all matcher %lld found in the config", (long long)simplePredicate.stop_all());
            return;
        }
        mStopAllLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStopAllLogMatcherIndex);
    } else {
        mStopAllLogMatcherIndex = -1;
    }
    setMatcherIndices(simplePredicate, atomMatchingTrackerMap);

    if (simplePredicate.has_dimensions()) {
        translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions);
        if (mOutputDimensions.size() > 0) {
            mSliced = true;
            mDimensionTag = mOutputDimensions[0].mMatcher.getTag();
        }
        mContainANYPositionInInternalDimensions = HasPositionANY(simplePredicate.dimensions());
    }
@@ -106,6 +73,59 @@ bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
    return mInitialized;
}

bool SimpleConditionTracker::onConfigUpdated(
        const vector<Predicate>& allConditionProtos, const int index,
        const vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
        const unordered_map<int64_t, int>& conditionTrackerMap) {
    ConditionTracker::onConfigUpdated(allConditionProtos, index, allConditionTrackers,
                                      atomMatchingTrackerMap, conditionTrackerMap);
    setMatcherIndices(allConditionProtos[index].simple_predicate(), atomMatchingTrackerMap);
    return true;
}

void SimpleConditionTracker::setMatcherIndices(
        const SimplePredicate& simplePredicate,
        const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
    mTrackerIndex.clear();
    if (simplePredicate.has_start()) {
        auto pair = atomMatchingTrackerMap.find(simplePredicate.start());
        if (pair == atomMatchingTrackerMap.end()) {
            ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start());
            return;
        }
        mStartLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStartLogMatcherIndex);
    } else {
        mStartLogMatcherIndex = -1;
    }

    if (simplePredicate.has_stop()) {
        auto pair = atomMatchingTrackerMap.find(simplePredicate.stop());
        if (pair == atomMatchingTrackerMap.end()) {
            ALOGW("Stop matcher %lld not found in the config", (long long)simplePredicate.stop());
            return;
        }
        mStopLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStopLogMatcherIndex);
    } else {
        mStopLogMatcherIndex = -1;
    }

    if (simplePredicate.has_stop_all()) {
        auto pair = atomMatchingTrackerMap.find(simplePredicate.stop_all());
        if (pair == atomMatchingTrackerMap.end()) {
            ALOGW("Stop all matcher %lld found in the config",
                  (long long)simplePredicate.stop_all());
            return;
        }
        mStopAllLogMatcherIndex = pair->second;
        mTrackerIndex.insert(mStopAllLogMatcherIndex);
    } else {
        mStopAllLogMatcherIndex = -1;
    }
}

void SimpleConditionTracker::dumpState() {
    VLOG("%lld DUMP:", (long long)mConditionId);
    for (const auto& pair : mSlicedConditionState) {
+13 −6
Original line number Diff line number Diff line
@@ -27,11 +27,11 @@ namespace android {
namespace os {
namespace statsd {

class SimpleConditionTracker : public virtual ConditionTracker {
class SimpleConditionTracker : public ConditionTracker {
public:
    SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
                           const SimplePredicate& simplePredicate,
                           const std::unordered_map<int64_t, int>& trackerNameIndexMap);
    SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const uint64_t protoHash,
                           const int index, const SimplePredicate& simplePredicate,
                           const std::unordered_map<int64_t, int>& atomMatchingTrackerMap);

    ~SimpleConditionTracker();

@@ -40,6 +40,11 @@ public:
              const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
              std::vector<ConditionState>& conditionCache) override;

    bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
                         const std::vector<sp<ConditionTracker>>& allConditionTrackers,
                         const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
                         const std::unordered_map<int64_t, int>& conditionTrackerMap) override;

    void evaluateCondition(const LogEvent& event,
                           const std::vector<MatchingState>& eventMatcherValues,
                           const std::vector<sp<ConditionTracker>>& mAllConditions,
@@ -112,10 +117,11 @@ private:
    std::set<HashableDimensionKey> mLastChangedToTrueDimensions;
    std::set<HashableDimensionKey> mLastChangedToFalseDimensions;

    int mDimensionTag;

    std::map<HashableDimensionKey, int> mSlicedConditionState;

    void setMatcherIndices(const SimplePredicate& predicate,
                           const std::unordered_map<int64_t, int>& logTrackerMap);

    void handleStopAll(std::vector<ConditionState>& conditionCache,
                       std::vector<bool>& changedCache);

@@ -129,6 +135,7 @@ private:
    FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedCondition);
    FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim);
    FRIEND_TEST(SimpleConditionTrackerTest, TestStopAll);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
};

}  // namespace statsd
Loading