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