• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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