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