1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/importers/common/metadata_tracker.h"
18
19 #include "perfetto/ext/base/crash_keys.h"
20 #include "src/trace_processor/storage/metadata.h"
21 #include "src/trace_processor/types/trace_processor_context.h"
22
23 namespace perfetto {
24 namespace trace_processor {
25
26 namespace {
27
28 base::CrashKey g_crash_key_uuid("trace_uuid");
29
30 }
31
MetadataTracker(TraceStorage * storage)32 MetadataTracker::MetadataTracker(TraceStorage* storage) : storage_(storage) {
33 for (uint32_t i = 0; i < kNumKeys; ++i) {
34 key_ids_[i] = storage->InternString(metadata::kNames[i]);
35 }
36 for (uint32_t i = 0; i < kNumKeyTypes; ++i) {
37 key_type_ids_[i] = storage->InternString(metadata::kKeyTypeNames[i]);
38 }
39 }
40
SetMetadata(metadata::KeyId key,Variadic value)41 MetadataId MetadataTracker::SetMetadata(metadata::KeyId key, Variadic value) {
42 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
43 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
44
45 // When the trace_uuid is set, store a copy in a crash key, so in case of
46 // a crash in the pipelines we can tell which trace caused the crash.
47 if (key == metadata::trace_uuid && value.type == Variadic::kString) {
48 auto uuid_string_view = storage_->GetString(value.string_value);
49 g_crash_key_uuid.Set(uuid_string_view);
50 }
51
52 auto* metadata_table = storage_->mutable_metadata_table();
53 uint32_t key_idx = static_cast<uint32_t>(key);
54 std::optional<uint32_t> opt_row =
55 metadata_table->name().IndexOf(metadata::kNames[key_idx]);
56 if (opt_row) {
57 WriteValue(*opt_row, value);
58 return metadata_table->id()[*opt_row];
59 }
60
61 tables::MetadataTable::Row row;
62 row.name = key_ids_[key_idx];
63 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
64
65 auto id_and_row = metadata_table->Insert(row);
66 WriteValue(id_and_row.row, value);
67 return id_and_row.id;
68 }
69
GetMetadata(metadata::KeyId key)70 std::optional<SqlValue> MetadataTracker::GetMetadata(metadata::KeyId key) {
71 // KeyType::kMulti not yet supported by this method:
72 PERFETTO_CHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
73
74 auto* metadata_table = storage_->mutable_metadata_table();
75 uint32_t key_idx = static_cast<uint32_t>(key);
76 std::optional<uint32_t> row =
77 metadata_table->name().IndexOf(metadata::kNames[key_idx]);
78 if (!row.has_value())
79 return {};
80
81 auto value_type = metadata::kValueTypes[key];
82 switch (value_type) {
83 case Variadic::kInt:
84 return metadata_table->mutable_int_value()->Get(*row);
85 case Variadic::kString:
86 return metadata_table->mutable_str_value()->Get(*row);
87 case Variadic::kNull:
88 return SqlValue();
89 case Variadic::kJson:
90 case Variadic::kUint:
91 case Variadic::kPointer:
92 case Variadic::kReal:
93 case Variadic::kBool:
94 PERFETTO_FATAL("Invalid metadata value type %zu", value_type);
95 }
96 PERFETTO_FATAL("For GCC");
97 }
98
AppendMetadata(metadata::KeyId key,Variadic value)99 MetadataId MetadataTracker::AppendMetadata(metadata::KeyId key,
100 Variadic value) {
101 PERFETTO_DCHECK(key < metadata::kNumKeys);
102 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kMulti);
103 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
104
105 uint32_t key_idx = static_cast<uint32_t>(key);
106 tables::MetadataTable::Row row;
107 row.name = key_ids_[key_idx];
108 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kMulti)];
109
110 auto* metadata_table = storage_->mutable_metadata_table();
111 auto id_and_row = metadata_table->Insert(row);
112 WriteValue(id_and_row.row, value);
113 return id_and_row.id;
114 }
115
SetDynamicMetadata(StringId key,Variadic value)116 MetadataId MetadataTracker::SetDynamicMetadata(StringId key, Variadic value) {
117 tables::MetadataTable::Row row;
118 row.name = key;
119 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
120
121 auto* metadata_table = storage_->mutable_metadata_table();
122 auto id_and_row = metadata_table->Insert(row);
123 WriteValue(id_and_row.row, value);
124 return id_and_row.id;
125 }
126
WriteValue(uint32_t row,Variadic value)127 void MetadataTracker::WriteValue(uint32_t row, Variadic value) {
128 auto* metadata_table = storage_->mutable_metadata_table();
129 switch (value.type) {
130 case Variadic::Type::kInt:
131 metadata_table->mutable_int_value()->Set(row, value.int_value);
132 break;
133 case Variadic::Type::kString:
134 metadata_table->mutable_str_value()->Set(row, value.string_value);
135 break;
136 case Variadic::Type::kJson:
137 metadata_table->mutable_str_value()->Set(row, value.json_value);
138 break;
139 case Variadic::Type::kBool:
140 case Variadic::Type::kPointer:
141 case Variadic::Type::kUint:
142 case Variadic::Type::kReal:
143 case Variadic::Type::kNull:
144 PERFETTO_FATAL("Unsupported value type");
145 }
146 }
147
148 } // namespace trace_processor
149 } // namespace perfetto
150