• 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   virtual ~ArgsTracker();
94 
AddArgsTo(RawId id)95   BoundInserter AddArgsTo(RawId id) {
96     return AddArgsTo(context_->storage->mutable_raw_table(), id);
97   }
98 
AddArgsTo(CounterId id)99   BoundInserter AddArgsTo(CounterId id) {
100     return AddArgsTo(context_->storage->mutable_counter_table(), id);
101   }
102 
AddArgsTo(InstantId id)103   BoundInserter AddArgsTo(InstantId id) {
104     return AddArgsTo(context_->storage->mutable_instant_table(), id);
105   }
106 
AddArgsTo(SliceId id)107   BoundInserter AddArgsTo(SliceId id) {
108     return AddArgsTo(context_->storage->mutable_slice_table(), id);
109   }
110 
AddArgsTo(MetadataId id)111   BoundInserter AddArgsTo(MetadataId id) {
112     auto* table = context_->storage->mutable_metadata_table();
113     uint32_t row = *table->id().IndexOf(id);
114     return BoundInserter(this, table->mutable_int_value(), row);
115   }
116 
AddArgsTo(TrackId id)117   BoundInserter AddArgsTo(TrackId id) {
118     auto* table = context_->storage->mutable_track_table();
119     uint32_t row = *table->id().IndexOf(id);
120     return BoundInserter(this, table->mutable_source_arg_set_id(), row);
121   }
122 
AddArgsTo(VulkanAllocId id)123   BoundInserter AddArgsTo(VulkanAllocId id) {
124     return AddArgsTo(
125         context_->storage->mutable_vulkan_memory_allocations_table(), id);
126   }
127 
128   // Commits the added args to storage.
129   // Virtual for testing.
130   virtual void Flush();
131 
132  private:
133   template <typename Table>
AddArgsTo(Table * table,typename Table::Id id)134   BoundInserter AddArgsTo(Table* table, typename Table::Id id) {
135     uint32_t row = *table->id().IndexOf(id);
136     return BoundInserter(this, table->mutable_arg_set_id(), row);
137   }
138 
139   void AddArg(Column* arg_set_id,
140               uint32_t row,
141               StringId flat_key,
142               StringId key,
143               Variadic,
144               UpdatePolicy);
145 
146   std::vector<GlobalArgsTracker::Arg> args_;
147   TraceProcessorContext* const context_;
148 
149   using ArrayKeyTuple =
150       std::tuple<Column* /*arg_set_id*/, uint32_t /*row*/, StringId /*key*/>;
151   std::map<ArrayKeyTuple, size_t /*next_index*/> array_indexes_;
152 };
153 
154 }  // namespace trace_processor
155 }  // namespace perfetto
156 
157 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_ARGS_TRACKER_H_
158