• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "condition/condition_util.h"
20 #include "src/statsd_config.pb.h"
21 #include "matchers/AtomMatchingTracker.h"
22 #include "matchers/matcher_util.h"
23 
24 #include <utils/RefBase.h>
25 
26 #include <unordered_map>
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
32 class ConditionTracker : public virtual RefBase {
33 public:
ConditionTracker(const int64_t & id,const int index,const uint64_t protoHash)34     ConditionTracker(const int64_t& id, const int index, const uint64_t protoHash)
35         : mConditionId(id),
36           mIndex(index),
37           mInitialized(false),
38           mTrackerIndex(),
39           mUnSlicedPartCondition(ConditionState::kUnknown),
40           mSliced(false),
41           mProtoHash(protoHash){};
42 
~ConditionTracker()43     virtual ~ConditionTracker(){};
44 
45     // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
46     // be done in the constructor, but we do it separately because (1) easy to return a bool to
47     // indicate whether the initialization is successful. (2) makes unit test easier.
48     // This function can also be called on config updates, in which case it does nothing other than
49     // fill the condition cache with the current condition.
50     // allConditionConfig: the list of all Predicate config from statsd_config.
51     // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
52     //                       need to call init() on child conditions)
53     // conditionIdIndexMap: the mapping from condition id to its index.
54     // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
55     // conditionCache: tracks initial conditions of all ConditionTrackers. returns the
56     //                        current condition if called on a config update.
57     virtual bool init(const std::vector<Predicate>& allConditionConfig,
58                       const std::vector<sp<ConditionTracker>>& allConditionTrackers,
59                       const std::unordered_map<int64_t, int>& conditionIdIndexMap,
60                       std::vector<bool>& stack, std::vector<ConditionState>& conditionCache) = 0;
61 
62     // Update appropriate state on config updates. Primarily, all indices need to be updated.
63     // This predicate and all of its children are guaranteed to be preserved across the update.
64     // This function is recursive and will call onConfigUpdated on child conditions. It does not
65     // manage cycle detection since all preserved conditions should not have any cycles.
66     //
67     // allConditionProtos: the new predicates.
68     // index: the new index of this tracker in allConditionProtos and allConditionTrackers.
69     // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
70     //                       need to call onConfigUpdated() on child conditions)
71     // atomMatchingTrackerMap: map of atom matcher id to index after the config update.
72     // conditionTrackerMap: map of condition tracker id to index after the config update.
73     // returns whether or not the update is successful.
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)74     virtual bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
75                                  const std::vector<sp<ConditionTracker>>& allConditionTrackers,
76                                  const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
77                                  const std::unordered_map<int64_t, int>& conditionTrackerMap) {
78         mIndex = index;
79         return true;
80     }
81 
82     // evaluate current condition given the new event.
83     // event: the new log event
84     // eventMatcherValues: the results of the AtomMatchingTrackers. AtomMatchingTrackers always
85     //                     process event before ConditionTrackers, because ConditionTracker depends
86     //                     on AtomMatchingTrackers.
87     // mAllConditions: the list of all ConditionTracker
88     // conditionCache: the cached non-sliced condition of the ConditionTrackers for this new event.
89     // conditionChanged: the bit map to record whether the condition has changed.
90     //                   If the condition has dimension, then any sub condition changes will report
91     //                   conditionChanged.
92     virtual void evaluateCondition(const LogEvent& event,
93                                    const std::vector<MatchingState>& eventMatcherValues,
94                                    const std::vector<sp<ConditionTracker>>& mAllConditions,
95                                    std::vector<ConditionState>& conditionCache,
96                                    std::vector<bool>& conditionChanged) = 0;
97 
98     // Query the condition with parameters.
99     // [conditionParameters]: a map from condition name to the HashableDimensionKey to query the
100     //                       condition.
101     // [allConditions]: all condition trackers. This is needed because the condition evaluation is
102     //                  done recursively
103     // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
104     //                  in the condition tracker output dimension.
105     // [conditionCache]: the cache holding the condition evaluation values.
106     virtual void isConditionMet(
107             const ConditionKey& conditionParameters,
108             const std::vector<sp<ConditionTracker>>& allConditions,
109             const bool isPartialLink,
110             std::vector<ConditionState>& conditionCache) const = 0;
111 
112     // return the list of AtomMatchingTracker index that this ConditionTracker uses.
getAtomMatchingTrackerIndex()113     virtual const std::set<int>& getAtomMatchingTrackerIndex() const {
114         return mTrackerIndex;
115     }
116 
setSliced(bool sliced)117     virtual void setSliced(bool sliced) {
118         mSliced = mSliced | sliced;
119     }
120 
isSliced()121     inline bool isSliced() const {
122         return mSliced;
123     }
124 
125     virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
126             const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
127     virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
128             const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
129 
getConditionId()130     inline int64_t getConditionId() const {
131         return mConditionId;
132     }
133 
getProtoHash()134     inline uint64_t getProtoHash() const {
135         return mProtoHash;
136     }
137 
138     virtual const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
139             const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
140 
141     virtual bool IsChangedDimensionTrackable() const = 0;
142 
143     virtual bool IsSimpleCondition() const = 0;
144 
145     virtual bool equalOutputDimensions(
146         const std::vector<sp<ConditionTracker>>& allConditions,
147         const vector<Matcher>& dimensions) const = 0;
148 
149     // Return the current condition state of the unsliced part of the condition.
getUnSlicedPartConditionState()150     inline ConditionState getUnSlicedPartConditionState() const  {
151         return mUnSlicedPartCondition;
152     }
153 
154 protected:
155     const int64_t mConditionId;
156 
157     // the index of this condition in the manager's condition list.
158     int mIndex;
159 
160     // if it's properly initialized.
161     bool mInitialized;
162 
163     // the list of AtomMatchingTracker index that this ConditionTracker uses.
164     std::set<int> mTrackerIndex;
165 
166     // This variable is only used for CombinationConditionTrackers.
167     // SimpleConditionTrackers technically don't have an unsliced part because
168     // they are either sliced or unsliced.
169     //
170     // CombinationConditionTrackers have multiple children ConditionTrackers
171     // that can be a mixture of sliced or unsliced. This tracks the
172     // condition of the unsliced part of the combination condition.
173     ConditionState mUnSlicedPartCondition;
174 
175     bool mSliced;
176 
177     // Hash of the Predicate's proto bytes from StatsdConfig.
178     // Used to determine if the definition of this condition has changed across a config update.
179     const uint64_t mProtoHash;
180 
181     FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
182 };
183 
184 }  // namespace statsd
185 }  // namespace os
186 }  // namespace android
187