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 35 // Stores the table and row at creation time which args are associated with. 36 // This allows callers to directly add args without repeating the row the 37 // args should be associated with. 38 class BoundInserter { 39 public: 40 virtual ~BoundInserter(); 41 42 BoundInserter(BoundInserter&&) noexcept; 43 BoundInserter& operator=(BoundInserter&&) noexcept; 44 45 BoundInserter(const BoundInserter&) = delete; 46 BoundInserter& operator=(const BoundInserter&) = delete; 47 48 // Adds an arg with the same key and flat_key. 49 BoundInserter& AddArg( 50 StringId key, 51 Variadic v, 52 UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) { 53 return AddArg(key, key, v, update_policy); 54 } 55 56 virtual BoundInserter& AddArg( 57 StringId flat_key, 58 StringId key, 59 Variadic v, 60 UpdatePolicy update_policy = UpdatePolicy::kAddOrUpdate) { 61 args_tracker_->AddArg(arg_set_id_column_, row_, flat_key, key, v, 62 update_policy); 63 return *this; 64 } 65 66 // IncrementArrayEntryIndex() and GetNextArrayEntryIndex() provide a way to 67 // track the next array index for an array under a specific key. GetNextArrayEntryIndex(StringId key)68 size_t GetNextArrayEntryIndex(StringId key) { 69 // Zero-initializes |key| in the map if it doesn't exist yet. 70 return args_tracker_ 71 ->array_indexes_[std::make_tuple(arg_set_id_column_, row_, key)]; 72 } 73 74 // Returns the next available array index after increment. IncrementArrayEntryIndex(StringId key)75 size_t IncrementArrayEntryIndex(StringId key) { 76 // Zero-initializes |key| in the map if it doesn't exist yet. 77 return ++args_tracker_->array_indexes_[std::make_tuple(arg_set_id_column_, 78 row_, key)]; 79 } 80 81 protected: 82 BoundInserter(ArgsTracker* args_tracker, 83 Column* arg_set_id_column, 84 uint32_t row); 85 86 private: 87 friend class ArgsTracker; 88 89 ArgsTracker* args_tracker_ = nullptr; 90 Column* arg_set_id_column_ = nullptr; 91 uint32_t row_ = 0; 92 }; 93 94 explicit ArgsTracker(TraceProcessorContext*); 95 ArgsTracker(const ArgsTracker&) = default; 96 virtual ~ArgsTracker(); 97 AddArgsTo(RawId id)98 BoundInserter AddArgsTo(RawId id) { 99 return AddArgsTo(context_->storage->mutable_raw_table(), id); 100 } 101 AddArgsTo(CounterId id)102 BoundInserter AddArgsTo(CounterId id) { 103 return AddArgsTo(context_->storage->mutable_counter_table(), id); 104 } 105 AddArgsTo(InstantId id)106 BoundInserter AddArgsTo(InstantId id) { 107 return AddArgsTo(context_->storage->mutable_instant_table(), id); 108 } 109 AddArgsTo(SliceId id)110 BoundInserter AddArgsTo(SliceId id) { 111 return AddArgsTo(context_->storage->mutable_slice_table(), id); 112 } 113 AddArgsTo(tables::FlowTable::Id id)114 BoundInserter AddArgsTo(tables::FlowTable::Id id) { 115 return AddArgsTo(context_->storage->mutable_flow_table(), id); 116 } 117 AddArgsTo(tables::MemorySnapshotNodeTable::Id id)118 BoundInserter AddArgsTo(tables::MemorySnapshotNodeTable::Id id) { 119 return AddArgsTo(context_->storage->mutable_memory_snapshot_node_table(), 120 id); 121 } 122 AddArgsTo(MetadataId id)123 BoundInserter AddArgsTo(MetadataId id) { 124 auto* table = context_->storage->mutable_metadata_table(); 125 uint32_t row = *table->id().IndexOf(id); 126 return BoundInserter(this, table->mutable_int_value(), row); 127 } 128 AddArgsTo(TrackId id)129 BoundInserter AddArgsTo(TrackId id) { 130 auto* table = context_->storage->mutable_track_table(); 131 uint32_t row = *table->id().IndexOf(id); 132 return BoundInserter(this, table->mutable_source_arg_set_id(), row); 133 } 134 AddArgsTo(VulkanAllocId id)135 BoundInserter AddArgsTo(VulkanAllocId id) { 136 return AddArgsTo( 137 context_->storage->mutable_vulkan_memory_allocations_table(), id); 138 } 139 AddArgsTo(UniquePid id)140 BoundInserter AddArgsTo(UniquePid id) { 141 return BoundInserter( 142 this, context_->storage->mutable_process_table()->mutable_arg_set_id(), 143 id); 144 } 145 146 // Commits the added args to storage. 147 // Virtual for testing. 148 virtual void Flush(); 149 150 private: 151 template <typename Table> AddArgsTo(Table * table,typename Table::Id id)152 BoundInserter AddArgsTo(Table* table, typename Table::Id id) { 153 uint32_t row = *table->id().IndexOf(id); 154 return BoundInserter(this, table->mutable_arg_set_id(), row); 155 } 156 157 void AddArg(Column* arg_set_id, 158 uint32_t row, 159 StringId flat_key, 160 StringId key, 161 Variadic, 162 UpdatePolicy); 163 164 base::SmallVector<GlobalArgsTracker::Arg, 16> args_; 165 TraceProcessorContext* const context_; 166 167 using ArrayKeyTuple = 168 std::tuple<Column* /*arg_set_id*/, uint32_t /*row*/, StringId /*key*/>; 169 std::map<ArrayKeyTuple, size_t /*next_index*/> array_indexes_; 170 }; 171 172 } // namespace trace_processor 173 } // namespace perfetto 174 175 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_ 176