Cpu usage optimization:
1/ Avoid unnecessary field/dimension proto construction.
2/ use unordered_map for slicing.
3/ Use dimension fields to compare dimension keys.
Test: all statsd tests passed.
Change-Id: I2f74f78589b7f6ecd0803a2ead822b8d0399f334
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 288ebe9..857a6dd 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -69,18 +69,17 @@
using std::string;
-
string HashableDimensionKey::toString() const {
string flattened;
DimensionsValueToString(getDimensionsValue(), &flattened);
return flattened;
}
-bool compareDimensionsValue(const DimensionsValue& s1, const DimensionsValue& s2) {
+bool EqualsTo(const DimensionsValue& s1, const DimensionsValue& s2) {
if (s1.field() != s2.field()) {
return false;
}
- if (s1.value_case() != s1.value_case()) {
+ if (s1.value_case() != s2.value_case()) {
return false;
}
switch (s1.value_case()) {
@@ -102,8 +101,8 @@
}
bool allMatched = true;
for (int i = 0; allMatched && i < s1.value_tuple().dimensions_value_size(); ++i) {
- allMatched &= compareDimensionsValue(s1.value_tuple().dimensions_value(i),
- s2.value_tuple().dimensions_value(i));
+ allMatched &= EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
}
return allMatched;
}
@@ -113,12 +112,54 @@
}
}
+bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
+ if (s1.field() != s2.field()) {
+ return s1.field() < s2.field();
+ }
+ if (s1.value_case() != s2.value_case()) {
+ return s1.value_case() < s2.value_case();
+ }
+ switch (s1.value_case()) {
+ case DimensionsValue::ValueCase::kValueStr:
+ return s1.value_str() < s2.value_str();
+ case DimensionsValue::ValueCase::kValueInt:
+ return s1.value_int() < s2.value_int();
+ case DimensionsValue::ValueCase::kValueLong:
+ return s1.value_long() < s2.value_long();
+ case DimensionsValue::ValueCase::kValueBool:
+ return (int)s1.value_bool() < (int)s2.value_bool();
+ case DimensionsValue::ValueCase::kValueFloat:
+ return s1.value_float() < s2.value_float();
+ case DimensionsValue::ValueCase::kValueTuple:
+ {
+ if (s1.value_tuple().dimensions_value_size() !=
+ s2.value_tuple().dimensions_value_size()) {
+ return s1.value_tuple().dimensions_value_size() <
+ s2.value_tuple().dimensions_value_size();
+ }
+ for (int i = 0; i < s1.value_tuple().dimensions_value_size(); ++i) {
+ if (EqualsTo(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i))) {
+ continue;
+ } else {
+ return LessThan(s1.value_tuple().dimensions_value(i),
+ s2.value_tuple().dimensions_value(i));
+ }
+ }
+ return false;
+ }
+ case DimensionsValue::ValueCase::VALUE_NOT_SET:
+ default:
+ return false;
+ }
+}
+
bool HashableDimensionKey::operator==(const HashableDimensionKey& that) const {
- return compareDimensionsValue(getDimensionsValue(), that.getDimensionsValue());
+ return EqualsTo(getDimensionsValue(), that.getDimensionsValue());
};
bool HashableDimensionKey::operator<(const HashableDimensionKey& that) const {
- return toString().compare(that.toString()) < 0;
+ return LessThan(getDimensionsValue(), that.getDimensionsValue());
};
} // namespace statsd
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index edc9f2c..90639b4 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -91,23 +91,22 @@
}
void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- std::vector<Field> uidFields;
+ std::set<Field, FieldCmp> uidFields;
if (android::util::kAtomsWithAttributionChain.find(event->GetTagId()) !=
android::util::kAtomsWithAttributionChain.end()) {
- findFields(
- event->getFieldValueMap(),
- buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY),
- &uidFields);
+ FieldMatcher matcher;
+ buildAttributionUidFieldMatcher(event->GetTagId(), Position::ANY, &matcher);
+ findFields(event->getFieldValueMap(), matcher, &uidFields);
} else if (android::util::kAtomsWithUidField.find(event->GetTagId()) !=
android::util::kAtomsWithUidField.end()) {
- findFields(
- event->getFieldValueMap(),
- buildSimpleAtomFieldMatcher(event->GetTagId(), 1 /* uid is always the 1st field. */),
- &uidFields);
+ FieldMatcher matcher;
+ buildSimpleAtomFieldMatcher(
+ event->GetTagId(), 1 /* uid is always the 1st field. */, &matcher);
+ findFields(event->getFieldValueMap(), matcher, &uidFields);
}
- for (size_t i = 0; i < uidFields.size(); ++i) {
- DimensionsValue* value = event->findFieldValueOrNull(uidFields[i]);
+ for (const auto& uidField : uidFields) {
+ DimensionsValue* value = event->findFieldValueOrNull(uidField);
if (value != nullptr && value->value_case() == DimensionsValue::ValueCase::kValueInt) {
const int uid = mUidMap->getHostUidOrSelf(value->value_int());
value->set_value_int(uid);
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 7a1bb0c..5cfc349 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -289,7 +289,8 @@
}
// outputKey is the output values. e.g, uid:1234
- const std::vector<DimensionsValue> outputValues = getDimensionKeys(event, mOutputDimensions);
+ std::vector<DimensionsValue> outputValues;
+ getDimensionKeys(event, mOutputDimensions, &outputValues);
if (outputValues.size() == 0) {
// The original implementation would generate an empty string dimension hash when condition
// is not sliced.
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
index ddfb8d1..3b2d480 100644
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ b/cmds/statsd/src/condition/condition_util.cpp
@@ -116,28 +116,30 @@
}
}
-void getFieldsFromFieldMatcher(const FieldMatcher& matcher, const Field& parentField,
- std::vector<Field> *allFields) {
- Field newParent = parentField;
- Field* leaf = getSingleLeaf(&newParent);
- leaf->set_field(matcher.field());
+void getFieldsFromFieldMatcher(const FieldMatcher& matcher, Field* rootField, Field* leafField,
+ std::vector<Field> *allFields) {
if (matcher.child_size() == 0) {
- allFields->push_back(newParent);
+ allFields->push_back(*rootField);
return;
}
for (int i = 0; i < matcher.child_size(); ++i) {
- leaf->add_child();
- getFieldsFromFieldMatcher(matcher.child(i), newParent, allFields);
+ Field* newLeafField = leafField->add_child();
+ newLeafField->set_field(matcher.child(i).field());
+ getFieldsFromFieldMatcher(matcher.child(i), rootField, newLeafField, allFields);
}
}
void getFieldsFromFieldMatcher(const FieldMatcher& matcher, std::vector<Field> *allFields) {
- Field parentField;
- getFieldsFromFieldMatcher(matcher, parentField, allFields);
+ if (!matcher.has_field()) {
+ return;
+ }
+ Field rootField;
+ rootField.set_field(matcher.field());
+ getFieldsFromFieldMatcher(matcher, &rootField, &rootField, allFields);
}
void flattenValueLeaves(const DimensionsValue& value,
- std::vector<DimensionsValue> *allLaves) {
+ std::vector<const DimensionsValue*> *allLaves) {
switch (value.value_case()) {
case DimensionsValue::ValueCase::kValueStr:
case DimensionsValue::ValueCase::kValueInt:
@@ -145,7 +147,7 @@
case DimensionsValue::ValueCase::kValueBool:
case DimensionsValue::ValueCase::kValueFloat:
case DimensionsValue::ValueCase::VALUE_NOT_SET:
- allLaves->push_back(value);
+ allLaves->push_back(&value);
break;
case DimensionsValue::ValueCase::kValueTuple:
for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
@@ -155,45 +157,44 @@
}
}
-std::vector<HashableDimensionKey> getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link) {
+void getDimensionKeysForCondition(
+ const LogEvent& event, const MetricConditionLink& link,
+ std::vector<HashableDimensionKey> *hashableDimensionKeys) {
std::vector<Field> whatFields;
getFieldsFromFieldMatcher(link.fields_in_what(), &whatFields);
std::vector<Field> conditionFields;
getFieldsFromFieldMatcher(link.fields_in_condition(), &conditionFields);
- std::vector<HashableDimensionKey> hashableDimensionKeys;
-
// TODO(yanglu): here we could simplify the logic to get the leaf value node in what and
// directly construct the full condition value tree.
- std::vector<DimensionsValue> whatValues = getDimensionKeys(event, link.fields_in_what());
+ std::vector<DimensionsValue> whatValues;
+ getDimensionKeys(event, link.fields_in_what(), &whatValues);
for (size_t i = 0; i < whatValues.size(); ++i) {
- std::vector<DimensionsValue> whatLeaves;
+ std::vector<const DimensionsValue*> whatLeaves;
flattenValueLeaves(whatValues[i], &whatLeaves);
if (whatLeaves.size() != whatFields.size() ||
whatLeaves.size() != conditionFields.size()) {
ALOGE("Dimensions between what and condition not equal.");
- return hashableDimensionKeys;
+ return;
}
FieldValueMap conditionValueMap;
for (size_t j = 0; j < whatLeaves.size(); ++j) {
- if (!setFieldInLeafValueProto(conditionFields[j], &whatLeaves[j])) {
+ DimensionsValue* conditionValue = &conditionValueMap[conditionFields[j]];
+ *conditionValue = *whatLeaves[i];
+ if (!setFieldInLeafValueProto(conditionFields[j], conditionValue)) {
ALOGE("Not able to reset the field for condition leaf value.");
- return hashableDimensionKeys;
+ return;
}
- conditionValueMap.insert(std::make_pair(conditionFields[j], whatLeaves[j]));
}
- std::vector<DimensionsValue> conditionValues;
- findDimensionsValues(conditionValueMap, link.fields_in_condition(), &conditionValues);
- if (conditionValues.size() != 1) {
+ std::vector<DimensionsValue> conditionValueTrees;
+ findDimensionsValues(conditionValueMap, link.fields_in_condition(), &conditionValueTrees);
+ if (conditionValueTrees.size() != 1) {
ALOGE("Not able to find unambiguous field value in condition atom.");
continue;
}
- hashableDimensionKeys.push_back(HashableDimensionKey(conditionValues[0]));
+ hashableDimensionKeys->push_back(HashableDimensionKey(conditionValueTrees[0]));
}
-
- return hashableDimensionKeys;
}
} // namespace statsd
diff --git a/cmds/statsd/src/condition/condition_util.h b/cmds/statsd/src/condition/condition_util.h
index 598027b..a7288be 100644
--- a/cmds/statsd/src/condition/condition_util.h
+++ b/cmds/statsd/src/condition/condition_util.h
@@ -40,8 +40,9 @@
const LogicalOperation& operation,
const std::vector<ConditionState>& conditionCache);
-std::vector<HashableDimensionKey> getDimensionKeysForCondition(
- const LogEvent& event, const MetricConditionLink& link);
+void getDimensionKeysForCondition(
+ const LogEvent& event, const MetricConditionLink& link,
+ std::vector<HashableDimensionKey> *dimensionKeys);
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/dimension.cpp b/cmds/statsd/src/dimension.cpp
index bb7a044..04445ca 100644
--- a/cmds/statsd/src/dimension.cpp
+++ b/cmds/statsd/src/dimension.cpp
@@ -38,7 +38,7 @@
return *leafValue;
}
-void appendLeafNodeToParent(const Field& field,
+void appendLeafNodeToTree(const Field& field,
const DimensionsValue& value,
DimensionsValue* parentValue) {
if (field.child_size() <= 0) {
@@ -58,24 +58,24 @@
parentValue->mutable_value_tuple()->add_dimensions_value();
idx = parentValue->mutable_value_tuple()->dimensions_value_size() - 1;
}
- appendLeafNodeToParent(
+ appendLeafNodeToTree(
field.child(0), value,
parentValue->mutable_value_tuple()->mutable_dimensions_value(idx));
}
-void addNodeToRootDimensionsValues(const Field& field,
- const DimensionsValue& node,
- std::vector<DimensionsValue>* rootValues) {
- if (rootValues == nullptr) {
+void appendLeafNodeToTrees(const Field& field,
+ const DimensionsValue& node,
+ std::vector<DimensionsValue>* rootTrees) {
+ if (rootTrees == nullptr) {
return;
}
- if (rootValues->empty()) {
- DimensionsValue rootValue;
- appendLeafNodeToParent(field, node, &rootValue);
- rootValues->push_back(rootValue);
+ if (rootTrees->empty()) {
+ DimensionsValue tree;
+ appendLeafNodeToTree(field, node, &tree);
+ rootTrees->push_back(tree);
} else {
- for (size_t i = 0; i < rootValues->size(); ++i) {
- appendLeafNodeToParent(field, node, &rootValues->at(i));
+ for (size_t i = 0; i < rootTrees->size(); ++i) {
+ appendLeafNodeToTree(field, node, &rootTrees->at(i));
}
}
}
@@ -85,22 +85,25 @@
void findDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootDimensionsValues);
void findNonRepeatedDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootValues) {
if (matcher.child_size() > 0) {
+ Field* newLeafField = leafField->add_child();
for (const auto& childMatcher : matcher.child()) {
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- findDimensionsValues(fieldValueMap, childMatcher, childField, rootValues);
+ newLeafField->set_field(childMatcher.field());
+ findDimensionsValues(fieldValueMap, childMatcher, rootField, newLeafField, rootValues);
}
+ leafField->clear_child();
} else {
- auto ret = fieldValueMap.equal_range(field);
+ auto ret = fieldValueMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -113,40 +116,43 @@
ALOGE("Found multiple values for optional field.");
return;
}
- addNodeToRootDimensionsValues(field, ret.first->second, rootValues);
+ appendLeafNodeToTrees(*rootField, ret.first->second, rootValues);
}
}
void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootValues) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, first_field, rootValues);
+ leafField->set_position_index(0);
+ findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField, rootValues);
+ leafField->clear_position_index();
} else {
- auto itLower = fieldValueMap.lower_bound(field);
+ auto itLower = fieldValueMap.lower_bound(*rootField);
if (itLower == fieldValueMap.end()) {
return;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldValueMap.lower_bound(next_field);
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldValueMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
switch (matcher.position()) {
case Position::LAST:
{
itUpper--;
if (itUpper != fieldValueMap.end()) {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return;
}
- setPositionForLeaf(&last_field, last_index);
+ leafField->set_position_index(last_index);
findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, last_field, rootValues);
+ fieldValueMap, matcher, rootField, leafField, rootValues);
+ leafField->clear_position_index();
}
}
break;
@@ -154,20 +160,20 @@
{
std::set<int> indexes;
for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
+ int index = getPositionByReferenceField(*rootField, it->first);
if (index >= 0) {
indexes.insert(index);
}
}
if (!indexes.empty()) {
- Field any_field = field;
std::vector<DimensionsValue> allValues;
for (const int index : indexes) {
- setPositionForLeaf(&any_field, index);
+ leafField->set_position_index(index);
std::vector<DimensionsValue> newValues = *rootValues;
findNonRepeatedDimensionsValues(
- fieldValueMap, matcher, any_field, &newValues);
+ fieldValueMap, matcher, rootField, leafField, &newValues);
allValues.insert(allValues.end(), newValues.begin(), newValues.end());
+ leafField->clear_position_index();
}
rootValues->clear();
rootValues->insert(rootValues->end(), allValues.begin(), allValues.end());
@@ -183,12 +189,15 @@
void findDimensionsValues(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
+ Field* rootField,
+ Field* leafField,
std::vector<DimensionsValue>* rootDimensionsValues) {
if (!matcher.has_position()) {
- findNonRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
+ findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
+ rootDimensionsValues);
} else {
- findRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
+ findRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
+ rootDimensionsValues);
}
}
@@ -198,56 +207,49 @@
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
std::vector<DimensionsValue>* rootDimensionsValues) {
- findDimensionsValues(fieldValueMap, matcher,
- buildSimpleAtomField(matcher.field()), rootDimensionsValues);
+ Field rootField;
+ buildSimpleAtomField(matcher.field(), &rootField);
+ findDimensionsValues(fieldValueMap, matcher, &rootField, &rootField, rootDimensionsValues);
}
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- return matcher;
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
}
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- matcher.add_child()->set_field(atomFieldNum);
- return matcher;
+void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ matcher->add_child()->set_field(fieldNum);
}
constexpr int ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
-FieldMatcher buildAttributionUidFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- auto child = matcher.add_child();
+void buildAttributionUidFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ auto child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
-FieldMatcher buildAttributionTagFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- FieldMatcher* child = matcher.add_child();
+void buildAttributionTagFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ FieldMatcher* child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
-FieldMatcher buildAttributionFieldMatcher(const int tagId, const Position position) {
- FieldMatcher matcher;
- matcher.set_field(tagId);
- FieldMatcher* child = matcher.add_child();
+void buildAttributionFieldMatcher(const int tagId, const Position position, FieldMatcher* matcher) {
+ matcher->set_field(tagId);
+ FieldMatcher* child = matcher->add_child();
child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
child->set_position(position);
child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
- return matcher;
}
void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
@@ -284,28 +286,6 @@
}
}
-void getDimensionsValueLeafNodes(
- const DimensionsValue& value, std::vector<DimensionsValue> *leafNodes) {
- switch (value.value_case()) {
- case DimensionsValue::ValueCase::kValueStr:
- case DimensionsValue::ValueCase::kValueInt:
- case DimensionsValue::ValueCase::kValueLong:
- case DimensionsValue::ValueCase::kValueBool:
- case DimensionsValue::ValueCase::kValueFloat:
- leafNodes->push_back(value);
- break;
- case DimensionsValue::ValueCase::kValueTuple:
- for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
- getDimensionsValueLeafNodes(value.value_tuple().dimensions_value(i), leafNodes);
- }
- break;
- case DimensionsValue::ValueCase::VALUE_NOT_SET:
- break;
- default:
- break;
- }
-}
-
std::string DimensionsValueToString(const DimensionsValue& value) {
std::string flatten;
DimensionsValueToString(value, &flatten);
diff --git a/cmds/statsd/src/dimension.h b/cmds/statsd/src/dimension.h
index d0f96a2..e900c5e 100644
--- a/cmds/statsd/src/dimension.h
+++ b/cmds/statsd/src/dimension.h
@@ -33,8 +33,7 @@
DimensionsValue getSingleLeafValue(const DimensionsValue& value);
// Appends the leaf node to the parent tree.
-void appendLeafNodeToParent(const Field& field, const DimensionsValue& value,
- DimensionsValue* parentValue);
+void appendLeafNodeToTree(const Field& field, const DimensionsValue& value, DimensionsValue* tree);
// Constructs the DimensionsValue protos from the FieldMatcher. Each DimensionsValue proto
// represents a tree. When the input proto has repeated fields and the input "dimensions" wants
@@ -45,13 +44,16 @@
std::vector<DimensionsValue>* rootDimensionsValues);
// Utils to build FieldMatcher proto for simple one-depth atoms.
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum);
-FieldMatcher buildSimpleAtomFieldMatcher(const int tagId);
+void buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum, FieldMatcher* matcher);
+void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher);
// Utils to build FieldMatcher proto for attribution nodes.
-FieldMatcher buildAttributionUidFieldMatcher(const int tagId, const Position position);
-FieldMatcher buildAttributionTagFieldMatcher(const int tagId, const Position position);
-FieldMatcher buildAttributionFieldMatcher(const int tagId, const Position position);
+void buildAttributionUidFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
+void buildAttributionTagFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
+void buildAttributionFieldMatcher(const int tagId, const Position position,
+ FieldMatcher* matcher);
// Utils to print pretty string for DimensionsValue proto.
std::string DimensionsValueToString(const DimensionsValue& value);
diff --git a/cmds/statsd/src/field_util.cpp b/cmds/statsd/src/field_util.cpp
index 4ff4f74..acf64fe 100644
--- a/cmds/statsd/src/field_util.cpp
+++ b/cmds/statsd/src/field_util.cpp
@@ -102,24 +102,13 @@
}
}
-Field buildAtomField(const int tagId, const Field &atomField) {
- Field field;
- *field.add_child() = atomField;
- field.set_field(tagId);
- return field;
+void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field *field) {
+ field->set_field(tagId);
+ field->add_child()->set_field(atomFieldNum);
}
-Field buildSimpleAtomField(const int tagId, const int atomFieldNum) {
- Field field;
- field.set_field(tagId);
- field.add_child()->set_field(atomFieldNum);
- return field;
-}
-
-Field buildSimpleAtomField(const int tagId) {
- Field field;
- field.set_field(tagId);
- return field;
+void buildSimpleAtomField(const int tagId, Field *field) {
+ field->set_field(tagId);
}
void appendLeaf(Field *parent, int node_field_num) {
@@ -145,18 +134,6 @@
}
}
-
-void getNextField(Field* field) {
- if (field->child_size() <= 0) {
- field->set_field(field->field() + 1);
- return;
- }
- if (field->child_size() != 1) {
- return;
- }
- getNextField(field->mutable_child(0));
-}
-
void increasePosition(Field *field) {
if (!field->has_position_index()) {
field->set_position_index(0);
@@ -176,34 +153,30 @@
return getPositionByReferenceField(ref.child(0), field_with_index.child(0));
}
-void setPositionForLeaf(Field *field, int index) {
- if (field->child_size() <= 0) {
- field->set_position_index(index);
- } else {
- setPositionForLeaf(field->mutable_child(0), index);
- }
-}
-
namespace {
+
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields);
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields);
void findNonRepeatedFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields) {
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (matcher.child_size() > 0) {
+ Field* newLeafField = leafField->add_child();
for (const auto& childMatcher : matcher.child()) {
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- findFields(fieldValueMap, childMatcher, childField, rootFields);
+ newLeafField->set_field(childMatcher.field());
+ findFields(fieldValueMap, childMatcher, rootField, newLeafField, rootFields);
}
+ leafField->clear_child();
} else {
- auto ret = fieldValueMap.equal_range(field);
+ auto ret = fieldValueMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -216,38 +189,42 @@
ALOGE("Found multiple values for optional field.");
return;
}
- rootFields->push_back(ret.first->first);
+ rootFields->insert(ret.first->first);
}
}
void findRepeatedFields(const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
- const Field& field, std::vector<Field>* rootFields) {
+ Field* rootField, Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- findNonRepeatedFields(fieldValueMap, matcher, first_field, rootFields);
+ leafField->set_position_index(0);
+ findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
} else {
- auto itLower = fieldValueMap.lower_bound(field);
+ auto itLower = fieldValueMap.lower_bound(*rootField);
if (itLower == fieldValueMap.end()) {
return;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldValueMap.lower_bound(next_field);
+
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldValueMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
switch (matcher.position()) {
case Position::LAST:
{
itUpper--;
if (itUpper != fieldValueMap.end()) {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return;
}
- setPositionForLeaf(&last_field, last_index);
+ leafField->set_position_index(last_index);
findNonRepeatedFields(
- fieldValueMap, matcher, last_field, rootFields);
+ fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
}
}
break;
@@ -255,17 +232,17 @@
{
std::set<int> indexes;
for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
+ int index = getPositionByReferenceField(*rootField, it->first);
if (index >= 0) {
indexes.insert(index);
}
}
if (!indexes.empty()) {
- Field any_field = field;
for (const int index : indexes) {
- setPositionForLeaf(&any_field, index);
+ leafField->set_position_index(index);
findNonRepeatedFields(
- fieldValueMap, matcher, any_field, rootFields);
+ fieldValueMap, matcher, rootField, leafField, rootFields);
+ leafField->clear_position_index();
}
}
}
@@ -279,12 +256,13 @@
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- const Field& field,
- std::vector<Field>* rootFields) {
+ Field* rootField,
+ Field* leafField,
+ std::set<Field, FieldCmp>* rootFields) {
if (!matcher.has_position()) {
- findNonRepeatedFields(fieldValueMap, matcher, field, rootFields);
+ findNonRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
} else {
- findRepeatedFields(fieldValueMap, matcher, field, rootFields);
+ findRepeatedFields(fieldValueMap, matcher, rootField, leafField, rootFields);
}
}
@@ -293,17 +271,24 @@
void findFields(
const FieldValueMap& fieldValueMap,
const FieldMatcher& matcher,
- std::vector<Field>* rootFields) {
- return findFields(fieldValueMap, matcher, buildSimpleAtomField(matcher.field()), rootFields);
+ std::set<Field, FieldCmp>* rootFields) {
+ if (!matcher.has_field() || fieldValueMap.empty()) {
+ return;
+ }
+ Field rootField;
+ buildSimpleAtomField(matcher.field(), &rootField);
+ return findFields(fieldValueMap, matcher, &rootField, &rootField, rootFields);
}
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap) {
- std::vector<Field> rootFields;
+ if (!matcher.has_field()) {
+ return;
+ }
+ std::set<Field, FieldCmp> rootFields;
findFields(*fieldValueMap, matcher, &rootFields);
- std::set<Field, FieldCmp> rootFieldSet(rootFields.begin(), rootFields.end());
auto it = fieldValueMap->begin();
while (it != fieldValueMap->end()) {
- if (rootFieldSet.find(it->first) == rootFieldSet.end()) {
+ if (rootFields.find(it->first) == rootFields.end()) {
it = fieldValueMap->erase(it);
} else {
it++;
diff --git a/cmds/statsd/src/field_util.h b/cmds/statsd/src/field_util.h
index a4dfddd..b04465d 100644
--- a/cmds/statsd/src/field_util.h
+++ b/cmds/statsd/src/field_util.h
@@ -20,7 +20,8 @@
#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
-#include <unordered_map>
+#include <map>
+#include <set>
namespace android {
namespace os {
@@ -54,15 +55,9 @@
void appendLeaf(Field *parent, int node_field_num);
void appendLeaf(Field *parent, int node_field_num, int position);
-// Given the field sorting logic, this function is to increase the "field" at the leaf node.
-void getNextField(Field* field);
-
// Increase the position index for the node. If the "position_index" is not set, set it as 0.
void increasePosition(Field *field);
-// Finds the leaf node and set the index there.
-void setPositionForLeaf(Field *field, int index);
-
// Returns true if the matcher has specified at least one leaf node.
bool hasLeafNode(const FieldMatcher& matcher);
@@ -72,15 +67,13 @@
int getPositionByReferenceField(const Field& reference, const Field& field_with_index);
// Utils to build the Field proto for simple atom fields.
-Field buildAtomField(const int tagId, const Field &atomField);
-Field buildSimpleAtomField(const int tagId, const int atomFieldNum);
-Field buildSimpleAtomField(const int tagId);
+void buildSimpleAtomField(const int tagId, const int atomFieldNum, Field* field);
+void buildSimpleAtomField(const int tagId, Field* field);
// Find out all the fields specified by the matcher.
void findFields(
- const FieldValueMap& fieldValueMap,
- const FieldMatcher& matcher,
- std::vector<Field>* rootFields);
+ const FieldValueMap& fieldValueMap, const FieldMatcher& matcher,
+ std::set<Field, FieldCmp>* rootFields);
// Filter out the fields not in the field matcher.
void filterFields(const FieldMatcher& matcher, FieldValueMap* fieldValueMap);
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 1ca793c..9e72f5b 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -198,7 +198,8 @@
int seenListStart = 0;
- Field field;
+ Field fieldTree;
+ Field* atomField = fieldTree.add_child();
do {
elem = android_log_read_next(context);
switch ((int)elem.type) {
@@ -206,51 +207,37 @@
// elem at [0] is EVENT_TYPE_LIST, [1] is the tag id.
if (i == 1) {
mTagId = elem.data.int32;
+ fieldTree.set_field(mTagId);
} else {
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_int(elem.data.int32);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_int(elem.data.int32);
}
break;
case EVENT_TYPE_FLOAT:
{
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_float(elem.data.float32);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_float(elem.data.float32);
}
break;
case EVENT_TYPE_STRING:
{
- increaseField(&field, seenListStart > 0/* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_str(string(elem.data.string, elem.len).c_str());
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0/* is_child */);
+ mFieldValueMap[fieldTree].set_value_str(
+ string(elem.data.string, elem.len).c_str());
}
break;
case EVENT_TYPE_LONG:
{
- increaseField(&field, seenListStart > 0 /* is_child */);
- DimensionsValue dimensionsValue;
- dimensionsValue.set_value_long(elem.data.int64);
- setFieldInLeafValueProto(field, &dimensionsValue);
- mFieldValueMap.insert(
- std::make_pair(buildAtomField(mTagId, field), dimensionsValue));
+ increaseField(atomField, seenListStart > 0 /* is_child */);
+ mFieldValueMap[fieldTree].set_value_long(elem.data.int64);
}
break;
case EVENT_TYPE_LIST:
if (i >= 1) {
if (seenListStart > 0) {
- increasePosition(&field);
+ increasePosition(atomField);
} else {
- increaseField(&field, false /* is_child */);
+ increaseField(atomField, false /* is_child */);
}
seenListStart++;
if (seenListStart >= 3) {
@@ -262,10 +249,10 @@
case EVENT_TYPE_LIST_STOP:
seenListStart--;
if (seenListStart == 0) {
- field.clear_position_index();
+ atomField->clear_position_index();
} else {
- if (field.child_size() > 0) {
- field.mutable_child(0)->clear_field();
+ if (atomField->child_size() > 0) {
+ atomField->mutable_child(0)->clear_field();
}
}
break;
@@ -393,14 +380,9 @@
bool LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField,
DimensionsValue* dimensionsValue) const {
- return GetAtomDimensionsValueProto(
- buildSimpleAtomFieldMatcher(mTagId, atomField), dimensionsValue);
-}
-
-DimensionsValue LogEvent::GetSimpleAtomDimensionsValueProto(size_t atomField) const {
- DimensionsValue dimensionsValue;
- GetSimpleAtomDimensionsValueProto(atomField, &dimensionsValue);
- return dimensionsValue;
+ FieldMatcher matcher;
+ buildSimpleAtomFieldMatcher(mTagId, atomField, &matcher);
+ return GetAtomDimensionsValueProto(matcher, dimensionsValue);
}
DimensionsValue* LogEvent::findFieldValueOrNull(const Field& field) {
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 5a4efd4..eb2c008 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -92,7 +92,6 @@
* Get a DimensionsValue proto objects from Field.
*/
bool GetSimpleAtomDimensionsValueProto(size_t field, DimensionsValue* dimensionsValue) const;
- DimensionsValue GetSimpleAtomDimensionsValueProto(size_t atomField) const;
/**
* Write test data to the LogEvent. This can only be used when the LogEvent is constructed
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 48f62e7..b6f440f 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -93,25 +93,28 @@
return matched;
}
-bool matchesNonRepeatedField(
- const UidMap& uidMap,
- const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher,
- const Field& field) {
+namespace {
+
+bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField);
+
+bool matchesNonRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
if (matcher.value_matcher_case() ==
FieldValueMatcher::ValueMatcherCase::VALUE_MATCHER_NOT_SET) {
return !fieldMap.empty() && fieldMap.begin()->first.field() == matcher.field();
} else if (matcher.value_matcher_case() == FieldValueMatcher::ValueMatcherCase::kMatchesTuple) {
bool allMatched = true;
+ Field* newLeafField = leafField->add_child();
for (int i = 0; allMatched && i < matcher.matches_tuple().field_value_matcher_size(); ++i) {
const auto& childMatcher = matcher.matches_tuple().field_value_matcher(i);
- Field childField = field;
- appendLeaf(&childField, childMatcher.field());
- allMatched &= matchFieldSimple(uidMap, fieldMap, childMatcher, childField);
+ newLeafField->set_field(childMatcher.field());
+ allMatched &= matchFieldSimple(uidMap, fieldMap, childMatcher, rootField, newLeafField);
}
+ leafField->clear_child();
return allMatched;
} else {
- auto ret = fieldMap.equal_range(field);
+ auto ret = fieldMap.equal_range(*rootField);
int found = 0;
for (auto it = ret.first; it != ret.second; ++it) {
found++;
@@ -132,7 +135,7 @@
break;
case FieldValueMatcher::ValueMatcherCase::kEqString:
{
- if (IsAttributionUidField(field)) {
+ if (IsAttributionUidField(*rootField)) {
const int uid = ret.first->second.value_int();
std::set<string> packageNames =
uidMap.getAppNamesFromUid(uid, true /* normalize*/);
@@ -171,19 +174,25 @@
}
bool matchesRepeatedField(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, const Field& field) {
+ const FieldValueMatcher&matcher,
+ Field* rootField, Field* leafField) {
if (matcher.position() == Position::FIRST) {
- Field first_field = field;
- setPositionForLeaf(&first_field, 0);
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, first_field);
+ leafField->set_position_index(0);
+ bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ return res;
} else {
- auto itLower = fieldMap.lower_bound(field);
+ auto itLower = fieldMap.lower_bound(*rootField);
if (itLower == fieldMap.end()) {
return false;
}
- Field next_field = field;
- getNextField(&next_field);
- auto itUpper = fieldMap.lower_bound(next_field);
+
+ const int leafFieldNum = leafField->field();
+ leafField->set_field(leafFieldNum + 1);
+ auto itUpper = fieldMap.lower_bound(*rootField);
+ // Resets the field number.
+ leafField->set_field(leafFieldNum);
+
switch (matcher.position()) {
case Position::LAST:
{
@@ -191,30 +200,30 @@
if (itUpper == fieldMap.end()) {
return false;
} else {
- Field last_field = field;
- int last_index = getPositionByReferenceField(field, itUpper->first);
+ int last_index = getPositionByReferenceField(*rootField, itUpper->first);
if (last_index < 0) {
return false;
}
- setPositionForLeaf(&last_field, last_index);
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, last_field);
+ leafField->set_position_index(last_index);
+ bool res = matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ return res;
}
}
break;
case Position::ANY:
{
- std::set<int> indexes;
- for (auto it = itLower; it != itUpper; ++it) {
- int index = getPositionByReferenceField(field, it->first);
- if (index >= 0) {
- indexes.insert(index);
- }
- }
bool matched = false;
- for (const int index : indexes) {
- Field any_field = field;
- setPositionForLeaf(&any_field, index);
- matched |= matchesNonRepeatedField(uidMap, fieldMap, matcher, any_field);
+ for (auto it = itLower; it != itUpper; ++it) {
+ int index = getPositionByReferenceField(*rootField, it->first);
+ if (index >= 0) {
+ leafField->set_position_index(index);
+ matched |= matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
+ leafField->clear_position_index();
+ if (matched) {
+ break;
+ }
+ }
}
return matched;
}
@@ -226,14 +235,16 @@
}
bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& fieldMap,
- const FieldValueMatcher&matcher, const Field& field) {
+ const FieldValueMatcher&matcher, Field* rootField, Field* leafField) {
if (!matcher.has_position()) {
- return matchesNonRepeatedField(uidMap, fieldMap, matcher, field);
+ return matchesNonRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
} else {
- return matchesRepeatedField(uidMap, fieldMap, matcher, field);
+ return matchesRepeatedField(uidMap, fieldMap, matcher, rootField, leafField);
}
}
+} // namespace
+
bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
const LogEvent& event) {
if (simpleMatcher.field_value_matcher_size() <= 0) {
@@ -247,13 +258,15 @@
*root_field_matcher.mutable_matches_tuple()->add_field_value_matcher() =
simpleMatcher.field_value_matcher(i);
}
- return matchFieldSimple(uidMap, event.getFieldValueMap(), root_field_matcher, root_field);
+ return matchFieldSimple(
+ uidMap, event.getFieldValueMap(), root_field_matcher, &root_field, &root_field);
}
-vector<DimensionsValue> getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher) {
- vector<DimensionsValue> values;
- findDimensionsValues(event.getFieldValueMap(), matcher, &values);
- return values;
+void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
+ std::vector<DimensionsValue> *dimensionKeys) {
+ if (matcher.has_field()) {
+ findDimensionsValues(event.getFieldValueMap(), matcher, dimensionKeys);
+ }
}
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/matchers/matcher_util.h b/cmds/statsd/src/matchers/matcher_util.h
index 704cb4c..a45a9fb 100644
--- a/cmds/statsd/src/matchers/matcher_util.h
+++ b/cmds/statsd/src/matchers/matcher_util.h
@@ -42,13 +42,11 @@
bool combinationMatch(const std::vector<int>& children, const LogicalOperation& operation,
const std::vector<MatchingState>& matcherResults);
-bool matchFieldSimple(const UidMap& uidMap, const FieldValueMap& dimensionsMap,
- const FieldValueMatcher& matcher, const Field& field);
-
bool matchesSimple(const UidMap& uidMap,
const SimpleAtomMatcher& simpleMatcher, const LogEvent& wrapper);
-std::vector<DimensionsValue> getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher);
+void getDimensionKeys(const LogEvent& event, const FieldMatcher& matcher,
+ std::vector<DimensionsValue> *dimensionKeys);
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index e26fe56..d233a84 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -275,7 +275,8 @@
auto it = mCurrentSlicedDuration.find(eventKey);
- std::vector<DimensionsValue> values = getDimensionKeys(event, mInternalDimensions);
+ std::vector<DimensionsValue> values;
+ getDimensionKeys(event, mInternalDimensions, &values);
if (values.empty()) {
if (matcherIndex == mStartIndex) {
it->second->noteStart(DEFAULT_DIMENSION_KEY, condition,
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index d620a7e..e74924a 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -32,8 +32,7 @@
ConditionKey conditionKey;
if (mConditionSliced) {
for (const auto& link : mConditionLinks) {
- conditionKey.insert(std::make_pair(link.condition(),
- getDimensionKeysForCondition(event, link)));
+ getDimensionKeysForCondition(event, link, &conditionKey[link.condition()]);
}
if (mWizard->query(mConditionTrackerIndex, conditionKey) != ConditionState::kTrue) {
condition = false;
@@ -44,8 +43,9 @@
condition = mCondition;
}
- if (mDimensions.child_size() > 0) {
- vector<DimensionsValue> dimensionValues = getDimensionKeys(event, mDimensions);
+ if (mDimensions.has_field() && mDimensions.child_size() > 0) {
+ vector<DimensionsValue> dimensionValues;
+ getDimensionKeys(event, mDimensions, &dimensionValues);
for (const DimensionsValue& dimensionValue : dimensionValues) {
onMatchedLogEventInternalLocked(
matcherIndex, HashableDimensionKey(dimensionValue), conditionKey, condition, event);
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 5d3c158..5053bde 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -50,7 +50,7 @@
const uint64_t currentTimestamp) const override;
private:
- std::map<HashableDimensionKey, DurationInfo> mInfos;
+ std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
const uint64_t timestamp);
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 638b7ad..9093a51 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -55,10 +55,10 @@
// 2) which keys are paused (started but condition was false)
// 3) whenever a key stops, we remove it from the started set. And if the set becomes empty,
// it means everything has stopped, we then record the end time.
- std::map<HashableDimensionKey, int> mStarted;
- std::map<HashableDimensionKey, int> mPaused;
+ std::unordered_map<HashableDimensionKey, int> mStarted;
+ std::unordered_map<HashableDimensionKey, int> mPaused;
int64_t mLastStartTime;
- std::map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
+ std::unordered_map<HashableDimensionKey, ConditionKey> mConditionKeyMap;
// return true if we should not allow newKey to be tracked because we are above the threshold
bool hitGuardRail(const HashableDimensionKey& newKey);
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 897328d..4ad2097 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -149,8 +149,8 @@
metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
MetricConditionLink* link = metric.add_links();
link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- *link->mutable_fields_in_what() = buildSimpleAtomFieldMatcher(tagId, 1);
- *link->mutable_fields_in_condition() = buildSimpleAtomFieldMatcher(conditionTagId, 2);
+ buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
+ buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
LogEvent event1(tagId, bucketStartTimeNs + 1);
event1.write("111"); // uid
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 34cde60..da00cae 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -98,8 +98,8 @@
metric.set_condition(StringToId("APP_IN_BACKGROUND_PER_UID_AND_SCREEN_ON"));
MetricConditionLink* link = metric.add_links();
link->set_condition(StringToId("APP_IN_BACKGROUND_PER_UID"));
- *link->mutable_fields_in_what() = buildSimpleAtomFieldMatcher(tagId, 1);
- *link->mutable_fields_in_condition() = buildSimpleAtomFieldMatcher(conditionTagId, 2);
+ buildSimpleAtomFieldMatcher(tagId, 1, link->mutable_fields_in_what());
+ buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
LogEvent event1(tagId, bucketStartTimeNs + 1);
EXPECT_TRUE(event1.write("111"));