Pass initial conditions to combination conditions and metrics
SimplePredicates have a configurable initial value that can be set to
unknown or false. Previously, CombinationPredicates and MetricProducers
were automatically initialized with an unknown condition value instead
of being synced with the conditions of the SimplePredicates that they
rely on.
An initial condition cache is used to store initial conditions of
ConditionTrackers after they are initialized.
CombinationConditionTrackers evaluate their initial condition based on
the initial conditions of their child SimpleConditionTrackers.
MetricProducers also use the initial condition cache to set its
condition during initialization.
Added unit tests in SimpleConditionTracker_test to check that
SimpleConditionTrackers have the correct initial conditions based on
what the InitialValue is set to and the condition is updated properly
after the first few condition change events.
Added unit test in MetricsManager_test to check that all
ConditionTrackers and MetricProducers have the correct initial
conditions.
Test: m statsd_test && adb sync data && adb shell
data/nativetest64/statsd_test/statsd_test64
Bug: b/156762672
Change-Id: I9f6088f8c92fb18eb2ca8632aaa338fb0ed8e679
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index c829ccd..e9875ba 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -37,7 +37,8 @@
bool CombinationConditionTracker::init(const vector<Predicate>& allConditionConfig,
const vector<sp<ConditionTracker>>& allConditionTrackers,
const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack) {
+ vector<bool>& stack,
+ vector<ConditionState>& initialConditionCache) {
VLOG("Combination predicate init() %lld", (long long)mConditionId);
if (mInitialized) {
return true;
@@ -73,9 +74,9 @@
return false;
}
-
- bool initChildSucceeded = childTracker->init(allConditionConfig, allConditionTrackers,
- conditionIdIndexMap, stack);
+ bool initChildSucceeded =
+ childTracker->init(allConditionConfig, allConditionTrackers, conditionIdIndexMap,
+ stack, initialConditionCache);
if (!initChildSucceeded) {
ALOGW("Child initialization failed %lld ", (long long)child);
@@ -95,6 +96,11 @@
childTracker->getLogTrackerIndex().end());
}
+ mUnSlicedPartCondition = evaluateCombinationCondition(mUnSlicedChildren, mLogicalOperation,
+ initialConditionCache);
+ initialConditionCache[mIndex] =
+ evaluateCombinationCondition(mChildren, mLogicalOperation, initialConditionCache);
+
// unmark this node in the recursion stack.
stack[mIndex] = false;
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.h b/cmds/statsd/src/condition/CombinationConditionTracker.h
index e3d8601..39ff0ab 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.h
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.h
@@ -32,8 +32,8 @@
bool init(const std::vector<Predicate>& allConditionConfig,
const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap,
- std::vector<bool>& stack) override;
+ const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
+ std::vector<ConditionState>& initialConditionCache) override;
void evaluateCondition(const LogEvent& event,
const std::vector<MatchingState>& eventMatcherValues,
diff --git a/cmds/statsd/src/condition/ConditionTracker.h b/cmds/statsd/src/condition/ConditionTracker.h
index f9a2c34..62736c8 100644
--- a/cmds/statsd/src/condition/ConditionTracker.h
+++ b/cmds/statsd/src/condition/ConditionTracker.h
@@ -51,10 +51,12 @@
// need to call init() on children 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.
+ // initialConditionCache: tracks initial conditions of all ConditionTrackers.
virtual bool init(const std::vector<Predicate>& allConditionConfig,
const std::vector<sp<ConditionTracker>>& allConditionTrackers,
const std::unordered_map<int64_t, int>& conditionIdIndexMap,
- std::vector<bool>& stack) = 0;
+ std::vector<bool>& stack,
+ std::vector<ConditionState>& initialConditionCache) = 0;
// evaluate current condition given the new event.
// event: the new log event
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index f23ec50..efb4d49 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -95,9 +95,11 @@
bool SimpleConditionTracker::init(const vector<Predicate>& allConditionConfig,
const vector<sp<ConditionTracker>>& allConditionTrackers,
const unordered_map<int64_t, int>& conditionIdIndexMap,
- vector<bool>& stack) {
+ vector<bool>& stack,
+ vector<ConditionState>& initialConditionCache) {
// SimpleConditionTracker does not have dependency on other conditions, thus we just return
// if the initialization was successful.
+ initialConditionCache[mIndex] = mInitialValue;
return mInitialized;
}
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.h b/cmds/statsd/src/condition/SimpleConditionTracker.h
index 5c5cc56..ea7f87b 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.h
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.h
@@ -37,8 +37,8 @@
bool init(const std::vector<Predicate>& allConditionConfig,
const std::vector<sp<ConditionTracker>>& allConditionTrackers,
- const std::unordered_map<int64_t, int>& conditionIdIndexMap,
- std::vector<bool>& stack) override;
+ const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
+ std::vector<ConditionState>& initialConditionCache) override;
void evaluateCondition(const LogEvent& event,
const std::vector<MatchingState>& eventMatcherValues,