• 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 
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