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/proto/metadata_tracker.h"
18 
19 #include "src/trace_processor/importers/common/process_tracker.h"
20 #include "src/trace_processor/types/trace_processor_context.h"
21 
22 namespace perfetto {
23 namespace trace_processor {
24 
MetadataTracker(TraceProcessorContext * context)25 MetadataTracker::MetadataTracker(TraceProcessorContext* context)
26     : context_(context) {
27   for (uint32_t i = 0; i < kNumKeys; ++i) {
28     key_ids_[i] = context->storage->InternString(metadata::kNames[i]);
29   }
30   for (uint32_t i = 0; i < kNumKeyTypes; ++i) {
31     key_type_ids_[i] =
32         context->storage->InternString(metadata::kKeyTypeNames[i]);
33   }
34 }
35 
SetMetadata(metadata::KeyId key,Variadic value)36 MetadataId MetadataTracker::SetMetadata(metadata::KeyId key, Variadic value) {
37   PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
38   PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
39 
40   auto* metadata_table = context_->storage->mutable_metadata_table();
41   uint32_t key_idx = static_cast<uint32_t>(key);
42   base::Optional<uint32_t> opt_row =
43       metadata_table->name().IndexOf(metadata::kNames[key_idx]);
44   if (opt_row) {
45     WriteValue(*opt_row, value);
46     return metadata_table->id()[*opt_row];
47   }
48 
49   tables::MetadataTable::Row row;
50   row.name = key_ids_[key_idx];
51   row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
52 
53   auto id_and_row = metadata_table->Insert(row);
54   WriteValue(id_and_row.row, value);
55   return id_and_row.id;
56 }
57 
GetMetadataForTesting(metadata::KeyId key)58 SqlValue MetadataTracker::GetMetadataForTesting(metadata::KeyId key) {
59   // KeyType::kMulti not yet supported by this method:
60   PERFETTO_CHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
61 
62   auto* metadata_table = context_->storage->mutable_metadata_table();
63   uint32_t key_idx = static_cast<uint32_t>(key);
64   uint32_t row =
65       metadata_table->name().IndexOf(metadata::kNames[key_idx]).value();
66   return metadata_table->mutable_str_value()->Get(row);
67 }
68 
AppendMetadata(metadata::KeyId key,Variadic value)69 MetadataId MetadataTracker::AppendMetadata(metadata::KeyId key,
70                                            Variadic value) {
71   PERFETTO_DCHECK(key < metadata::kNumKeys);
72   PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kMulti);
73   PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
74 
75   uint32_t key_idx = static_cast<uint32_t>(key);
76   tables::MetadataTable::Row row;
77   row.name = key_ids_[key_idx];
78   row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kMulti)];
79 
80   auto* metadata_table = context_->storage->mutable_metadata_table();
81   auto id_and_row = metadata_table->Insert(row);
82   WriteValue(id_and_row.row, value);
83   return id_and_row.id;
84 }
85 
SetDynamicMetadata(StringId key,Variadic value)86 MetadataId MetadataTracker::SetDynamicMetadata(StringId key, Variadic value) {
87   tables::MetadataTable::Row row;
88   row.name = key;
89   row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
90 
91   auto* metadata_table = context_->storage->mutable_metadata_table();
92   auto id_and_row = metadata_table->Insert(row);
93   WriteValue(id_and_row.row, value);
94   return id_and_row.id;
95 }
96 
WriteValue(uint32_t row,Variadic value)97 void MetadataTracker::WriteValue(uint32_t row, Variadic value) {
98   auto* metadata_table = context_->storage->mutable_metadata_table();
99   switch (value.type) {
100     case Variadic::Type::kInt:
101       metadata_table->mutable_int_value()->Set(row, value.int_value);
102       break;
103     case Variadic::Type::kString:
104       metadata_table->mutable_str_value()->Set(row, value.string_value);
105       break;
106     case Variadic::Type::kJson:
107       metadata_table->mutable_str_value()->Set(row, value.json_value);
108       break;
109     case Variadic::Type::kBool:
110     case Variadic::Type::kPointer:
111     case Variadic::Type::kUint:
112     case Variadic::Type::kReal:
113       PERFETTO_FATAL("Unsupported value type");
114   }
115 }
116 
117 }  // namespace trace_processor
118 }  // namespace perfetto
119