quipper: PerfReader stores string metadata as proto
BUG=chromium:568870
TEST=unit tests pass
Change-Id: Iac14ef57f4e40d50026f254ef46e21b29ad0d483
Signed-off-by: Simon Que <sque@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/327295
Reviewed-by: David Sharp <dhsharp@chromium.org>
diff --git a/chromiumos-wide-profiling/perf_reader.cc b/chromiumos-wide-profiling/perf_reader.cc
index 5eb3773..65f0306 100644
--- a/chromiumos-wide-profiling/perf_reader.cc
+++ b/chromiumos-wide-profiling/perf_reader.cc
@@ -26,6 +26,8 @@
using PerfEvent = PerfDataProto_PerfEvent;
using SampleInfo = PerfDataProto_SampleInfo;
+using StringAndMd5sumPrefix =
+ PerfDataProto_StringMetadata_StringAndMd5sumPrefix;
namespace {
@@ -136,8 +138,7 @@
}
// Reads a CStringWithLength from |data| into |dest| at the current offset.
-bool ReadStringFromBuffer(DataReader* data,
- CStringWithLength* dest) {
+bool ReadStringFromBuffer(DataReader* data, CStringWithLength* dest) {
if (!data->ReadUint32(&dest->len)) {
LOG(ERROR) << "Could not read string length from data.";
return false;
@@ -196,6 +197,11 @@
} // namespace
+// static
+size_t CStringWithLength::ExpectedStorageSizeOf(const string& str) {
+ return sizeof(CStringWithLength::len) + GetUint64AlignedStringLength(str);
+}
+
PerfReader::PerfReader() : metadata_mask_(0),
is_cross_endian_(false) {}
@@ -215,6 +221,10 @@
// Serialize metadata.
perf_data_proto->add_metadata_mask(metadata_mask_);
perf_data_proto->mutable_build_ids()->CopyFrom(proto_.build_ids());
+ if (proto_.has_string_metadata()) {
+ perf_data_proto->mutable_string_metadata()->
+ CopyFrom(proto_.string_metadata());
+ }
if (!serializer_.SerializeMetadata(*this, perf_data_proto)) {
return false;
}
@@ -240,6 +250,10 @@
if (perf_data_proto.metadata_mask_size())
metadata_mask_ = perf_data_proto.metadata_mask(0);
proto_.mutable_build_ids()->CopyFrom(perf_data_proto.build_ids());
+ if (perf_data_proto.has_string_metadata()) {
+ proto_.mutable_string_metadata()->
+ CopyFrom(perf_data_proto.string_metadata());
+ }
if (!serializer_.DeserializeMetadata(perf_data_proto, this))
return false;
@@ -912,15 +926,58 @@
return false;
break;
case HEADER_HOSTNAME:
- case HEADER_OSRELEASE:
- case HEADER_VERSION:
- case HEADER_ARCH:
- case HEADER_CPUDESC:
- case HEADER_CPUID:
- case HEADER_CMDLINE:
- if (!ReadStringMetadata(data, type, size))
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_hostname())) {
return false;
+ }
break;
+ case HEADER_OSRELEASE:
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_kernel_version())) {
+ return false;
+ }
+ break;
+ case HEADER_VERSION:
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_perf_version())) {
+ return false;
+ }
+ break;
+ case HEADER_ARCH:
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_architecture())) {
+ return false;
+ }
+ break;
+ case HEADER_CPUDESC:
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_cpu_description())) {
+ return false;
+ }
+ break;
+ case HEADER_CPUID:
+ if (!ReadSingleStringMetadata(
+ data, size,
+ proto_.mutable_string_metadata()->mutable_cpu_id())) {
+ return false;
+ }
+ break;
+ case HEADER_CMDLINE:
+ {
+ auto* string_metadata = proto_.mutable_string_metadata();
+ if (!ReadRepeatedStringMetadata(
+ data, size,
+ string_metadata->mutable_perf_command_line_token(),
+ string_metadata->mutable_perf_command_line_whole())) {
+ return false;
+ }
+ break;
+ }
case HEADER_NRCPUS:
if (!ReadUint32Metadata(data, type, size))
return false;
@@ -999,29 +1056,50 @@
return true;
}
-bool PerfReader::ReadStringMetadata(DataReader* data, u32 type, size_t size) {
- PerfStringMetadata str_data;
- str_data.type = type;
+bool PerfReader::ReadSingleStringMetadata(
+ DataReader* data,
+ size_t max_readable_size,
+ StringAndMd5sumPrefix* dest) const {
+ // If a string metadata field is present but empty, it can have a size of 0,
+ // in which case there is nothing to be read.
+ CStringWithLength single_string;
+ if (max_readable_size && !ReadStringFromBuffer(data, &single_string))
+ return false;
+ dest->set_value(single_string.str);
+ dest->set_value_md5_prefix(Md5Prefix(single_string.str));
+ return true;
+}
- // Skip the number of string data if it is present.
- if (NeedsNumberOfStringData(type)) {
- num_string_data_type count;
- if (!data->ReadUint32(&count)) {
- LOG(ERROR) << "Error reading string count.";
+bool PerfReader::ReadRepeatedStringMetadata(
+ DataReader* data,
+ size_t max_readable_size,
+ RepeatedPtrField<StringAndMd5sumPrefix>* dest_array,
+ StringAndMd5sumPrefix* dest_single) const {
+ num_string_data_type count = 1;
+ if (!data->ReadUint32(&count)) {
+ LOG(ERROR) << "Error reading string count.";
+ return false;
+ }
+ size_t size_read = sizeof(count);
+
+ string full_string;
+ while (count-- > 0 && size_read < max_readable_size) {
+ StringAndMd5sumPrefix* new_entry = dest_array->Add();
+ size_t offset = data->Tell();
+ if (!ReadSingleStringMetadata(data, max_readable_size - size_read,
+ new_entry)) {
return false;
}
- size -= sizeof(count);
+
+ if (!full_string.empty())
+ full_string += " ";
+ full_string += new_entry->value();
+
+ size_read += data->Tell() - offset;
}
- while (size > 0) {
- CStringWithLength single_string;
- if (!ReadStringFromBuffer(data, &single_string))
- return false;
- str_data.data.push_back(single_string);
- size -= (sizeof(single_string.len) + single_string.len);
- }
-
- string_metadata_.push_back(str_data);
+ dest_single->set_value(full_string);
+ dest_single->set_value_md5_prefix(Md5Prefix(full_string));
return true;
}
@@ -1261,32 +1339,50 @@
break;
case PERF_RECORD_HEADER_HOSTNAME:
metadata_mask_ |= (1 << HEADER_HOSTNAME);
- result = ReadStringMetadata(data, HEADER_HOSTNAME, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_hostname());
break;
case PERF_RECORD_HEADER_OSRELEASE:
metadata_mask_ |= (1 << HEADER_OSRELEASE);
- result = ReadStringMetadata(data, HEADER_OSRELEASE, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_kernel_version());
break;
case PERF_RECORD_HEADER_VERSION:
metadata_mask_ |= (1 << HEADER_VERSION);
- result = ReadStringMetadata(data, HEADER_VERSION, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_perf_version());
break;
case PERF_RECORD_HEADER_ARCH:
metadata_mask_ |= (1 << HEADER_ARCH);
- result = ReadStringMetadata(data, HEADER_ARCH, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_architecture());
break;
case PERF_RECORD_HEADER_CPUDESC:
metadata_mask_ |= (1 << HEADER_CPUDESC);
- result = ReadStringMetadata(data, HEADER_CPUDESC, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_cpu_description());
break;
case PERF_RECORD_HEADER_CPUID:
metadata_mask_ |= (1 << HEADER_CPUID);
- result = ReadStringMetadata(data, HEADER_CPUID, size_without_header);
+ result = ReadSingleStringMetadata(
+ data, size_without_header,
+ proto_.mutable_string_metadata()->mutable_cpu_id());
break;
case PERF_RECORD_HEADER_CMDLINE:
+ {
metadata_mask_ |= (1 << HEADER_CMDLINE);
- result = ReadStringMetadata(data, HEADER_CMDLINE, size_without_header);
+ auto* string_metadata = proto_.mutable_string_metadata();
+ result = ReadRepeatedStringMetadata(
+ data, size_without_header,
+ string_metadata->mutable_perf_command_line_token(),
+ string_metadata->mutable_perf_command_line_whole());
break;
+ }
case PERF_RECORD_HEADER_NRCPUS:
metadata_mask_ |= (1 << HEADER_NRCPUS);
result = ReadUint32Metadata(data, HEADER_NRCPUS, size_without_header);
@@ -1402,6 +1498,9 @@
std::vector<struct perf_file_section> metadata_sections;
metadata_sections.reserve(GetNumSupportedMetadata());
+ // For less verbose access to string metadata fields.
+ const auto& string_metadata = proto_.string_metadata();
+
for (u32 type = HEADER_FIRST_FEATURE; type != HEADER_LAST_FEATURE; ++type) {
if ((header.adds_features[0] & (1 << type)) == 0)
continue;
@@ -1421,15 +1520,36 @@
return false;
break;
case HEADER_HOSTNAME:
- case HEADER_OSRELEASE:
- case HEADER_VERSION:
- case HEADER_ARCH:
- case HEADER_CPUDESC:
- case HEADER_CPUID:
- case HEADER_CMDLINE:
- if (!WriteStringMetadata(type, data))
+ if (!WriteSingleStringMetadata(string_metadata.hostname(), data))
return false;
break;
+ case HEADER_OSRELEASE:
+ if (!WriteSingleStringMetadata(string_metadata.kernel_version(), data))
+ return false;
+ break;
+ case HEADER_VERSION:
+ if (!WriteSingleStringMetadata(string_metadata.perf_version(), data))
+ return false;
+ break;
+ case HEADER_ARCH:
+ if (!WriteSingleStringMetadata(string_metadata.architecture(), data))
+ return false;
+ break;
+ case HEADER_CPUDESC:
+ if (!WriteSingleStringMetadata(string_metadata.cpu_description(), data))
+ return false;
+ break;
+ case HEADER_CPUID:
+ if (!WriteSingleStringMetadata(string_metadata.cpu_id(), data))
+ return false;
+ break;
+ case HEADER_CMDLINE:
+ if (!WriteRepeatedStringMetadata(
+ string_metadata.perf_command_line_token(),
+ data)) {
+ return false;
+ }
+ break;
case HEADER_NRCPUS:
if (!WriteUint32Metadata(type, data))
return false;
@@ -1496,28 +1616,31 @@
return true;
}
-bool PerfReader::WriteStringMetadata(u32 type, DataWriter* data) const {
- for (size_t i = 0; i < string_metadata_.size(); ++i) {
- const PerfStringMetadata& str_data = string_metadata_[i];
- if (str_data.type == type) {
- num_string_data_type num_strings = str_data.data.size();
- if (NeedsNumberOfStringData(type) &&
- !data->WriteDataValue(&num_strings, sizeof(num_strings),
- "number of string metadata")) {
- return false;
- }
+bool PerfReader::WriteSingleStringMetadata(
+ const StringAndMd5sumPrefix& src,
+ DataWriter* data) const {
+ CStringWithLength string_with_length;
+ string_with_length.str = src.value();
+ string_with_length.len = GetUint64AlignedStringLength(src.value());
+ return WriteStringToBuffer(string_with_length, data);
+}
- for (size_t j = 0; j < num_strings; ++j) {
- const CStringWithLength& single_string = str_data.data[j];
- if (!WriteStringToBuffer(single_string, data))
- return false;
- }
-
- return true;
- }
+bool PerfReader::WriteRepeatedStringMetadata(
+ const RepeatedPtrField<StringAndMd5sumPrefix>& src_array,
+ DataWriter* data) const {
+ num_string_data_type num_strings = src_array.size();
+ if (!data->WriteDataValue(&num_strings, sizeof(num_strings),
+ "number of string metadata")) {
+ return false;
}
- LOG(ERROR) << "String metadata of type " << type << " not present";
- return false;
+ for (const auto src_entry : src_array) {
+ CStringWithLength string_with_length;
+ string_with_length.str = src_entry.value();
+ string_with_length.len = GetUint64AlignedStringLength(src_entry.value());
+ if (!WriteStringToBuffer(string_with_length, data))
+ return false;
+ }
+ return true;
}
bool PerfReader::WriteUint32Metadata(u32 type, DataWriter* data) const {
@@ -1778,16 +1901,25 @@
}
size_t PerfReader::GetStringMetadataSize() const {
+ auto ExpectedStorageSizeOf = CStringWithLength::ExpectedStorageSizeOf;
size_t size = 0;
- for (size_t i = 0; i < string_metadata_.size(); ++i) {
- const PerfStringMetadata& metadata = string_metadata_[i];
- if (NeedsNumberOfStringData(metadata.type))
- size += sizeof(num_string_data_type);
+ if (string_metadata().has_hostname())
+ size += ExpectedStorageSizeOf(string_metadata().hostname().value());
+ if (string_metadata().has_kernel_version())
+ size += ExpectedStorageSizeOf(string_metadata().kernel_version().value());
+ if (string_metadata().has_perf_version())
+ size += ExpectedStorageSizeOf(string_metadata().perf_version().value());
+ if (string_metadata().has_architecture())
+ size += ExpectedStorageSizeOf(string_metadata().architecture().value());
+ if (string_metadata().has_cpu_description())
+ size += ExpectedStorageSizeOf(string_metadata().cpu_description().value());
+ if (string_metadata().has_cpu_id())
+ size += ExpectedStorageSizeOf(string_metadata().cpu_id().value());
- for (size_t j = 0; j < metadata.data.size(); ++j) {
- const CStringWithLength& str = metadata.data[j];
- size += sizeof(str.len) + str.len;
- }
+ if (!string_metadata().perf_command_line_token().empty()) {
+ size += sizeof(num_string_data_type);
+ for (const auto& token : string_metadata().perf_command_line_token())
+ size += ExpectedStorageSizeOf(token.value());
}
return size;
}
diff --git a/chromiumos-wide-profiling/perf_reader.h b/chromiumos-wide-profiling/perf_reader.h
index 326d2bc..20f7c24 100644
--- a/chromiumos-wide-profiling/perf_reader.h
+++ b/chromiumos-wide-profiling/perf_reader.h
@@ -38,14 +38,22 @@
const size_t kBuildIDArraySize = 20;
const size_t kBuildIDStringLength = kBuildIDArraySize * 2;
+// TODO(sque): Move this to perf_reader.cc once it is no longer used in this
+// file.
struct CStringWithLength {
u32 len;
string str;
-};
-struct PerfStringMetadata {
- u32 type;
- std::vector<CStringWithLength> data;
+ // Returns the size required to store both |len| and a string of size |len|.
+ // This is not the same as the minimum size required to store |str|.
+ size_t GetStorageSize() const {
+ return sizeof(len) + len;
+ }
+
+ // Given a string, returns the total size required to store the string in perf
+ // data, including a preceding length field and extra padding to align the
+ // string + null terminator to a multiple of uint64s.
+ static size_t ExpectedStorageSizeOf(const string& str);
};
struct PerfUint32Metadata {
@@ -175,11 +183,8 @@
metadata_mask_ = mask;
}
- const std::vector<PerfStringMetadata>& string_metadata() const {
- return string_metadata_;
- }
- std::vector<PerfStringMetadata>* mutable_string_metadata() {
- return &string_metadata_;
+ const PerfDataProto_StringMetadata& string_metadata() const {
+ return proto_.string_metadata();
}
const std::vector<PerfUint32Metadata>& uint32_metadata() const {
@@ -235,7 +240,23 @@
bool ReadBuildIDMetadataWithoutHeader(DataReader* data,
const perf_event_header& header);
- bool ReadStringMetadata(DataReader* data, u32 type, size_t size);
+ // Reads a singular string metadata field (with preceding size field) from
+ // |data| and writes the string and its Md5sum prefix into |dest|.
+ bool ReadSingleStringMetadata(
+ DataReader* data,
+ size_t max_readable_size,
+ PerfDataProto_StringMetadata_StringAndMd5sumPrefix* dest) const;
+ // Reads a string metadata with multiple string fields (each with preceding
+ // size field) from |data|. Writes each string field and its Md5sum prefix
+ // into |dest_array|. Writes the combined string fields (joined into one
+ // string into |dest_single|.
+ bool ReadRepeatedStringMetadata(
+ DataReader* data,
+ size_t max_readable_size,
+ RepeatedPtrField<PerfDataProto_StringMetadata_StringAndMd5sumPrefix>*
+ dest_array,
+ PerfDataProto_StringMetadata_StringAndMd5sumPrefix* dest_single) const;
+
bool ReadUint32Metadata(DataReader* data, u32 type, size_t size);
bool ReadUint64Metadata(DataReader* data, u32 type, size_t size);
bool ReadCPUTopologyMetadata(DataReader* data, u32 type, size_t size);
@@ -266,7 +287,13 @@
// For writing the various types of metadata.
bool WriteBuildIDMetadata(u32 type, DataWriter* data) const;
- bool WriteStringMetadata(u32 type, DataWriter* data) const;
+ bool WriteSingleStringMetadata(
+ const PerfDataProto_StringMetadata_StringAndMd5sumPrefix& src,
+ DataWriter* data) const;
+ bool WriteRepeatedStringMetadata(
+ const RepeatedPtrField<
+ PerfDataProto_StringMetadata_StringAndMd5sumPrefix>& src_array,
+ DataWriter* data) const;
bool WriteUint32Metadata(u32 type, DataWriter* data) const;
bool WriteUint64Metadata(u32 type, DataWriter* data) const;
bool WriteEventDescMetadata(u32 type, DataWriter* data) const;
@@ -313,7 +340,6 @@
// TODO(sque): Store all fields in here, not just events.
PerfDataProto proto_;
- std::vector<PerfStringMetadata> string_metadata_;
std::vector<PerfUint32Metadata> uint32_metadata_;
std::vector<PerfUint64Metadata> uint64_metadata_;
PerfCPUTopologyMetadata cpu_topology_;
diff --git a/chromiumos-wide-profiling/perf_reader_test.cc b/chromiumos-wide-profiling/perf_reader_test.cc
index 2063123..3f3acb9 100644
--- a/chromiumos-wide-profiling/perf_reader_test.cc
+++ b/chromiumos-wide-profiling/perf_reader_test.cc
@@ -833,26 +833,13 @@
PerfReader pr;
ASSERT_TRUE(pr.ReadFromString(input.str()));
+ // The dummy metadata should not have prevented the reading of the other
+ // metadata.
const auto& string_metadata = pr.string_metadata();
-
- // The dummy metadata should not have been stored.
- EXPECT_EQ(4, string_metadata.size());
-
- // Make sure each metadata entry has a stored string value.
- for (const auto& entry : string_metadata)
- EXPECT_EQ(1, entry.data.size());
-
- EXPECT_EQ(HEADER_HOSTNAME, string_metadata[0].type);
- EXPECT_EQ("hostname", string_metadata[0].data[0].str);
-
- EXPECT_EQ(HEADER_OSRELEASE, string_metadata[1].type);
- EXPECT_EQ("osrelease", string_metadata[1].data[0].str);
-
- EXPECT_EQ(HEADER_VERSION, string_metadata[2].type);
- EXPECT_EQ("version", string_metadata[2].data[0].str);
-
- EXPECT_EQ(HEADER_ARCH, string_metadata[3].type);
- EXPECT_EQ("arch", string_metadata[3].data[0].str);
+ EXPECT_EQ("hostname", string_metadata.hostname().value());
+ EXPECT_EQ("osrelease", string_metadata.kernel_version().value());
+ EXPECT_EQ("version", string_metadata.perf_version().value());
+ EXPECT_EQ("arch", string_metadata.architecture().value());
}
// Regression test for http://crbug.com/493533
@@ -884,26 +871,13 @@
PerfReader pr;
ASSERT_TRUE(pr.ReadFromString(input.str()));
+ // The dummy metadata should not have prevented the reading of the other
+ // metadata.
const auto& string_metadata = pr.string_metadata();
-
- // The dummy metadata should not have been stored.
- EXPECT_EQ(4, string_metadata.size());
-
- // Make sure each metadata entry has a stored string value.
- for (const auto& entry : string_metadata)
- EXPECT_EQ(1, entry.data.size());
-
- EXPECT_EQ(HEADER_HOSTNAME, string_metadata[0].type);
- EXPECT_EQ("hostname", string_metadata[0].data[0].str);
-
- EXPECT_EQ(HEADER_OSRELEASE, string_metadata[1].type);
- EXPECT_EQ("osrelease", string_metadata[1].data[0].str);
-
- EXPECT_EQ(HEADER_VERSION, string_metadata[2].type);
- EXPECT_EQ("version", string_metadata[2].data[0].str);
-
- EXPECT_EQ(HEADER_ARCH, string_metadata[3].type);
- EXPECT_EQ("arch", string_metadata[3].data[0].str);
+ EXPECT_EQ("hostname", string_metadata.hostname().value());
+ EXPECT_EQ("osrelease", string_metadata.kernel_version().value());
+ EXPECT_EQ("version", string_metadata.perf_version().value());
+ EXPECT_EQ("arch", string_metadata.architecture().value());
}
TEST(PerfReaderTest, AttrsWithDifferentSampleTypes) {
diff --git a/chromiumos-wide-profiling/perf_serializer.cc b/chromiumos-wide-profiling/perf_serializer.cc
index bb8da86..1d8c896 100644
--- a/chromiumos-wide-profiling/perf_serializer.cc
+++ b/chromiumos-wide-profiling/perf_serializer.cc
@@ -768,71 +768,6 @@
to->mutable_numa_topology())) {
return false;
}
- typedef PerfDataProto_StringMetadata_StringAndMd5sumPrefix
- StringAndMd5sumPrefix;
- // Handle the string metadata specially.
- for (const auto& metadata : from.string_metadata()) {
- StringAndMd5sumPrefix* to_metadata = NULL;
- PerfDataProto_StringMetadata* proto_string_metadata =
- to->mutable_string_metadata();
- bool is_command_line = false;
-
- switch (metadata.type) {
- case HEADER_HOSTNAME:
- to_metadata = proto_string_metadata->mutable_hostname();
- break;
- case HEADER_OSRELEASE:
- to_metadata = proto_string_metadata->mutable_kernel_version();
- break;
- case HEADER_VERSION:
- to_metadata = proto_string_metadata->mutable_perf_version();
- break;
- case HEADER_ARCH:
- to_metadata = proto_string_metadata->mutable_architecture();
- break;
- case HEADER_CPUDESC:
- to_metadata = proto_string_metadata->mutable_cpu_description();
- break;
- case HEADER_CPUID:
- to_metadata = proto_string_metadata->mutable_cpu_id();
- break;
- case HEADER_CMDLINE:
- is_command_line = true;
- to_metadata = proto_string_metadata->mutable_perf_command_line_whole();
- break;
- default:
- LOG(ERROR) << "Unsupported string metadata type: " << metadata.type;
- continue;
- }
- if (is_command_line) {
- // Handle command lines as a special case. It has two protobuf fields, one
- // of which is a repeated field.
- string full_command_line;
- for (const auto& data : metadata.data) {
- StringAndMd5sumPrefix* command_line_token =
- proto_string_metadata->add_perf_command_line_token();
- command_line_token->set_value(data.str);
- command_line_token->
- set_value_md5_prefix(Md5Prefix(command_line_token->value()));
- full_command_line += data.str + " ";
- }
- // Delete the extra space at the end of the newly created command string.
- TrimWhitespace(&full_command_line);
- to_metadata->set_value(full_command_line);
- to_metadata->set_value_md5_prefix(Md5Prefix(full_command_line));
- } else {
- DCHECK(to_metadata); // Make sure a valid destination metadata was found.
- // In some cases there is a null or empty string metadata value in the
- // perf data. Make sure not to access |string_metadata_[i].data[0]| if
- // that is the case.
- if (!metadata.data.empty())
- to_metadata->set_value(metadata.data[0].str);
- else
- to_metadata->set_value(string());
-
- to_metadata->set_value_md5_prefix(Md5Prefix(to_metadata->value()));
- }
- }
return true;
}
@@ -850,63 +785,6 @@
return false;
}
- // Handle the string metadata specially.
- typedef PerfDataProto_StringMetadata_StringAndMd5sumPrefix
- StringAndMd5sumPrefix;
- const PerfDataProto_StringMetadata& data = from.string_metadata();
- std::vector<std::pair<u32, StringAndMd5sumPrefix> > metadata_strings;
- if (data.has_hostname()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_HOSTNAME), data.hostname()));
- }
- if (data.has_kernel_version()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_OSRELEASE),
- data.kernel_version()));
- }
- if (data.has_perf_version()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_VERSION), data.perf_version()));
- }
- if (data.has_architecture()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_ARCH), data.architecture()));
- }
- if (data.has_cpu_description()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_CPUDESC),
- data.cpu_description()));
- }
- if (data.has_cpu_id()) {
- metadata_strings.push_back(
- std::make_pair(static_cast<u32>(HEADER_CPUID), data.cpu_id()));
- }
-
- // Add each string metadata element to |string_metadata_|.
- for (size_t i = 0; i < metadata_strings.size(); ++i) {
- PerfStringMetadata metadata;
- metadata.type = metadata_strings[i].first;
- CStringWithLength cstring;
- cstring.str = metadata_strings[i].second.value();
- cstring.len = cstring.str.size() + 1; // Include the null terminator.
- metadata.data.push_back(cstring);
-
- to->mutable_string_metadata()->push_back(metadata);
- }
-
- // Add the command line tokens as a special case (repeated field).
- if (data.perf_command_line_token_size() > 0) {
- PerfStringMetadata metadata;
- metadata.type = HEADER_CMDLINE;
- for (int i = 0; i < data.perf_command_line_token_size(); ++i) {
- CStringWithLength cstring;
- cstring.str = data.perf_command_line_token(i).value();
- cstring.len = cstring.str.size() + 1; // Include the null terminator.
- metadata.data.push_back(cstring);
- }
- to->mutable_string_metadata()->push_back(metadata);
- }
-
return true;
}