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