Add LogEvent::hasAttributionChain()
Optionally, accept a std::pair<int, int>* that is populated with the
starting and ending indices of attribution nodes in FieldValues vector.
Bug: 154286011
Test: bit statsd_test:*
Change-Id: I6f19abea7fbb27712b6c2d5a7679aa4f428c191d
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index e251399..afb55f0 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -27,7 +27,6 @@
struct Field;
struct FieldValue;
-const int32_t kAttributionField = 1;
const int32_t kMaxLogDepth = 2;
const int32_t kLastBitMask = 0x80;
const int32_t kClearLastBitDeco = 0x7f;
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index d914ab2..50fe47d 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -139,14 +139,13 @@
}
void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- if (event->getAttributionChainIndex() != -1) {
- for (auto& value : *(event->getMutableValues())) {
- if (value.mField.getPosAtDepth(0) > kAttributionField) {
- break;
- }
- if (isAttributionUidField(value)) {
- const int hostUid = mUidMap->getHostUidOrSelf(value.mValue.int_value);
- value.mValue.setInt(hostUid);
+ if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) {
+ vector<FieldValue>* const fieldValues = event->getMutableValues();
+ for (int i = indexRange.first; i <= indexRange.second; i++) {
+ FieldValue& fieldValue = fieldValues->at(i);
+ if (isAttributionUidField(fieldValue)) {
+ const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
+ fieldValue.mValue.setInt(hostUid);
}
}
} else {
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
index 9e72a23..c688133 100644
--- a/cmds/statsd/src/external/puller_util.cpp
+++ b/cmds/statsd/src/external/puller_util.cpp
@@ -51,7 +51,8 @@
int tagId, const vector<int>& additiveFieldsVec) {
// Check the first LogEvent for attribution chain or a uid field as either all atoms with this
// tagId have them or none of them do.
- const bool hasAttributionChain = data[0]->getAttributionChainIndex() != -1;
+ std::pair<int, int> attrIndexRange;
+ const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange);
bool hasUidField = (data[0]->getUidFieldIndex() != -1);
if (!hasAttributionChain && !hasUidField) {
@@ -65,14 +66,13 @@
ALOGE("Wrong atom. Expecting %d, got %d", tagId, event->GetTagId());
return;
}
- if (event->getAttributionChainIndex() != -1) {
- for (auto& value : *(event->getMutableValues())) {
- if (value.mField.getPosAtDepth(0) > kAttributionField) {
- break;
- }
- if (isAttributionUidField(value)) {
- const int hostUid = uidMap->getHostUidOrSelf(value.mValue.int_value);
- value.mValue.setInt(hostUid);
+ if (hasAttributionChain) {
+ vector<FieldValue>* const fieldValues = event->getMutableValues();
+ for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
+ FieldValue& fieldValue = fieldValues->at(i);
+ if (isAttributionUidField(fieldValue)) {
+ const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
+ fieldValue.mValue.setInt(hostUid);
}
}
} else {
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 61cd017..18f1b82 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -219,8 +219,8 @@
void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
uint8_t numAnnotations) {
- int firstUidInChainIndex = mValues.size();
- int32_t numNodes = readNextValue<uint8_t>();
+ const unsigned int firstUidInChainIndex = mValues.size();
+ const int32_t numNodes = readNextValue<uint8_t>();
for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
last[1] = (pos[1] == numNodes);
@@ -233,6 +233,11 @@
last[2] = true;
parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
}
+ // Check if at least one node was successfully parsed.
+ if (mValues.size() - 1 > firstUidInChainIndex) {
+ mAttributionChainStartIndex = firstUidInChainIndex;
+ mAttributionChainEndIndex = mValues.size() - 1;
+ }
parseAnnotations(numAnnotations, firstUidInChainIndex);
@@ -411,7 +416,6 @@
break;
case ATTRIBUTION_CHAIN_TYPE:
parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
- if (mAttributionChainIndex == -1) mAttributionChainIndex = pos[0];
break;
default:
mValid = false;
@@ -572,6 +576,19 @@
writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
}
+bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
+ if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
+ return false;
+ }
+
+ if (nullptr != indexRange) {
+ indexRange->first = mAttributionChainStartIndex;
+ indexRange->second = mAttributionChainEndIndex;
+ }
+
+ return true;
+}
+
void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds,
std::vector<uint8_t>* protoOut) {
ProtoOutputStream proto;
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 41fdcc2..e7340ef 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -163,12 +163,10 @@
return mUidFieldIndex;
}
- // Returns the index of (the first) attribution chain within the atom
- // definition. Note that the value is 1-indexed. If there is no attribution
- // chain, returns -1.
- inline int getAttributionChainIndex() {
- return mAttributionChainIndex;
- }
+ // Returns whether this LogEvent has an AttributionChain.
+ // If it does and indexRange is not a nullptr, populate indexRange with the start and end index
+ // of the AttributionChain within mValues.
+ bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const;
// Returns the index of the exclusive state field within the FieldValues vector if
// an exclusive state exists. If there is no exclusive state field, returns -1.
@@ -310,7 +308,8 @@
// Annotations
bool mTruncateTimestamp = false;
int mUidFieldIndex = -1;
- int mAttributionChainIndex = -1;
+ int mAttributionChainStartIndex = -1;
+ int mAttributionChainEndIndex = -1;
int mExclusiveStateFieldIndex = -1;
};
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index bb4578d..e2c2743 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -95,6 +95,7 @@
EXPECT_EQ(100, logEvent.GetTagId());
EXPECT_EQ(1000, logEvent.GetUid());
EXPECT_EQ(1001, logEvent.GetPid());
+ EXPECT_FALSE(logEvent.hasAttributionChain());
const vector<FieldValue>& values = logEvent.getValues();
EXPECT_EQ(4, values.size());
@@ -143,6 +144,7 @@
EXPECT_EQ(100, logEvent.GetTagId());
EXPECT_EQ(1000, logEvent.GetUid());
EXPECT_EQ(1001, logEvent.GetPid());
+ EXPECT_FALSE(logEvent.hasAttributionChain());
const vector<FieldValue>& values = logEvent.getValues();
EXPECT_EQ(2, values.size());
@@ -179,6 +181,7 @@
EXPECT_EQ(100, logEvent.GetTagId());
EXPECT_EQ(1000, logEvent.GetUid());
EXPECT_EQ(1001, logEvent.GetPid());
+ EXPECT_FALSE(logEvent.hasAttributionChain());
const vector<FieldValue>& values = logEvent.getValues();
EXPECT_EQ(1, values.size());
@@ -248,6 +251,11 @@
const vector<FieldValue>& values = logEvent.getValues();
EXPECT_EQ(4, values.size()); // 2 per attribution node
+ std::pair<int, int> attrIndexRange;
+ EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
+ EXPECT_EQ(0, attrIndexRange.first);
+ EXPECT_EQ(3, attrIndexRange.second);
+
// Check first attribution node
const FieldValue& uid1Item = values[0];
Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});