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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_ 19 20 #include <cstdint> 21 #include "perfetto/ext/base/small_vector.h" 22 #include "src/trace_processor/importers/common/global_args_tracker.h" 23 #include "src/trace_processor/storage/trace_storage.h" 24 #include "src/trace_processor/tables/metadata_tables_py.h" 25 #include "src/trace_processor/types/trace_processor_context.h" 26 #include "src/trace_processor/types/variadic.h" 27 28 namespace perfetto { 29 namespace trace_processor { 30 31 // Tracks and stores args for rows until the end of the packet. This allows 32 // allows args to pushed as a group into storage. 33 class ArgsTracker { 34 public: 35 using UpdatePolicy = GlobalArgsTracker::UpdatePolicy; 36 using CompactArg = GlobalArgsTracker::CompactArg; 37 using CompactArgSet = base::SmallVector<CompactArg, 16>; 38 39 // Stores the table and row at creation time which args are associated with. 40 // This allows callers to directly add args without repeating the row the 41 // args should be associated with. 42 class BoundInserter { 43 public: 44 virtual ~BoundInserter(); 45 46 BoundInserter(BoundInserter&&) noexcept = default; 47 BoundInserter& operator=(BoundInserter&&) noexcept = default; 48 49 BoundInserter(const BoundInserter&) = delete; 50 BoundInserter& operator=(const BoundInserter&) = delete; 51 52 // Adds an arg with the same key and flat_key. 53 BoundInserter& AddArg( 54 StringId key, 55 Variadic v, 56 UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) { 57 return AddArg(key, key, v, update_policy); 58 } 59 60 virtual BoundInserter& AddArg( 61 StringId flat_key, 62 StringId key, 63 Variadic v, 64 UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) { 65 args_tracker_->AddArg(arg_set_id_column_, row_, flat_key, key, v, 66 update_policy); 67 return *this; 68 } 69 70 // IncrementArrayEntryIndex() and GetNextArrayEntryIndex() provide a way to 71 // track the next array index for an array under a specific key. GetNextArrayEntryIndex(StringId key)72 size_t GetNextArrayEntryIndex(StringId key) { 73 // Zero-initializes |key| in the map if it doesn't exist yet. 74 return args_tracker_ 75 ->array_indexes_[std::make_tuple(arg_set_id_column_, row_, key)]; 76 } 77 78 // Returns the next available array index after increment. IncrementArrayEntryIndex(StringId key)79 size_t IncrementArrayEntryIndex(StringId key) { 80 // Zero-initializes |key| in the map if it doesn't exist yet. 81 return ++args_tracker_->array_indexes_[std::make_tuple(arg_set_id_column_, 82 row_, key)]; 83 } 84 85 protected: 86 BoundInserter(ArgsTracker* args_tracker, 87 ColumnLegacy* arg_set_id_column, 88 uint32_t row); 89 90 private: 91 friend class ArgsTracker; 92 93 ArgsTracker* args_tracker_ = nullptr; 94 ColumnLegacy* arg_set_id_column_ = nullptr; 95 uint32_t row_ = 0; 96 }; 97 98 explicit ArgsTracker(TraceProcessorContext*); 99 100 ArgsTracker(const ArgsTracker&) = delete; 101 ArgsTracker& operator=(const ArgsTracker&) = delete; 102 103 ArgsTracker(ArgsTracker&&) = default; 104 ArgsTracker& operator=(ArgsTracker&&) = default; 105 106 virtual ~ArgsTracker(); 107 AddArgsTo(tables::ChromeRawTable::Id id)108 BoundInserter AddArgsTo(tables::ChromeRawTable::Id id) { 109 return AddArgsTo(context_->storage->mutable_chrome_raw_table(), id); 110 } 111 AddArgsTo(tables::FtraceEventTable::Id id)112 BoundInserter AddArgsTo(tables::FtraceEventTable::Id id) { 113 return AddArgsTo(context_->storage->mutable_ftrace_event_table(), id); 114 } 115 AddArgsTo(CounterId id)116 BoundInserter AddArgsTo(CounterId id) { 117 return AddArgsTo(context_->storage->mutable_counter_table(), id); 118 } 119 AddArgsTo(SliceId id)120 BoundInserter AddArgsTo(SliceId id) { 121 return AddArgsTo(context_->storage->mutable_slice_table(), id); 122 } 123 AddArgsTo(tables::FlowTable::Id id)124 BoundInserter AddArgsTo(tables::FlowTable::Id id) { 125 return AddArgsTo(context_->storage->mutable_flow_table(), id); 126 } 127 AddArgsTo(tables::InputMethodClientsTable::Id id)128 BoundInserter AddArgsTo(tables::InputMethodClientsTable::Id id) { 129 return AddArgsTo(context_->storage->mutable_inputmethod_clients_table(), 130 id); 131 } 132 AddArgsTo(tables::InputMethodServiceTable::Id id)133 BoundInserter AddArgsTo(tables::InputMethodServiceTable::Id id) { 134 return AddArgsTo(context_->storage->mutable_inputmethod_service_table(), 135 id); 136 } 137 AddArgsTo(tables::InputMethodManagerServiceTable::Id id)138 BoundInserter AddArgsTo(tables::InputMethodManagerServiceTable::Id id) { 139 return AddArgsTo( 140 context_->storage->mutable_inputmethod_manager_service_table(), id); 141 } 142 AddArgsTo(tables::MemorySnapshotNodeTable::Id id)143 BoundInserter AddArgsTo(tables::MemorySnapshotNodeTable::Id id) { 144 return AddArgsTo(context_->storage->mutable_memory_snapshot_node_table(), 145 id); 146 } 147 AddArgsTo(tables::SurfaceFlingerLayersSnapshotTable::Id id)148 BoundInserter AddArgsTo(tables::SurfaceFlingerLayersSnapshotTable::Id id) { 149 return AddArgsTo( 150 context_->storage->mutable_surfaceflinger_layers_snapshot_table(), id); 151 } 152 AddArgsTo(tables::SurfaceFlingerLayerTable::Id id)153 BoundInserter AddArgsTo(tables::SurfaceFlingerLayerTable::Id id) { 154 return AddArgsTo(context_->storage->mutable_surfaceflinger_layer_table(), 155 id); 156 } 157 AddArgsTo(tables::SurfaceFlingerTransactionsTable::Id id)158 BoundInserter AddArgsTo(tables::SurfaceFlingerTransactionsTable::Id id) { 159 return AddArgsTo( 160 context_->storage->mutable_surfaceflinger_transactions_table(), id); 161 } 162 AddArgsTo(tables::ViewCaptureTable::Id id)163 BoundInserter AddArgsTo(tables::ViewCaptureTable::Id id) { 164 return AddArgsTo(context_->storage->mutable_viewcapture_table(), id); 165 } 166 AddArgsTo(tables::ViewCaptureViewTable::Id id)167 BoundInserter AddArgsTo(tables::ViewCaptureViewTable::Id id) { 168 return AddArgsTo(context_->storage->mutable_viewcapture_view_table(), id); 169 } 170 AddArgsTo(tables::WindowManagerTable::Id id)171 BoundInserter AddArgsTo(tables::WindowManagerTable::Id id) { 172 return AddArgsTo(context_->storage->mutable_windowmanager_table(), id); 173 } 174 AddArgsTo(tables::WindowManagerShellTransitionsTable::Id id)175 BoundInserter AddArgsTo(tables::WindowManagerShellTransitionsTable::Id id) { 176 return AddArgsTo( 177 context_->storage->mutable_window_manager_shell_transitions_table(), 178 id); 179 } 180 AddArgsTo(tables::AndroidKeyEventsTable::Id id)181 BoundInserter AddArgsTo(tables::AndroidKeyEventsTable::Id id) { 182 return AddArgsTo(context_->storage->mutable_android_key_events_table(), id); 183 } 184 AddArgsTo(tables::AndroidMotionEventsTable::Id id)185 BoundInserter AddArgsTo(tables::AndroidMotionEventsTable::Id id) { 186 return AddArgsTo(context_->storage->mutable_android_motion_events_table(), 187 id); 188 } 189 AddArgsTo(tables::AndroidInputEventDispatchTable::Id id)190 BoundInserter AddArgsTo(tables::AndroidInputEventDispatchTable::Id id) { 191 return AddArgsTo( 192 context_->storage->mutable_android_input_event_dispatch_table(), id); 193 } 194 AddArgsTo(MetadataId id)195 BoundInserter AddArgsTo(MetadataId id) { 196 auto* table = context_->storage->mutable_metadata_table(); 197 uint32_t row = table->FindById(id)->ToRowNumber().row_number(); 198 return BoundInserter(this, table->mutable_int_value(), row); 199 } 200 AddArgsTo(TrackId id)201 BoundInserter AddArgsTo(TrackId id) { 202 auto* table = context_->storage->mutable_track_table(); 203 uint32_t row = table->FindById(id)->ToRowNumber().row_number(); 204 return BoundInserter(this, table->mutable_source_arg_set_id(), row); 205 } 206 AddArgsTo(VulkanAllocId id)207 BoundInserter AddArgsTo(VulkanAllocId id) { 208 return AddArgsTo( 209 context_->storage->mutable_vulkan_memory_allocations_table(), id); 210 } 211 AddArgsTo(UniquePid id)212 BoundInserter AddArgsTo(UniquePid id) { 213 return BoundInserter( 214 this, context_->storage->mutable_process_table()->mutable_arg_set_id(), 215 id); 216 } 217 AddArgsTo(tables::ExperimentalProtoPathTable::Id id)218 BoundInserter AddArgsTo(tables::ExperimentalProtoPathTable::Id id) { 219 return AddArgsTo(context_->storage->mutable_experimental_proto_path_table(), 220 id); 221 } 222 AddArgsTo(tables::CpuTable::Id id)223 BoundInserter AddArgsTo(tables::CpuTable::Id id) { 224 return AddArgsTo(context_->storage->mutable_cpu_table(), id); 225 } 226 227 // Returns a CompactArgSet which contains the args inserted into this 228 // ArgsTracker. Requires that every arg in this tracker was inserted for the 229 // "arg_set_id" column given by |column| at the given |row_number|. 230 // 231 // Note that this means the args stored in this tracker will *not* be flushed 232 // into the tables: it is the callers responsibility to ensure this happens if 233 // necessary. 234 CompactArgSet ToCompactArgSet(const ColumnLegacy& column, 235 uint32_t row_number) &&; 236 237 // Returns whether this ArgsTracker contains any arg which require translation 238 // according to the provided |table|. 239 bool NeedsTranslation(const ArgsTranslationTable& table) const; 240 241 // Commits the added args to storage. 242 // Virtual for testing. 243 virtual void Flush(); 244 245 private: 246 template <typename Table> AddArgsTo(Table * table,typename Table::Id id)247 BoundInserter AddArgsTo(Table* table, typename Table::Id id) { 248 uint32_t row = table->FindById(id)->ToRowNumber().row_number(); 249 return BoundInserter(this, table->mutable_arg_set_id(), row); 250 } 251 252 void AddArg(ColumnLegacy* arg_set_id, 253 uint32_t row, 254 StringId flat_key, 255 StringId key, 256 Variadic, 257 UpdatePolicy); 258 259 base::SmallVector<GlobalArgsTracker::Arg, 16> args_; 260 TraceProcessorContext* context_ = nullptr; 261 262 using ArrayKeyTuple = std:: 263 tuple<ColumnLegacy* /*arg_set_id*/, uint32_t /*row*/, StringId /*key*/>; 264 std::map<ArrayKeyTuple, size_t /*next_index*/> array_indexes_; 265 }; 266 267 } // namespace trace_processor 268 } // namespace perfetto 269 270 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_ 271