trace_processor: migrate metadata to macro tables
While doing this, we can also refactor a bunch of code in TraceStorage
into a dedicated metadata tracker.
Context: go/perfetto-tp-refactor
Bug: 135177627
Change-Id: Id612bc66ed62fd39b5dd156d7ab87e41d4fa064c
diff --git a/Android.bp b/Android.bp
index c29530e..17b6886 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5724,7 +5724,6 @@
"src/trace_processor/args_table.cc",
"src/trace_processor/filtered_row_index.cc",
"src/trace_processor/gfp_flags.cc",
- "src/trace_processor/metadata_table.cc",
"src/trace_processor/process_table.cc",
"src/trace_processor/raw_table.cc",
"src/trace_processor/read_trace.cc",
@@ -5841,6 +5840,7 @@
"src/trace_processor/importers/proto/track_event_module.cc",
"src/trace_processor/importers/proto/track_event_parser.cc",
"src/trace_processor/importers/proto/track_event_tokenizer.cc",
+ "src/trace_processor/metadata_tracker.cc",
"src/trace_processor/process_tracker.cc",
"src/trace_processor/slice_tracker.cc",
"src/trace_processor/stack_profile_tracker.cc",
@@ -5883,7 +5883,6 @@
"src/trace_processor/importers/proto/heap_graph_walker_unittest.cc",
"src/trace_processor/importers/proto/proto_trace_parser_unittest.cc",
"src/trace_processor/importers/systrace/systrace_parser_unittest.cc",
- "src/trace_processor/metadata_table_unittest.cc",
"src/trace_processor/process_table_unittest.cc",
"src/trace_processor/process_tracker_unittest.cc",
"src/trace_processor/protozero_to_text_unittests.cc",
diff --git a/BUILD b/BUILD
index 5699b8b..18a633e 100644
--- a/BUILD
+++ b/BUILD
@@ -755,6 +755,7 @@
"src/trace_processor/tables/counter_tables.h",
"src/trace_processor/tables/macros.h",
"src/trace_processor/tables/macros_internal.h",
+ "src/trace_processor/tables/metadata_tables.h",
"src/trace_processor/tables/profiler_tables.h",
"src/trace_processor/tables/slice_tables.h",
"src/trace_processor/tables/track_tables.h",
@@ -789,8 +790,6 @@
"src/trace_processor/filtered_row_index.h",
"src/trace_processor/gfp_flags.cc",
"src/trace_processor/gfp_flags.h",
- "src/trace_processor/metadata_table.cc",
- "src/trace_processor/metadata_table.h",
"src/trace_processor/process_table.cc",
"src/trace_processor/process_table.h",
"src/trace_processor/raw_table.cc",
@@ -930,6 +929,8 @@
"src/trace_processor/importers/proto/track_event_tokenizer.cc",
"src/trace_processor/importers/proto/track_event_tokenizer.h",
"src/trace_processor/metadata.h",
+ "src/trace_processor/metadata_tracker.cc",
+ "src/trace_processor/metadata_tracker.h",
"src/trace_processor/process_tracker.cc",
"src/trace_processor/process_tracker.h",
"src/trace_processor/slice_tracker.cc",
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index b794b92..c999174 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -4072,6 +4072,75 @@
// End of protos/perfetto/trace/track_event/chrome_legacy_ipc.proto
+// Begin of protos/perfetto/trace/track_event/chrome_process_descriptor.proto
+
+// Describes the attributes for a Chrome process. Must be paired with a
+// ProcessDescriptor in the same TrackDescriptor.
+//
+// Next id: 4.
+message ChromeProcessDescriptor {
+ // See chromium's content::ProcessType.
+ enum ChromeProcessType {
+ PROCESS_UNSPECIFIED = 0;
+ PROCESS_BROWSER = 1;
+ PROCESS_RENDERER = 2;
+ PROCESS_UTILITY = 3;
+ PROCESS_ZYGOTE = 4;
+ PROCESS_SANDBOX_HELPER = 5;
+ PROCESS_GPU = 6;
+ PROCESS_PPAPI_PLUGIN = 7;
+ PROCESS_PPAPI_BROKER = 8;
+ }
+ optional ChromeProcessType process_type = 1;
+ optional int32 process_priority = 2;
+
+ // To support old UI. New UI should determine default sorting by process_type.
+ optional int32 legacy_sort_index = 3;
+}
+
+// End of protos/perfetto/trace/track_event/chrome_process_descriptor.proto
+
+// Begin of protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
+
+// Describes a Chrome thread's attributes. Emitted as part of a TrackDescriptor,
+// usually by the thread's trace writer. Must be paired with a ThreadDescriptor
+// in the same TrackDescriptor.
+//
+// Next id: 3.
+message ChromeThreadDescriptor {
+ enum ThreadType {
+ THREAD_UNSPECIFIED = 0;
+
+ THREAD_MAIN = 1;
+ THREAD_IO = 2;
+
+ // Scheduler:
+ THREAD_POOL_BG_WORKER = 3;
+ THREAD_POOL_FG_WORKER = 4;
+ THREAD_POOL_FB_BLOCKING = 5;
+ THREAD_POOL_BG_BLOCKING = 6;
+ THREAD_POOL_SERVICE = 7;
+
+ // Compositor:
+ THREAD_COMPOSITOR = 8;
+ THREAD_VIZ_COMPOSITOR = 9;
+ THREAD_COMPOSITOR_WORKER = 10;
+
+ // Renderer:
+ THREAD_SERVICE_WORKER = 11;
+
+ // Tracing related threads:
+ THREAD_MEMORY_INFRA = 50;
+ THREAD_SAMPLING_PROFILER = 51;
+ };
+ optional ThreadType thread_type = 1;
+
+ // To support old UI. New UI should determine default sorting by thread_type.
+ optional int32 legacy_sort_index = 2;
+}
+
+// End of protos/perfetto/trace/track_event/chrome_thread_descriptor.proto
+
// Begin of protos/perfetto/trace/track_event/chrome_user_event.proto
// Details about a UI interaction initiated by the user, such as opening or
@@ -4165,11 +4234,17 @@
// Describes a process's attributes. Emitted as part of a TrackDescriptor,
// usually by the process's main thread.
//
-// Next id: 5.
+// Next id: 6.
message ProcessDescriptor {
optional int32 pid = 1;
repeated string cmdline = 2;
+ optional int32 process_priority = 5;
+
+ // ---------------------------------------------------------------------------
+ // Deprecated / legacy fields, which will be removed in the future:
+ // ---------------------------------------------------------------------------
+
// See chromium's content::ProcessType.
enum ChromeProcessType {
PROCESS_UNSPECIFIED = 0;
@@ -4183,7 +4258,6 @@
PROCESS_PPAPI_BROKER = 8;
}
optional ChromeProcessType chrome_process_type = 4;
- optional int32 process_priority = 5;
// To support old UI. New UI should determine default sorting by process_type.
optional int32 legacy_sort_index = 3;
@@ -4229,6 +4303,10 @@
optional string thread_name = 5;
+ // ---------------------------------------------------------------------------
+ // Deprecated / legacy fields, which will be removed in the future:
+ // ---------------------------------------------------------------------------
+
enum ChromeThreadType {
CHROME_THREAD_UNSPECIFIED = 0;
@@ -4256,10 +4334,6 @@
};
optional ChromeThreadType chrome_thread_type = 4;
- // ---------------------------------------------------------------------------
- // Deprecated / legacy fields, which will be removed in the future:
- // ---------------------------------------------------------------------------
-
// Deprecated. Use ClockSnapshot in combination with TracePacket's timestamp
// and timestamp_clock_id fields instead.
optional int64 reference_timestamp_us = 6;
@@ -4280,7 +4354,9 @@
// Begin of protos/perfetto/trace/track_event/track_descriptor.proto
// Defines a track for TrackEvents. Slices and instant events on the same track
-// will be nested based on their timestamps, see TrackEvent::Type.
+// will be nested based on their timestamps, see TrackEvent::Type. Additionally
+// events on tracks which represent the same thread (i.e., matching pid and tid
+// in ThreadDescriptor) will be merged onto one sequential timeline.
//
// A TrackDescriptor only needs to be emitted by one trace writer / producer and
// is valid for the entirety of the trace. To ensure the descriptor isn't lost
@@ -4292,7 +4368,7 @@
// |TrackEvent::track_uuid|. It is possible but not necessary to emit a
// TrackDescriptor for this implicit track.
//
-// Next id: 1.
+// Next id: 8.
message TrackDescriptor {
// Unique ID that identifies this track. This ID is global to the whole trace.
// Producers should ensure that it is unlikely to clash with IDs emitted by
@@ -4302,16 +4378,20 @@
// event id + id_scope, pid, and/or tid to compute this ID.
optional uint64 uuid = 1;
- // TODO(eseckler): Support track hierarchies.
- // uint64 parent_uuid = X;
+ // A parent track reference can be used to describe relationships between
+ // tracks. For example, to define an asynchronous track which is scoped to a
+ // specific process, specify the uuid for that process's process track here.
+ optional uint64 parent_uuid = 5;
// Name of the track.
optional string name = 2;
- // Associate the track with a process or thread - the UI will draw this track
- // in the context of the process/thread.
+ // Associate the track with a process or thread - the UI will merge all tracks
+ // for the same process / thread into a single timeline view.
optional ProcessDescriptor process = 3;
+ optional ChromeProcessDescriptor chrome_process = 6;
optional ThreadDescriptor thread = 4;
+ optional ChromeThreadDescriptor chrome_thread = 7;
}
// End of protos/perfetto/trace/track_event/track_descriptor.proto
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 6a05dfa..a6fd002 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -112,6 +112,8 @@
"importers/proto/track_event_tokenizer.cc",
"importers/proto/track_event_tokenizer.h",
"metadata.h",
+ "metadata_tracker.cc",
+ "metadata_tracker.h",
"process_tracker.cc",
"process_tracker.h",
"slice_tracker.cc",
@@ -286,8 +288,6 @@
"filtered_row_index.h",
"gfp_flags.cc",
"gfp_flags.h",
- "metadata_table.cc",
- "metadata_table.h",
"process_table.cc",
"process_table.h",
"raw_table.cc",
@@ -379,7 +379,6 @@
"importers/proto/heap_graph_walker_unittest.cc",
"importers/proto/proto_trace_parser_unittest.cc",
"importers/systrace/systrace_parser_unittest.cc",
- "metadata_table_unittest.cc",
"process_table_unittest.cc",
"process_tracker_unittest.cc",
"protozero_to_text_unittests.cc",
diff --git a/src/trace_processor/args_tracker.cc b/src/trace_processor/args_tracker.cc
index cfd9f83..4f143c5 100644
--- a/src/trace_processor/args_tracker.cc
+++ b/src/trace_processor/args_tracker.cc
@@ -87,8 +87,8 @@
break;
// Special case: overwrites the metadata table row.
case TableId::kMetadataTable:
- storage->mutable_metadata()->OverwriteMetadata(
- row, Variadic::Integer(set_id));
+ storage->mutable_metadata_table()->mutable_int_value()->Set(row,
+ set_id);
break;
case TableId::kTrack:
storage->mutable_track_table()->mutable_source_arg_set_id()->Set(
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 93e9d01..ee12912 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -309,6 +309,8 @@
PERFETTO_FATAL("Invalid type");
}
+ const StringPool& string_pool() const { return *string_pool_; }
+
private:
enum class ColumnType {
// Standard primitive types.
diff --git a/src/trace_processor/db/typed_column.h b/src/trace_processor/db/typed_column.h
index 99355d7..a7183f6 100644
--- a/src/trace_processor/db/typed_column.h
+++ b/src/trace_processor/db/typed_column.h
@@ -62,6 +62,11 @@
// Inserts the value at the end of the column.
void Append(T v) { mutable_sparse_vector<T>()->Append(v); }
+ // Returns the row containing the given value in the Column.
+ base::Optional<uint32_t> IndexOf(T v) const {
+ return Column::IndexOf(NumericToSqlValue(v));
+ }
+
// Implements equality between two items of type |T|.
static bool Equals(T a, T b) {
// We need to use equal_to here as it could be T == double and because we
@@ -147,6 +152,16 @@
mutable_sparse_vector<StringPool::Id>()->Append(v);
}
+ // Returns the row containing the given value in the Column.
+ base::Optional<uint32_t> IndexOf(StringPool::Id v) const {
+ return Column::IndexOf(SqlValue::String(string_pool().Get(v).c_str()));
+ }
+
+ // Returns the row containing the given value in the Column.
+ base::Optional<uint32_t> IndexOf(NullTermStringView v) const {
+ return Column::IndexOf(SqlValue::String(v.c_str()));
+ }
+
// Implements equality between two items of type |T|.
static bool Equals(StringPool::Id a, StringPool::Id b) { return a == b; }
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index e10da4e..4aa62b9 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -952,64 +952,69 @@
util::Status ExportMetadata(const TraceStorage* storage,
TraceFormatWriter* writer) {
- const auto& trace_metadata = storage->metadata();
- const auto& keys = trace_metadata.keys();
- const auto& values = trace_metadata.values();
- for (size_t pos = 0; pos < keys.size(); pos++) {
+ const auto& trace_metadata = storage->metadata_table();
+ const auto& keys = trace_metadata.name();
+ const auto& int_values = trace_metadata.int_value();
+ const auto& str_values = trace_metadata.str_value();
+
+ // Create a mapping from key string ids to keys.
+ std::unordered_map<StringId, metadata::KeyIDs> key_map;
+ for (uint32_t i = 0; i < metadata::kNumKeys; ++i) {
+ auto id = *storage->string_pool().GetId(metadata::kNames[i]);
+ key_map[id] = static_cast<metadata::KeyIDs>(i);
+ }
+
+ for (uint32_t pos = 0; pos < trace_metadata.row_count(); pos++) {
// Cast away from enum type, as otherwise -Wswitch-enum will demand an
// exhaustive list of cases, even if there's a default case.
- switch (static_cast<size_t>(keys[pos])) {
+ metadata::KeyIDs key = key_map[keys[pos]];
+ switch (static_cast<size_t>(key)) {
case metadata::benchmark_description:
writer->AppendTelemetryMetadataString(
"benchmarkDescriptions",
- GetNonNullString(storage, values[pos].string_value));
+ GetNonNullString(storage, str_values[pos]));
break;
case metadata::benchmark_name:
writer->AppendTelemetryMetadataString(
- "benchmarks", GetNonNullString(storage, values[pos].string_value));
+ "benchmarks", GetNonNullString(storage, str_values[pos]));
break;
case metadata::benchmark_start_time_us:
writer->SetTelemetryMetadataTimestamp("benchmarkStart",
- values[pos].int_value);
+ *int_values[pos]);
break;
case metadata::benchmark_had_failures:
- if (pos < values.size())
- writer->AppendTelemetryMetadataBool("hadFailures",
- values[pos].int_value);
+ writer->AppendTelemetryMetadataBool("hadFailures", *int_values[pos]);
break;
case metadata::benchmark_label:
writer->AppendTelemetryMetadataString(
- "labels", GetNonNullString(storage, values[pos].string_value));
+ "labels", GetNonNullString(storage, str_values[pos]));
break;
case metadata::benchmark_story_name:
writer->AppendTelemetryMetadataString(
- "stories", GetNonNullString(storage, values[pos].string_value));
+ "stories", GetNonNullString(storage, str_values[pos]));
break;
case metadata::benchmark_story_run_index:
- writer->AppendTelemetryMetadataInt("storysetRepeats",
- values[pos].int_value);
+ writer->AppendTelemetryMetadataInt("storysetRepeats", *int_values[pos]);
break;
case metadata::benchmark_story_run_time_us:
- writer->SetTelemetryMetadataTimestamp("traceStart",
- values[pos].int_value);
+ writer->SetTelemetryMetadataTimestamp("traceStart", *int_values[pos]);
break;
case metadata::benchmark_story_tags: // repeated
writer->AppendTelemetryMetadataString(
- "storyTags", GetNonNullString(storage, values[pos].string_value));
+ "storyTags", GetNonNullString(storage, str_values[pos]));
break;
default:
- PERFETTO_DLOG("Ignoring metadata key %zu",
- static_cast<size_t>(keys[pos]));
+ PERFETTO_DLOG("Ignoring metadata key %zu", static_cast<size_t>(key));
break;
}
}
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index cfcb6f0..7cac7cd 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -26,6 +26,7 @@
#include "perfetto/ext/base/temp_file.h"
#include "src/trace_processor/args_tracker.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
#include "src/trace_processor/track_tracker.h"
@@ -67,6 +68,7 @@
context_.args_tracker.reset(new ArgsTracker(&context_));
context_.storage.reset(new TraceStorage());
context_.track_tracker.reset(new TrackTracker(&context_));
+ context_.metadata_tracker.reset(new MetadataTracker(&context_));
}
std::string ToJson(ArgumentFilterPredicate argument_filter = nullptr,
@@ -254,17 +256,20 @@
StringId desc_id =
context_.storage->InternString(base::StringView(kDescription));
Variadic description = Variadic::String(desc_id);
- context_.storage->SetMetadata(metadata::benchmark_description, description);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_description,
+ description);
StringId benchmark_name_id =
context_.storage->InternString(base::StringView(kBenchmarkName));
Variadic benchmark_name = Variadic::String(benchmark_name_id);
- context_.storage->SetMetadata(metadata::benchmark_name, benchmark_name);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_name,
+ benchmark_name);
StringId story_name_id =
context_.storage->InternString(base::StringView(kStoryName));
Variadic story_name = Variadic::String(story_name_id);
- context_.storage->SetMetadata(metadata::benchmark_story_name, story_name);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_story_name,
+ story_name);
StringId tag1_id =
context_.storage->InternString(base::StringView(kStoryTag1));
@@ -272,19 +277,22 @@
context_.storage->InternString(base::StringView(kStoryTag2));
Variadic tag1 = Variadic::String(tag1_id);
Variadic tag2 = Variadic::String(tag2_id);
- context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag1);
- context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag2);
+ context_.metadata_tracker->AppendMetadata(metadata::benchmark_story_tags,
+ tag1);
+ context_.metadata_tracker->AppendMetadata(metadata::benchmark_story_tags,
+ tag2);
Variadic benchmark_start = Variadic::Integer(kBenchmarkStart);
- context_.storage->SetMetadata(metadata::benchmark_start_time_us,
- benchmark_start);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_start_time_us,
+ benchmark_start);
Variadic story_start = Variadic::Integer(kStoryStart);
- context_.storage->SetMetadata(metadata::benchmark_story_run_time_us,
- story_start);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_story_run_time_us,
+ story_start);
Variadic had_failures = Variadic::Integer(kHadFailures);
- context_.storage->SetMetadata(metadata::benchmark_had_failures, had_failures);
+ context_.metadata_tracker->SetMetadata(metadata::benchmark_had_failures,
+ had_failures);
base::TempFile temp_file = base::TempFile::Create();
FILE* output = fopen(temp_file.path().c_str(), "w+");
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
index 5370e57..178be15 100644
--- a/src/trace_processor/importers/proto/android_probes_parser.cc
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -21,6 +21,7 @@
#include "src/trace_processor/args_tracker.h"
#include "src/trace_processor/clock_tracker.h"
#include "src/trace_processor/event_tracker.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/syscall_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
@@ -207,7 +208,7 @@
protos::pbzero::TraceConfig::StatsdMetadata::Decoder metadata(blob.data,
blob.size);
if (metadata.has_triggering_subscription_id()) {
- context_->storage->SetMetadata(
+ context_->metadata_tracker->SetMetadata(
metadata::statsd_triggering_subscription_id,
Variadic::Integer(metadata.triggering_subscription_id()));
}
@@ -226,9 +227,9 @@
for (auto it = pkg_list.packages(); it; ++it) {
// Insert a placeholder metadata entry, which will be overwritten by the
// arg_set_id when the arg tracker is flushed.
- uint32_t row = context_->storage->AppendMetadata(
+ auto id = context_->metadata_tracker->AppendMetadata(
metadata::android_packages_list, Variadic::Integer(0));
-
+ uint32_t row = *context_->storage->metadata_table().id().IndexOf(id);
auto add_arg = [this, row](base::StringView name, Variadic value) {
StringId key_id = context_->storage->InternString(name);
context_->args_tracker->AddArg(TableId::kMetadataTable, row, key_id,
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 76dffe8..9fe74c8 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -36,6 +36,7 @@
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/metadata.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stack_profile_tracker.h"
@@ -462,47 +463,50 @@
void ProtoTraceParser::ParseChromeBenchmarkMetadata(ConstBytes blob) {
TraceStorage* storage = context_->storage.get();
+ MetadataTracker* metadata = context_->metadata_tracker.get();
+
protos::pbzero::ChromeBenchmarkMetadata::Decoder packet(blob.data, blob.size);
if (packet.has_benchmark_name()) {
auto benchmark_name_id = storage->InternString(packet.benchmark_name());
- storage->SetMetadata(metadata::benchmark_name,
- Variadic::String(benchmark_name_id));
+ metadata->SetMetadata(metadata::benchmark_name,
+ Variadic::String(benchmark_name_id));
}
if (packet.has_benchmark_description()) {
auto benchmark_description_id =
storage->InternString(packet.benchmark_description());
- storage->SetMetadata(metadata::benchmark_description,
- Variadic::String(benchmark_description_id));
+ metadata->SetMetadata(metadata::benchmark_description,
+ Variadic::String(benchmark_description_id));
}
if (packet.has_label()) {
auto label_id = storage->InternString(packet.label());
- storage->SetMetadata(metadata::benchmark_label, Variadic::String(label_id));
+ metadata->SetMetadata(metadata::benchmark_label,
+ Variadic::String(label_id));
}
if (packet.has_story_name()) {
auto story_name_id = storage->InternString(packet.story_name());
- storage->SetMetadata(metadata::benchmark_story_name,
- Variadic::String(story_name_id));
+ metadata->SetMetadata(metadata::benchmark_story_name,
+ Variadic::String(story_name_id));
}
for (auto it = packet.story_tags(); it; ++it) {
auto story_tag_id = storage->InternString(*it);
- storage->AppendMetadata(metadata::benchmark_story_tags,
- Variadic::String(story_tag_id));
+ metadata->AppendMetadata(metadata::benchmark_story_tags,
+ Variadic::String(story_tag_id));
}
if (packet.has_benchmark_start_time_us()) {
- storage->SetMetadata(metadata::benchmark_start_time_us,
- Variadic::Integer(packet.benchmark_start_time_us()));
+ metadata->SetMetadata(metadata::benchmark_start_time_us,
+ Variadic::Integer(packet.benchmark_start_time_us()));
}
if (packet.has_story_run_time_us()) {
- storage->SetMetadata(metadata::benchmark_story_run_time_us,
- Variadic::Integer(packet.story_run_time_us()));
+ metadata->SetMetadata(metadata::benchmark_story_run_time_us,
+ Variadic::Integer(packet.story_run_time_us()));
}
if (packet.has_story_run_index()) {
- storage->SetMetadata(metadata::benchmark_story_run_index,
- Variadic::Integer(packet.story_run_index()));
+ metadata->SetMetadata(metadata::benchmark_story_run_index,
+ Variadic::Integer(packet.story_run_index()));
}
if (packet.has_had_failures()) {
- storage->SetMetadata(metadata::benchmark_had_failures,
- Variadic::Integer(packet.had_failures()));
+ metadata->SetMetadata(metadata::benchmark_had_failures,
+ Variadic::Integer(packet.had_failures()));
}
}
@@ -615,7 +619,8 @@
base::Uuid uuid(uuid_lsb, uuid_msb);
std::string str = uuid.ToPrettyString();
StringId id = context_->storage->InternString(base::StringView(str));
- context_->storage->SetMetadata(metadata::trace_uuid, Variadic::String(id));
+ context_->metadata_tracker->SetMetadata(metadata::trace_uuid,
+ Variadic::String(id));
}
}
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 9e7b9cd..f90418d 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -28,6 +28,7 @@
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/metadata.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/register_additional_modules.h"
#include "src/trace_processor/slice_tracker.h"
@@ -218,6 +219,7 @@
context_.storage.reset(storage_);
context_.track_tracker.reset(new TrackTracker(&context_));
context_.args_tracker.reset(new ArgsTracker(&context_));
+ context_.metadata_tracker.reset(new MetadataTracker(&context_));
event_ = new MockEventTracker(&context_);
context_.event_tracker.reset(event_);
sched_ = new MockSchedEventTracker(&context_);
@@ -2373,22 +2375,25 @@
EXPECT_CALL(*storage_, InternString(base::StringView(kTag2)))
.WillOnce(Return(3));
+ StringId benchmark_id = *storage_->string_pool().GetId(
+ metadata::kNames[metadata::benchmark_name]);
+ StringId tags_id = *storage_->string_pool().GetId(
+ metadata::kNames[metadata::benchmark_story_tags]);
+
context_.sorter->ExtractEventsForced();
- const auto& meta_keys = storage_->metadata().keys();
- const auto& meta_values = storage_->metadata().values();
- EXPECT_EQ(meta_keys.size(), 3u);
- std::vector<std::pair<metadata::KeyIDs, Variadic>> meta_entries;
- for (size_t i = 0; i < meta_keys.size(); i++) {
+ const auto& meta_keys = storage_->metadata_table().name();
+ const auto& meta_values = storage_->metadata_table().str_value();
+ EXPECT_EQ(storage_->metadata_table().row_count(), 3u);
+
+ std::vector<std::pair<StringId, StringId>> meta_entries;
+ for (uint32_t i = 0; i < storage_->metadata_table().row_count(); i++) {
meta_entries.emplace_back(std::make_pair(meta_keys[i], meta_values[i]));
}
- EXPECT_THAT(
- meta_entries,
- UnorderedElementsAreArray(
- {std::make_pair(metadata::benchmark_name, Variadic::String(1)),
- std::make_pair(metadata::benchmark_story_tags, Variadic::String(2)),
- std::make_pair(metadata::benchmark_story_tags,
- Variadic::String(3))}));
+ EXPECT_THAT(meta_entries,
+ UnorderedElementsAreArray({std::make_pair(benchmark_id, 1),
+ std::make_pair(tags_id, 2),
+ std::make_pair(tags_id, 3)}));
}
TEST_F(ProtoTraceParserTest, AndroidPackagesList) {
@@ -2426,25 +2431,15 @@
// structure, make an assumption that metadata storage is filled in in the
// FIFO order of seen packages.
const auto& args = context_.storage->args();
- const auto& metadata = context_.storage->metadata();
- const auto& meta_keys = metadata.keys();
- const auto& meta_values = metadata.values();
+ const auto& metadata = context_.storage->metadata_table();
- ASSERT_TRUE(std::count(meta_keys.cbegin(), meta_keys.cend(),
- metadata::android_packages_list) == 2);
+ Table package_list = metadata.Filter(
+ {metadata.name().eq(metadata::kNames[metadata::android_packages_list])});
+ ASSERT_EQ(package_list.row_count(), 2u);
- auto first_meta_idx = std::distance(
- meta_keys.cbegin(), std::find(meta_keys.cbegin(), meta_keys.cend(),
- metadata::android_packages_list));
- auto second_meta_idx = std::distance(
- meta_keys.cbegin(),
- std::find(meta_keys.cbegin() + first_meta_idx + 1, meta_keys.cend(),
- metadata::android_packages_list));
-
- uint32_t first_set_id = static_cast<uint32_t>(
- meta_values[static_cast<size_t>(first_meta_idx)].int_value);
- uint32_t second_set_id = static_cast<uint32_t>(
- meta_values[static_cast<size_t>(second_meta_idx)].int_value);
+ const Column* int_value = package_list.GetColumnByName("int_value");
+ uint32_t first_set_id = static_cast<uint32_t>(int_value->Get(0).long_value);
+ uint32_t second_set_id = static_cast<uint32_t>(int_value->Get(1).long_value);
// helper to look up arg values
auto find_arg = [&args, this](ArgSetId set_id, const char* arg_name) {
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 5beed38..dd143dd 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -21,6 +21,7 @@
#include "perfetto/protozero/proto_decoder.h"
#include "src/trace_processor/event_tracker.h"
#include "src/trace_processor/metadata.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/syscall_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
@@ -308,18 +309,18 @@
StringPool::Id machine_id =
context_->storage->InternString(utsname.machine());
- context_->storage->SetMetadata(metadata::system_name,
- Variadic::String(sysname_id));
- context_->storage->SetMetadata(metadata::system_version,
- Variadic::String(version_id));
- context_->storage->SetMetadata(metadata::system_release,
- Variadic::String(release_id));
- context_->storage->SetMetadata(metadata::system_machine,
- Variadic::String(machine_id));
+ MetadataTracker* metadata = context_->metadata_tracker.get();
+ metadata->SetMetadata(metadata::system_name, Variadic::String(sysname_id));
+ metadata->SetMetadata(metadata::system_version,
+ Variadic::String(version_id));
+ metadata->SetMetadata(metadata::system_release,
+ Variadic::String(release_id));
+ metadata->SetMetadata(metadata::system_machine,
+ Variadic::String(machine_id));
}
if (packet.has_android_build_fingerprint()) {
- context_->storage->SetMetadata(
+ context_->metadata_tracker->SetMetadata(
metadata::android_build_fingerprint,
Variadic::String(context_->storage->InternString(
packet.android_build_fingerprint())));
diff --git a/src/trace_processor/metadata.h b/src/trace_processor/metadata.h
index aad028f..e7edcd8 100644
--- a/src/trace_processor/metadata.h
+++ b/src/trace_processor/metadata.h
@@ -28,41 +28,58 @@
// Compile time list of metadata items.
// clang-format off
-#define PERFETTO_TP_METADATA(F) \
- F(benchmark_description, kSingle, Variadic::kString), \
- F(benchmark_name, kSingle, Variadic::kString), \
- F(benchmark_start_time_us, kSingle, Variadic::kInt), \
- F(benchmark_had_failures, kSingle, Variadic::kInt), \
- F(benchmark_label, kSingle, Variadic::kString), \
- F(benchmark_story_name, kSingle, Variadic::kString), \
- F(benchmark_story_run_index, kSingle, Variadic::kInt), \
- F(benchmark_story_run_time_us, kSingle, Variadic::kInt), \
- F(benchmark_story_tags, kMulti, Variadic::kString), \
- F(android_packages_list, kMulti, Variadic::kInt), \
- F(statsd_triggering_subscription_id, kSingle, Variadic::kInt), \
- F(trace_uuid, kSingle, Variadic::kString), \
- F(system_name, kSingle, Variadic::kString), \
- F(system_version, kSingle, Variadic::kString), \
- F(system_release, kSingle, Variadic::kString), \
- F(system_machine, kSingle, Variadic::kString), \
- F(android_build_fingerprint, kSingle, Variadic::kString)
+#define PERFETTO_TP_METADATA(F) \
+ F(benchmark_description, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_name, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_start_time_us, KeyType::kSingle, Variadic::kInt), \
+ F(benchmark_had_failures, KeyType::kSingle, Variadic::kInt), \
+ F(benchmark_label, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_story_name, KeyType::kSingle, Variadic::kString), \
+ F(benchmark_story_run_index, KeyType::kSingle, Variadic::kInt), \
+ F(benchmark_story_run_time_us, KeyType::kSingle, Variadic::kInt), \
+ F(benchmark_story_tags, KeyType::kMulti, Variadic::kString), \
+ F(android_packages_list, KeyType::kMulti, Variadic::kInt), \
+ F(statsd_triggering_subscription_id, KeyType::kSingle, Variadic::kInt), \
+ F(trace_uuid, KeyType::kSingle, Variadic::kString), \
+ F(system_name, KeyType::kSingle, Variadic::kString), \
+ F(system_version, KeyType::kSingle, Variadic::kString), \
+ F(system_release, KeyType::kSingle, Variadic::kString), \
+ F(system_machine, KeyType::kSingle, Variadic::kString), \
+ F(android_build_fingerprint, KeyType::kSingle, Variadic::kString)
// clang-format on
-enum KeyType {
- kSingle, // One value per key.
- kMulti // Multiple values per key.
+// Compile time list of metadata items.
+// clang-format off
+#define PERFETTO_TP_METADATA_KEY_TYPES(F) \
+ F(kSingle, "single"), \
+ F(kMulti, "multi")
+// clang-format
+
+#define PERFETTO_TP_META_TYPE_ENUM(varname, ...) varname
+enum class KeyType : size_t {
+ PERFETTO_TP_METADATA_KEY_TYPES(PERFETTO_TP_META_TYPE_ENUM),
+ kNumKeyTypes,
+};
+
+#define PERFETTO_TP_META_TYPE_NAME(_, name, ...) name
+constexpr char const* kKeyTypeNames[] = {
+ PERFETTO_TP_METADATA_KEY_TYPES(PERFETTO_TP_META_TYPE_NAME)
};
// Declares an enum of literals (one for each item). The enum values of each
// literal corresponds to the string index in the arrays below.
#define PERFETTO_TP_META_ENUM(name, ...) name
-enum KeyIDs : size_t { PERFETTO_TP_METADATA(PERFETTO_TP_META_ENUM), kNumKeys };
+enum KeyIDs : size_t {
+ PERFETTO_TP_METADATA(PERFETTO_TP_META_ENUM),
+ kNumKeys
+};
// The code below declares an array for each property:
// name, key type, value type.
#define PERFETTO_TP_META_NAME(name, ...) #name
-constexpr char const* kNames[] = {PERFETTO_TP_METADATA(PERFETTO_TP_META_NAME)};
+constexpr char const* kNames[] = {
+ PERFETTO_TP_METADATA(PERFETTO_TP_META_NAME)};
#define PERFETTO_TP_META_KEYTYPE(_, type, ...) type
constexpr KeyType kKeyTypes[] = {
diff --git a/src/trace_processor/metadata_table.cc b/src/trace_processor/metadata_table.cc
deleted file mode 100644
index a31a7c0..0000000
--- a/src/trace_processor/metadata_table.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/metadata_table.h"
-#include "src/trace_processor/sqlite/sqlite_utils.h"
-#include "src/trace_processor/storage_columns.h"
-#include "src/trace_processor/storage_schema.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-MetadataTable::MetadataTable(sqlite3*, const TraceStorage* storage)
- : storage_(storage) {}
-
-void MetadataTable::RegisterTable(sqlite3* db, const TraceStorage* storage) {
- SqliteTable::Register<MetadataTable>(db, storage, "metadata");
-}
-
-StorageSchema MetadataTable::CreateStorageSchema() {
- return StorageSchema::Builder()
- .AddColumn<StringColumn<MetadataKeyNameAccessor>>(
- "name", &storage_->metadata().keys())
- .AddColumn<StringColumn<MetadataKeyTypeAccessor>>(
- "key_type", &storage_->metadata().keys())
- .AddColumn<ValueColumn>("int_value", Variadic::Type::kInt, storage_)
- .AddColumn<ValueColumn>("str_value", Variadic::Type::kString, storage_)
- .Build({"name"});
-}
-
-uint32_t MetadataTable::RowCount() {
- return static_cast<uint32_t>(storage_->metadata().keys().size());
-}
-
-int MetadataTable::BestIndex(const QueryConstraints&, BestIndexInfo*) {
- return SQLITE_OK;
-}
-
-MetadataTable::MetadataKeyNameAccessor::MetadataKeyNameAccessor(
- const std::deque<metadata::KeyIDs>* keys)
- : keys_(keys) {}
-
-MetadataTable::MetadataKeyNameAccessor::~MetadataKeyNameAccessor() = default;
-
-MetadataTable::MetadataKeyTypeAccessor::MetadataKeyTypeAccessor(
- const std::deque<metadata::KeyIDs>* keys)
- : keys_(keys) {}
-
-MetadataTable::MetadataKeyTypeAccessor::~MetadataKeyTypeAccessor() = default;
-
-MetadataTable::ValueColumn::ValueColumn(std::string col_name,
- Variadic::Type type,
- const TraceStorage* storage)
- : StorageColumn(col_name, false /* hidden */),
- type_(type),
- storage_(storage) {
- PERFETTO_CHECK(type == Variadic::Type::kInt ||
- type == Variadic::Type::kString);
-}
-
-void MetadataTable::ValueColumn::ReportResult(sqlite3_context* ctx,
- uint32_t row) const {
- const auto& metadata = storage_->metadata();
- auto value_type = metadata::kValueTypes[metadata.keys()[row]];
- if (value_type != type_) {
- sqlite3_result_null(ctx);
- return;
- }
-
- if (value_type == Variadic::Type::kInt) {
- sqlite_utils::ReportSqliteResult(ctx, metadata.values()[row].int_value);
- return;
- }
- if (value_type == Variadic::Type::kString) {
- const char* str =
- storage_->GetString(metadata.values()[row].string_value).c_str();
- sqlite3_result_text(ctx, str, -1, sqlite_utils::kSqliteStatic);
- return;
- }
- PERFETTO_FATAL("Unimplemented metadata value type.");
-}
-
-MetadataTable::ValueColumn::Bounds MetadataTable::ValueColumn::BoundFilter(
- int,
- sqlite3_value*) const {
- return Bounds{};
-}
-
-void MetadataTable::ValueColumn::Filter(int op,
- sqlite3_value* value,
- FilteredRowIndex* index) const {
- if (type_ == Variadic::Type::kInt) {
- bool op_is_null = sqlite_utils::IsOpIsNull(op);
- auto predicate = sqlite_utils::CreateNumericPredicate<int64_t>(op, value);
- index->FilterRows(
- [this, predicate, op_is_null](uint32_t row) PERFETTO_ALWAYS_INLINE {
- const auto& arg = storage_->metadata().values()[row];
- return arg.type == type_ ? predicate(arg.int_value) : op_is_null;
- });
- return;
- }
- if (type_ == Variadic::Type::kString) {
- auto predicate = sqlite_utils::CreateStringPredicate(op, value);
- index->FilterRows([this, &predicate](uint32_t row) PERFETTO_ALWAYS_INLINE {
- const auto& arg = storage_->metadata().values()[row];
- return arg.type == type_
- ? predicate(storage_->GetString(arg.string_value).c_str())
- : predicate(nullptr);
- });
- return;
- }
- PERFETTO_FATAL("Unimplemented metadata value type.");
-}
-
-MetadataTable::ValueColumn::Comparator MetadataTable::ValueColumn::Sort(
- const QueryConstraints::OrderBy& ob) const {
- if (ob.desc) {
- return [this](uint32_t f, uint32_t s) { return -CompareRefsAsc(f, s); };
- }
- return [this](uint32_t f, uint32_t s) { return CompareRefsAsc(f, s); };
-}
-
-int MetadataTable::ValueColumn::CompareRefsAsc(uint32_t f, uint32_t s) const {
- const auto& arg_f = storage_->metadata().values()[f];
- const auto& arg_s = storage_->metadata().values()[s];
-
- if (arg_f.type == type_ && arg_s.type == type_) {
- if (type_ == Variadic::Type::kInt) {
- return sqlite_utils::CompareValuesAsc(arg_f.int_value, arg_s.int_value);
- }
- if (type_ == Variadic::Type::kString) {
- const auto& f_str = storage_->GetString(arg_f.string_value);
- const auto& s_str = storage_->GetString(arg_s.string_value);
- return sqlite_utils::CompareValuesAsc(f_str, s_str);
- }
- PERFETTO_FATAL("Unimplemented metadata value type.");
- } else if (arg_s.type == type_) {
- return -1;
- } else if (arg_f.type == type_) {
- return 1;
- }
- return 0;
-}
-
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/metadata_table.h b/src/trace_processor/metadata_table.h
deleted file mode 100644
index c7b0dfe..0000000
--- a/src/trace_processor/metadata_table.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_METADATA_TABLE_H_
-#define SRC_TRACE_PROCESSOR_METADATA_TABLE_H_
-
-#include "src/trace_processor/metadata.h"
-#include "src/trace_processor/storage_table.h"
-#include "src/trace_processor/trace_storage.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-class MetadataTable : public StorageTable {
- public:
- MetadataTable(sqlite3*, const TraceStorage*);
-
- static void RegisterTable(sqlite3* db, const TraceStorage* storage);
-
- // StorageTable implementation.
- StorageSchema CreateStorageSchema() override;
- uint32_t RowCount() override;
- int BestIndex(const QueryConstraints&, BestIndexInfo*) override;
-
- private:
- // Returns the stringified key enum name from metadata::kNames.
- class MetadataKeyNameAccessor : public Accessor<NullTermStringView> {
- public:
- MetadataKeyNameAccessor(const std::deque<metadata::KeyIDs>* keys);
- ~MetadataKeyNameAccessor() override;
-
- uint32_t Size() const override {
- return static_cast<uint32_t>(keys_->size());
- }
-
- NullTermStringView Get(uint32_t idx) const override {
- return NullTermStringView(metadata::kNames[(*keys_)[idx]]);
- }
-
- private:
- const std::deque<metadata::KeyIDs>* keys_;
- };
-
- // Returns the stringified metadata type, "single" for scalar, "multi" for
- // repeated.
- class MetadataKeyTypeAccessor : public Accessor<NullTermStringView> {
- public:
- MetadataKeyTypeAccessor(const std::deque<metadata::KeyIDs>* keys);
- ~MetadataKeyTypeAccessor() override;
-
- uint32_t Size() const override {
- return static_cast<uint32_t>(keys_->size());
- }
-
- NullTermStringView Get(uint32_t idx) const override {
- switch (metadata::kKeyTypes[(*keys_)[idx]]) {
- case metadata::KeyType::kSingle:
- return NullTermStringView("single");
- break;
- case metadata::KeyType::kMulti:
- return NullTermStringView("multi");
- break;
- }
- PERFETTO_FATAL("unsupported metadata type"); // for gcc
- }
-
- private:
- const std::deque<metadata::KeyIDs>* keys_;
- };
-
- // Returns values from Variadic storage. Only supports columns of
- // type Variadic::Type::kInt or Variadic::Type::kString.
- //
- // Based on ArgsTable::ValueColumn.
- class ValueColumn final : public StorageColumn {
- public:
- ValueColumn(std::string col_name,
- Variadic::Type type,
- const TraceStorage* storage);
-
- void ReportResult(sqlite3_context* ctx, uint32_t row) const override;
- Bounds BoundFilter(int op, sqlite3_value* sqlite_val) const override;
- void Filter(int op, sqlite3_value* value, FilteredRowIndex*) const override;
- Comparator Sort(const QueryConstraints::OrderBy& ob) const override;
-
- bool HasOrdering() const override { return false; }
-
- SqlValue::Type GetType() const override {
- if (type_ == Variadic::Type::kInt)
- return SqlValue::Type::kLong;
- if (type_ == Variadic::Type::kString)
- return SqlValue::Type::kString;
- PERFETTO_FATAL("Unimplemented metadata value type.");
- }
-
- private:
- int CompareRefsAsc(uint32_t f, uint32_t s) const;
-
- Variadic::Type type_;
- const TraceStorage* storage_ = nullptr;
- };
-
- const TraceStorage* const storage_;
-};
-
-} // namespace trace_processor
-} // namespace perfetto
-
-#endif // SRC_TRACE_PROCESSOR_METADATA_TABLE_H_
diff --git a/src/trace_processor/metadata_table_unittest.cc b/src/trace_processor/metadata_table_unittest.cc
deleted file mode 100644
index 9f8309c..0000000
--- a/src/trace_processor/metadata_table_unittest.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/metadata_table.h"
-#include "src/trace_processor/sqlite/scoped_db.h"
-#include "src/trace_processor/trace_processor_context.h"
-#include "src/trace_processor/trace_storage.h"
-#include "test/gtest_and_gmock.h"
-
-namespace perfetto {
-namespace trace_processor {
-namespace {
-
-class MetadataTableUnittest : public ::testing::Test {
- public:
- MetadataTableUnittest() {
- sqlite3* db = nullptr;
- PERFETTO_CHECK(sqlite3_initialize() == SQLITE_OK);
- PERFETTO_CHECK(sqlite3_open(":memory:", &db) == SQLITE_OK);
- db_.reset(db);
-
- context_.storage.reset(new TraceStorage());
- MetadataTable::RegisterTable(db_.get(), context_.storage.get());
- }
-
- void PrepareValidStatement(const std::string& sql) {
- int size = static_cast<int>(sql.size());
- sqlite3_stmt* stmt;
- ASSERT_EQ(sqlite3_prepare_v2(*db_, sql.c_str(), size, &stmt, nullptr),
- SQLITE_OK);
- stmt_.reset(stmt);
- }
-
- const char* GetColumnAsText(int colId) {
- return reinterpret_cast<const char*>(sqlite3_column_text(*stmt_, colId));
- }
-
- protected:
- TraceProcessorContext context_;
- ScopedDb db_;
- ScopedStmt stmt_;
-};
-
-TEST_F(MetadataTableUnittest, NoEntries) {
- PrepareValidStatement("SELECT * FROM metadata");
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_DONE);
-}
-
-TEST_F(MetadataTableUnittest, SingleStringValue) {
- static const char kName[] = "benchmark";
- Variadic value = Variadic::String(context_.storage->InternString(kName));
- context_.storage->SetMetadata(metadata::benchmark_name, value);
-
- PrepareValidStatement("SELECT * FROM metadata");
-
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_ROW);
- ASSERT_STREQ(GetColumnAsText(0), "benchmark_name"); // name
- ASSERT_STREQ(GetColumnAsText(1), "single"); // key_type
- ASSERT_EQ(sqlite3_column_type(*stmt_, 2), SQLITE_NULL); // int_value
- ASSERT_STREQ(GetColumnAsText(3), kName); // str_value
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_DONE);
-}
-
-TEST_F(MetadataTableUnittest, SingleIntegerValue) {
- static const int64_t kTimestamp = 1234567890;
- Variadic value = Variadic::Integer(kTimestamp);
- context_.storage->SetMetadata(metadata::benchmark_story_run_time_us, value);
-
- PrepareValidStatement("SELECT * FROM metadata");
-
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_ROW);
- ASSERT_STREQ(GetColumnAsText(0), "benchmark_story_run_time_us"); // name
- ASSERT_STREQ(GetColumnAsText(1), "single"); // key_type
- ASSERT_EQ(sqlite3_column_int64(*stmt_, 2), kTimestamp); // int_value
- ASSERT_EQ(sqlite3_column_type(*stmt_, 3), SQLITE_NULL); // str_value
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_DONE);
-}
-
-TEST_F(MetadataTableUnittest, MultipleStringValues) {
- static const char kTag1[] = "foo";
- static const char kTag2[] = "bar";
- Variadic tag1 = Variadic::String(context_.storage->InternString(kTag1));
- Variadic tag2 = Variadic::String(context_.storage->InternString(kTag2));
- context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag1);
- context_.storage->AppendMetadata(metadata::benchmark_story_tags, tag2);
-
- PrepareValidStatement("SELECT * FROM metadata");
-
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_ROW);
- ASSERT_STREQ(GetColumnAsText(0), "benchmark_story_tags"); // name
- ASSERT_STREQ(GetColumnAsText(1), "multi"); // key_type
- ASSERT_EQ(sqlite3_column_type(*stmt_, 2), SQLITE_NULL); // int_value
- ASSERT_STREQ(GetColumnAsText(3), kTag1); // str_value
-
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_ROW);
- ASSERT_STREQ(GetColumnAsText(0), "benchmark_story_tags"); // name
- ASSERT_STREQ(GetColumnAsText(1), "multi"); // key_type
- ASSERT_EQ(sqlite3_column_type(*stmt_, 2), SQLITE_NULL); // int_value
- ASSERT_STREQ(GetColumnAsText(3), kTag2); // str_value
-
- ASSERT_EQ(sqlite3_step(*stmt_), SQLITE_DONE);
-}
-
-} // namespace
-} // namespace trace_processor
-} // namespace perfetto
diff --git a/src/trace_processor/metadata_tracker.cc b/src/trace_processor/metadata_tracker.cc
new file mode 100644
index 0000000..e105d01
--- /dev/null
+++ b/src/trace_processor/metadata_tracker.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/metadata_tracker.h"
+
+#include "src/trace_processor/process_tracker.h"
+#include "src/trace_processor/trace_processor_context.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+MetadataTracker::MetadataTracker(TraceProcessorContext* context)
+ : context_(context) {
+ for (uint32_t i = 0; i < kNumKeys; ++i) {
+ key_ids_[i] = context->storage->InternString(metadata::kNames[i]);
+ }
+ for (uint32_t i = 0; i < kNumKeyTypes; ++i) {
+ key_type_ids_[i] =
+ context->storage->InternString(metadata::kKeyTypeNames[i]);
+ }
+}
+
+MetadataId MetadataTracker::SetMetadata(metadata::KeyIDs key, Variadic value) {
+ PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
+ PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
+
+ auto* metadata_table = context_->storage->mutable_metadata_table();
+ uint32_t key_idx = static_cast<uint32_t>(key);
+ base::Optional<uint32_t> opt_row =
+ metadata_table->name().IndexOf(metadata::kNames[key_idx]);
+ if (opt_row) {
+ WriteValue(*opt_row, value);
+ return metadata_table->id()[*opt_row];
+ }
+
+ tables::MetadataTable::Row row;
+ row.name = key_ids_[key_idx];
+ row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
+
+ MetadataId id = metadata_table->Insert(row);
+ WriteValue(*metadata_table->id().IndexOf(id), value);
+ return id;
+}
+
+MetadataId MetadataTracker::AppendMetadata(metadata::KeyIDs key,
+ Variadic value) {
+ PERFETTO_DCHECK(key < metadata::kNumKeys);
+ PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kMulti);
+ PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
+
+ uint32_t key_idx = static_cast<uint32_t>(key);
+ tables::MetadataTable::Row row;
+ row.name = key_ids_[key_idx];
+ row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kMulti)];
+
+ auto* metadata_table = context_->storage->mutable_metadata_table();
+ MetadataId id = metadata_table->Insert(row);
+ WriteValue(*metadata_table->id().IndexOf(id), value);
+ return id;
+}
+
+void MetadataTracker::WriteValue(uint32_t row, Variadic value) {
+ auto* metadata_table = context_->storage->mutable_metadata_table();
+ switch (value.type) {
+ case Variadic::Type::kInt:
+ metadata_table->mutable_int_value()->Set(row, value.int_value);
+ break;
+ case Variadic::Type::kString:
+ metadata_table->mutable_str_value()->Set(row, value.string_value);
+ break;
+ case Variadic::Type::kJson:
+ case Variadic::Type::kBool:
+ case Variadic::Type::kPointer:
+ case Variadic::Type::kUint:
+ case Variadic::Type::kReal:
+ PERFETTO_FATAL("Unsupported value type");
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/metadata_tracker.h b/src/trace_processor/metadata_tracker.h
new file mode 100644
index 0000000..38685ac
--- /dev/null
+++ b/src/trace_processor/metadata_tracker.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_METADATA_TRACKER_H_
+#define SRC_TRACE_PROCESSOR_METADATA_TRACKER_H_
+
+#include "src/trace_processor/trace_storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Tracks information in the metadata table.
+class MetadataTracker {
+ public:
+ MetadataTracker(TraceProcessorContext* context);
+
+ // Example usage:
+ // SetMetadata(metadata::benchmark_name,
+ // Variadic::String(storage->InternString("foo"));
+ // Returns the id of the new entry.
+ MetadataId SetMetadata(metadata::KeyIDs key, Variadic value);
+
+ // Example usage:
+ // AppendMetadata(metadata::benchmark_story_tags,
+ // Variadic::String(storage->InternString("bar"));
+ // Returns the id of the new entry.
+ MetadataId AppendMetadata(metadata::KeyIDs key, Variadic value);
+
+ private:
+ static constexpr size_t kNumKeys =
+ static_cast<size_t>(metadata::KeyIDs::kNumKeys);
+ static constexpr size_t kNumKeyTypes =
+ static_cast<size_t>(metadata::KeyType::kNumKeyTypes);
+
+ void WriteValue(uint32_t row, Variadic value);
+
+ std::array<StringId, kNumKeys> key_ids_;
+ std::array<StringId, kNumKeyTypes> key_type_ids_;
+
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_METADATA_TRACKER_H_
diff --git a/src/trace_processor/raw_table.cc b/src/trace_processor/raw_table.cc
index f657650..ac8127f 100644
--- a/src/trace_processor/raw_table.cc
+++ b/src/trace_processor/raw_table.cc
@@ -96,20 +96,22 @@
}
bool RawTable::ParseGfpFlags(Variadic value, base::StringWriter* writer) {
- if (!storage_->metadata().MetadataExists(metadata::KeyIDs::system_name) ||
- !storage_->metadata().MetadataExists(metadata::KeyIDs::system_release)) {
- return false;
- }
+ const auto& metadata_table = storage_->metadata_table();
- const Variadic& name =
- storage_->metadata().GetScalarMetadata(metadata::KeyIDs::system_name);
- base::StringView system_name = storage_->GetString(name.string_value);
+ auto opt_name_idx = metadata_table.name().IndexOf(
+ metadata::kNames[metadata::KeyIDs::system_name]);
+ auto opt_release_idx = metadata_table.name().IndexOf(
+ metadata::kNames[metadata::KeyIDs::system_release]);
+ if (!opt_name_idx || !opt_release_idx)
+ return false;
+
+ StringId name = metadata_table.str_value()[*opt_name_idx];
+ base::StringView system_name = storage_->GetString(name);
if (system_name != "Linux")
return false;
- const Variadic& release =
- storage_->metadata().GetScalarMetadata(metadata::KeyIDs::system_release);
- base::StringView system_release = storage_->GetString(release.string_value);
+ StringId release = metadata_table.str_value()[*opt_release_idx];
+ base::StringView system_release = storage_->GetString(release);
auto version = ParseKernelReleaseVersion(system_release);
WriteGfpFlag(value.uint_value, version, writer);
diff --git a/src/trace_processor/tables/BUILD.gn b/src/trace_processor/tables/BUILD.gn
index aebd76c..268e419 100644
--- a/src/trace_processor/tables/BUILD.gn
+++ b/src/trace_processor/tables/BUILD.gn
@@ -20,6 +20,7 @@
"counter_tables.h",
"macros.h",
"macros_internal.h",
+ "metadata_tables.h",
"profiler_tables.h",
"slice_tables.h",
"track_tables.h",
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
new file mode 100644
index 0000000..9a2095d
--- /dev/null
+++ b/src/trace_processor/tables/metadata_tables.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
+#define SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
+
+#include "src/trace_processor/tables/macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace tables {
+
+#define PERFETTO_TP_METADATA_TABLE_DEF(NAME, PARENT, C) \
+ NAME(MetadataTable, "metadata") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(StringPool::Id, name) \
+ C(StringPool::Id, key_type) \
+ C(base::Optional<int64_t>, int_value) \
+ C(base::Optional<StringPool::Id>, str_value)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_METADATA_TABLE_DEF);
+
+} // namespace tables
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_TABLES_METADATA_TABLES_H_
diff --git a/src/trace_processor/trace_processor_context.cc b/src/trace_processor/trace_processor_context.cc
index dbefd62..52ec6de 100644
--- a/src/trace_processor/trace_processor_context.cc
+++ b/src/trace_processor/trace_processor_context.cc
@@ -25,6 +25,7 @@
#include "src/trace_processor/importers/json/json_trace_parser.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stack_profile_tracker.h"
diff --git a/src/trace_processor/trace_processor_context.h b/src/trace_processor/trace_processor_context.h
index 2fd3c15..10e6eb4 100644
--- a/src/trace_processor/trace_processor_context.h
+++ b/src/trace_processor/trace_processor_context.h
@@ -35,6 +35,7 @@
class FtraceModule;
class HeapGraphTracker;
class HeapProfileTracker;
+class MetadataTracker;
class ProcessTracker;
class SliceTracker;
class TraceParser;
@@ -60,6 +61,7 @@
std::unique_ptr<TraceSorter> sorter;
std::unique_ptr<ChunkedTraceReader> chunk_reader;
std::unique_ptr<HeapProfileTracker> heap_profile_tracker;
+ std::unique_ptr<MetadataTracker> metadata_tracker;
// These fields are stored as pointers to Destructible objects rather than
// their actual type (a subclass of Destructible), as the concrete subclass
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 191780b..c843df7 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -25,7 +25,6 @@
#include "perfetto/ext/base/string_utils.h"
#include "src/trace_processor/args_table.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
-#include "src/trace_processor/metadata_table.h"
#include "src/trace_processor/process_table.h"
#include "src/trace_processor/raw_table.h"
#include "src/trace_processor/register_additional_modules.h"
@@ -379,7 +378,6 @@
WindowOperatorTable::RegisterTable(*db_, context_.storage.get());
StatsTable::RegisterTable(*db_, context_.storage.get());
RawTable::RegisterTable(*db_, context_.storage.get());
- MetadataTable::RegisterTable(*db_, context_.storage.get());
// New style db-backed tables.
const TraceStorage* storage = context_.storage.get();
@@ -451,6 +449,9 @@
DbSqliteTable::RegisterTable(
*db_, &storage->vulkan_memory_allocations_table(),
storage->vulkan_memory_allocations_table().table_name());
+
+ DbSqliteTable::RegisterTable(*db_, &storage->metadata_table(),
+ storage->metadata_table().table_name());
}
TraceProcessorImpl::~TraceProcessorImpl() {
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index 9e0726d..0ad11ee 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -26,6 +26,7 @@
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
+#include "src/trace_processor/metadata_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stack_profile_tracker.h"
@@ -46,6 +47,7 @@
context_.process_tracker.reset(new ProcessTracker(&context_));
context_.clock_tracker.reset(new ClockTracker(&context_));
context_.heap_profile_tracker.reset(new HeapProfileTracker(&context_));
+ context_.metadata_tracker.reset(new MetadataTracker(&context_));
context_.modules.emplace_back(new FtraceModule());
// Ftrace module is special, because it has one extra method for parsing
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index 2faa5d9..83a609b 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -38,6 +38,7 @@
#include "src/trace_processor/stats.h"
#include "src/trace_processor/tables/android_tables.h"
#include "src/trace_processor/tables/counter_tables.h"
+#include "src/trace_processor/tables/metadata_tables.h"
#include "src/trace_processor/tables/profiler_tables.h"
#include "src/trace_processor/tables/slice_tables.h"
#include "src/trace_processor/tables/track_tables.h"
@@ -85,6 +86,8 @@
using MappingId = tables::StackProfileMappingTable::Id;
+using MetadataId = tables::MetadataTable::Id;
+
// TODO(lalitm): this is a temporary hack while migrating the counters table and
// will be removed when the migration is complete.
static const TrackId kInvalidTrackId =
@@ -479,64 +482,6 @@
};
using StatsMap = std::array<Stats, stats::kNumKeys>;
- class Metadata {
- public:
- const std::deque<metadata::KeyIDs>& keys() const { return keys_; }
- const std::deque<Variadic>& values() const { return values_; }
-
- uint32_t SetScalarMetadata(metadata::KeyIDs key, Variadic value) {
- PERFETTO_DCHECK(key < metadata::kNumKeys);
- PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::kSingle);
- PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
-
- // Already set - on release builds, overwrite the previous value.
- auto it = scalar_indices.find(key);
- if (it != scalar_indices.end()) {
- PERFETTO_DFATAL("Setting a scalar metadata entry more than once.");
- uint32_t index = static_cast<uint32_t>(it->second);
- values_[index] = value;
- return index;
- }
- // First time setting this key.
- keys_.push_back(key);
- values_.push_back(value);
- uint32_t index = static_cast<uint32_t>(keys_.size() - 1);
- scalar_indices[key] = index;
- return index;
- }
-
- uint32_t AppendMetadata(metadata::KeyIDs key, Variadic value) {
- PERFETTO_DCHECK(key < metadata::kNumKeys);
- PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::kMulti);
- PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
-
- keys_.push_back(key);
- values_.push_back(value);
- return static_cast<uint32_t>(keys_.size() - 1);
- }
-
- const Variadic& GetScalarMetadata(metadata::KeyIDs key) const {
- PERFETTO_DCHECK(scalar_indices.count(key) == 1);
- return values_.at(scalar_indices.at(key));
- }
-
- bool MetadataExists(metadata::KeyIDs key) const {
- return scalar_indices.count(key) >= 1;
- }
-
- void OverwriteMetadata(uint32_t index, Variadic value) {
- PERFETTO_DCHECK(index < values_.size());
- values_[index] = value;
- }
-
- private:
- std::deque<metadata::KeyIDs> keys_;
- std::deque<Variadic> values_;
- // Extraneous state to track locations of entries that should have at most
- // one row. Used only to maintain uniqueness during insertions.
- std::map<metadata::KeyIDs, uint32_t> scalar_indices;
- };
-
UniqueTid AddEmptyThread(uint32_t tid) {
unique_threads_.emplace_back(tid);
return static_cast<UniqueTid>(unique_threads_.size() - 1);
@@ -592,24 +537,6 @@
stats_[key].indexed_values[index] = value;
}
- // Example usage:
- // SetMetadata(metadata::benchmark_name,
- // Variadic::String(storage->InternString("foo"));
- // Returns the row of the new entry.
- // Virtual for testing.
- virtual uint32_t SetMetadata(metadata::KeyIDs key, Variadic value) {
- return metadata_.SetScalarMetadata(key, value);
- }
-
- // Example usage:
- // AppendMetadata(metadata::benchmark_story_tags,
- // Variadic::String(storage->InternString("bar"));
- // Returns the row of the new entry.
- // Virtual for testing.
- virtual uint32_t AppendMetadata(metadata::KeyIDs key, Variadic value) {
- return metadata_.AppendMetadata(key, value);
- }
-
class ScopedStatsTracer {
public:
ScopedStatsTracer(TraceStorage* storage, size_t key)
@@ -772,8 +699,10 @@
const StatsMap& stats() const { return stats_; }
- const Metadata& metadata() const { return metadata_; }
- Metadata* mutable_metadata() { return &metadata_; }
+ const tables::MetadataTable& metadata_table() const {
+ return metadata_table_;
+ }
+ tables::MetadataTable* mutable_metadata_table() { return &metadata_table_; }
const Args& args() const { return args_; }
Args* mutable_args() { return &args_; }
@@ -925,7 +854,7 @@
// Extra data extracted from the trace. Includes:
// * metadata from chrome and benchmarking infrastructure
// * descriptions of android packages
- Metadata metadata_{};
+ tables::MetadataTable metadata_table_{&string_pool_, nullptr};
// Metadata for tracks.
tables::TrackTable track_table_{&string_pool_, nullptr};
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
index d8a8f7f..5cfece7 100755
--- a/tools/gen_merged_protos
+++ b/tools/gen_merged_protos
@@ -99,6 +99,8 @@
'protos/perfetto/trace/track_event/chrome_histogram_sample.proto',
'protos/perfetto/trace/track_event/chrome_keyed_service.proto',
'protos/perfetto/trace/track_event/chrome_legacy_ipc.proto',
+ 'protos/perfetto/trace/track_event/chrome_process_descriptor.proto',
+ 'protos/perfetto/trace/track_event/chrome_thread_descriptor.proto',
'protos/perfetto/trace/track_event/chrome_user_event.proto',
'protos/perfetto/trace/track_event/debug_annotation.proto',
'protos/perfetto/trace/track_event/log_message.proto',