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/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);