xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/common/args_tracker.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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