• 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_TABLES_MACROS_INTERNAL_H_
18 #define SRC_TRACE_PROCESSOR_TABLES_MACROS_INTERNAL_H_
19 
20 #include <type_traits>
21 
22 #include "perfetto/ext/base/small_vector.h"
23 #include "src/trace_processor/db/table.h"
24 #include "src/trace_processor/db/typed_column.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 namespace macros_internal {
29 
30 // We define this class to allow the table macro below to compile without
31 // needing templates; in reality none of the methods will be called because the
32 // pointer to this class will always be null.
33 class RootParentTable : public Table {
34  public:
35   struct Row {
36    public:
37     Row(std::nullptr_t = nullptr) {}
38 
typeRow39     const char* type() const { return type_; }
40 
41    protected:
42     const char* type_ = nullptr;
43   };
44   // This class only exists to allow typechecking to work correctly in Insert
45   // below. If we had C++17 and if constexpr, we could statically verify that
46   // this was never created but for now, we still need to define it to satisfy
47   // the typechecker.
48   struct IdAndRow {
49     uint32_t id;
50   };
51   struct RowNumber {
row_numberRowNumber52     uint32_t row_number() { PERFETTO_FATAL("Should not be called"); }
53   };
Insert(const Row &)54   IdAndRow Insert(const Row&) { PERFETTO_FATAL("Should not be called"); }
55 
56  private:
57   explicit RootParentTable(std::nullptr_t);
58 };
59 
60 // The parent class for all macro generated tables.
61 // This class is used to extract common code from the macro tables to reduce
62 // code size.
63 class MacroTable : public Table {
64  protected:
65   // Constructors for tables created by the regular constructor.
66   MacroTable(StringPool* pool, const Table* parent = nullptr)
Table(pool)67       : Table(pool), allow_inserts_(true), parent_(parent) {
68     if (!parent) {
69       overlays_.emplace_back();
70       columns_.emplace_back(Column::IdColumn(this, 0, 0));
71       columns_.emplace_back(
72           Column("type", &type_, Column::kNonNull, this, 1, 0));
73       return;
74     }
75 
76     overlays_.resize(parent->overlays().size() + 1);
77     for (const Column& col : parent->columns()) {
78       columns_.emplace_back(col, this, col.index_in_table(),
79                             col.overlay_index());
80     }
81   }
82 
83   // Constructor for tables created by SelectAndExtendParent.
MacroTable(StringPool * pool,const Table & parent,const RowMap & parent_overlay)84   MacroTable(StringPool* pool,
85              const Table& parent,
86              const RowMap& parent_overlay)
87       : Table(pool), allow_inserts_(false) {
88     row_count_ = parent_overlay.size();
89     for (const auto& rm : parent.overlays()) {
90       overlays_.emplace_back(rm.SelectRows(parent_overlay));
91       PERFETTO_DCHECK(overlays_.back().size() == row_count_);
92     }
93     overlays_.emplace_back(ColumnStorageOverlay(row_count_));
94 
95     for (const Column& col : parent.columns()) {
96       columns_.emplace_back(col, this, col.index_in_table(),
97                             col.overlay_index());
98     }
99   }
100   ~MacroTable() override;
101 
102   // We don't want a move or copy constructor because we store pointers to
103   // fields of macro tables which will be invalidated if we move/copy them.
104   MacroTable(const MacroTable&) = delete;
105   MacroTable& operator=(const MacroTable&) = delete;
106 
107   MacroTable(MacroTable&&) = delete;
108   MacroTable& operator=(MacroTable&&) noexcept = delete;
109 
UpdateOverlaysAfterParentInsert()110   void UpdateOverlaysAfterParentInsert() {
111     // Add the last inserted row in each of the parent row maps to the
112     // corresponding row map in the child.
113     for (uint32_t i = 0; i < parent_->overlays().size(); ++i) {
114       const ColumnStorageOverlay& parent_rm = parent_->overlays()[i];
115       overlays_[i].Insert(parent_rm.Get(parent_rm.size() - 1));
116     }
117   }
118 
UpdateSelfOverlayAfterInsert()119   void UpdateSelfOverlayAfterInsert() {
120     // Also add the index of the new row to the identity row map and increment
121     // the size.
122     overlays_.back().Insert(row_count_++);
123   }
124 
FilterAndApplyToOverlays(const std::vector<Constraint> & cs,RowMap::OptimizeFor optimize_for)125   std::vector<ColumnStorageOverlay> FilterAndApplyToOverlays(
126       const std::vector<Constraint>& cs,
127       RowMap::OptimizeFor optimize_for) const {
128     RowMap rm = FilterToRowMap(cs, optimize_for);
129     std::vector<ColumnStorageOverlay> overlays;
130     overlays.reserve(overlays_.size());
131     for (uint32_t i = 0; i < overlays_.size(); ++i) {
132       overlays.emplace_back(overlays_[i].SelectRows(rm));
133     }
134     return overlays;
135   }
136 
137   // Stores whether inserts are allowed into this macro table; by default
138   // inserts are allowed but they are disallowed when a parent table is extended
139   // with |ExtendParent|; the rationale for this is that extensions usually
140   // happen in dynamic tables and they should not be allowed to insert rows into
141   // the real (static) tables.
142   bool allow_inserts_ = true;
143 
144   // Stores the most specific "derived" type of this row in the table.
145   //
146   // For example, suppose a row is inserted into the gpu_slice table. This will
147   // also cause a row to be inserted into the slice table. For users querying
148   // the slice table, they will want to know the "real" type of this slice (i.e.
149   // they will want to see that the type is gpu_slice). This sparse vector
150   // stores precisely the real type.
151   //
152   // Only relevant for parentless tables. Will be empty and unreferenced by
153   // tables with parents.
154   ColumnStorage<StringPool::Id> type_;
155 
156  private:
157   const Table* parent_ = nullptr;
158 };
159 
160 // Abstract iterator class for macro tables.
161 // Extracted to allow sharing with view code.
162 template <typename Iterator,
163           typename MacroTable,
164           typename RowNumber,
165           typename ConstRowReference>
166 class AbstractConstIterator {
167  public:
168   explicit operator bool() const { return its_[0]; }
169 
170   Iterator& operator++() {
171     for (ColumnStorageOverlay::Iterator& it : its_) {
172       it.Next();
173     }
174     return *this_it();
175   }
176 
177   // Returns a RowNumber for the current row.
row_number()178   RowNumber row_number() const {
179     return RowNumber(this_it()->CurrentRowNumber());
180   }
181 
182   // Returns a ConstRowReference to the current row.
row_reference()183   ConstRowReference row_reference() const {
184     return ConstRowReference(table_, this_it()->CurrentRowNumber());
185   }
186 
187  protected:
AbstractConstIterator(const MacroTable * table,std::vector<ColumnStorageOverlay> overlays)188   explicit AbstractConstIterator(const MacroTable* table,
189                                  std::vector<ColumnStorageOverlay> overlays)
190       : overlays_(std::move(overlays)), table_(table) {
191     static_assert(std::is_base_of<Table, MacroTable>::value,
192                   "Template param should be a subclass of Table.");
193 
194     for (const auto& rm : overlays_) {
195       its_.emplace_back(rm.IterateRows());
196     }
197   }
198 
199   // Must not be modified as |its_| contains pointers into this vector.
200   std::vector<ColumnStorageOverlay> overlays_;
201   std::vector<ColumnStorageOverlay::Iterator> its_;
202 
203   const MacroTable* table_;
204 
205  private:
this_it()206   Iterator* this_it() { return static_cast<Iterator*>(this); }
this_it()207   const Iterator* this_it() const { return static_cast<const Iterator*>(this); }
208 };
209 
210 // Abstract RowNumber class for macro tables.
211 // Extracted to allow sharing with view code.
212 template <typename MacroTable,
213           typename ConstRowReference,
214           typename RowReference = void>
215 class AbstractRowNumber {
216  public:
217   // Converts this RowNumber to a RowReference for the given |table|.
218   template <
219       typename RR = RowReference,
220       typename = typename std::enable_if<!std::is_same<RR, void>::value>::type>
ToRowReference(MacroTable * table)221   RR ToRowReference(MacroTable* table) const {
222     return RR(table, row_number_);
223   }
224 
225   // Converts this RowNumber to a ConstRowReference for the given |table|.
ToRowReference(const MacroTable & table)226   ConstRowReference ToRowReference(const MacroTable& table) const {
227     return ConstRowReference(&table, row_number_);
228   }
229 
230   // Converts this object to the underlying int value.
row_number()231   uint32_t row_number() const { return row_number_; }
232 
233   // Allows sorting + storage in a map/set.
234   bool operator<(const AbstractRowNumber& other) const {
235     return row_number_ < other.row_number_;
236   }
237 
238  protected:
AbstractRowNumber(uint32_t row_number)239   explicit AbstractRowNumber(uint32_t row_number) : row_number_(row_number) {}
240 
241  private:
242   uint32_t row_number_ = 0;
243 };
244 
245 // Abstract ConstRowReference class for macro tables.
246 // Extracted to allow sharing with view code.
247 template <typename MacroTable, typename RowNumber>
248 class AbstractConstRowReference {
249  public:
250   // Converts this RowReference to a RowNumber object which is more memory
251   // efficient to store.
ToRowNumber()252   RowNumber ToRowNumber() { return RowNumber(row_number_); }
253 
254  protected:
AbstractConstRowReference(const MacroTable * table,uint32_t row_number)255   AbstractConstRowReference(const MacroTable* table, uint32_t row_number)
256       : table_(table), row_number_(row_number) {}
257 
258   const MacroTable* table_ = nullptr;
259   uint32_t row_number_ = 0;
260 };
261 
262 }  // namespace macros_internal
263 }  // namespace trace_processor
264 }  // namespace perfetto
265 
266 #endif  // SRC_TRACE_PROCESSOR_TABLES_MACROS_INTERNAL_H_
267