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