• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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