1 #ifndef SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_PY_H_
2 #define SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_PY_H_
3 
4 #include <array>
5 #include <cstddef>
6 #include <cstdint>
7 #include <memory>
8 #include <optional>
9 #include <type_traits>
10 #include <utility>
11 #include <vector>
12 
13 #include "perfetto/base/logging.h"
14 #include "perfetto/trace_processor/basic_types.h"
15 #include "perfetto/trace_processor/ref_counted.h"
16 #include "src/trace_processor/containers/bit_vector.h"
17 #include "src/trace_processor/containers/row_map.h"
18 #include "src/trace_processor/containers/string_pool.h"
19 #include "src/trace_processor/db/column/arrangement_overlay.h"
20 #include "src/trace_processor/db/column/data_layer.h"
21 #include "src/trace_processor/db/column/dense_null_overlay.h"
22 #include "src/trace_processor/db/column/numeric_storage.h"
23 #include "src/trace_processor/db/column/id_storage.h"
24 #include "src/trace_processor/db/column/null_overlay.h"
25 #include "src/trace_processor/db/column/range_overlay.h"
26 #include "src/trace_processor/db/column/selector_overlay.h"
27 #include "src/trace_processor/db/column/set_id_storage.h"
28 #include "src/trace_processor/db/column/string_storage.h"
29 #include "src/trace_processor/db/column/types.h"
30 #include "src/trace_processor/db/column_storage.h"
31 #include "src/trace_processor/db/column.h"
32 #include "src/trace_processor/db/table.h"
33 #include "src/trace_processor/db/typed_column.h"
34 #include "src/trace_processor/db/typed_column_internal.h"
35 #include "src/trace_processor/tables/macros_internal.h"
36 
37 #include "src/trace_processor/tables/track_tables_py.h"
38 
39 namespace perfetto::trace_processor::tables {
40 
41 class CounterTable : public macros_internal::MacroTable {
42  public:
43   static constexpr uint32_t kColumnCount = 6;
44 
45   struct Id : public BaseId {
46     Id() = default;
IdId47     explicit constexpr Id(uint32_t v) : BaseId(v) {}
48   };
49   static_assert(std::is_trivially_destructible_v<Id>,
50                 "Inheritance used without trivial destruction");
51 
52   struct ColumnIndex {
53     static constexpr uint32_t id = 0;
54     static constexpr uint32_t type = 1;
55     static constexpr uint32_t ts = 2;
56     static constexpr uint32_t track_id = 3;
57     static constexpr uint32_t value = 4;
58     static constexpr uint32_t arg_set_id = 5;
59   };
60   struct ColumnType {
61     using id = IdColumn<CounterTable::Id>;
62     using type = TypedColumn<StringPool::Id>;
63     using ts = TypedColumn<int64_t>;
64     using track_id = TypedColumn<TrackTable::Id>;
65     using value = TypedColumn<double>;
66     using arg_set_id = TypedColumn<std::optional<uint32_t>>;
67   };
68   struct Row : public macros_internal::RootParentTable::Row {
69     Row(int64_t in_ts = {},
70         TrackTable::Id in_track_id = {},
71         double in_value = {},
72         std::optional<uint32_t> in_arg_set_id = {},
73         std::nullptr_t = nullptr)
RowRow74         : macros_internal::RootParentTable::Row(),
75           ts(in_ts),
76           track_id(in_track_id),
77           value(in_value),
78           arg_set_id(in_arg_set_id) {
79       type_ = "__intrinsic_counter";
80     }
81     int64_t ts;
82     TrackTable::Id track_id;
83     double value;
84     std::optional<uint32_t> arg_set_id;
85 
86     bool operator==(const CounterTable::Row& other) const {
87       return type() == other.type() && ColumnType::ts::Equals(ts, other.ts) &&
88        ColumnType::track_id::Equals(track_id, other.track_id) &&
89        ColumnType::value::Equals(value, other.value) &&
90        ColumnType::arg_set_id::Equals(arg_set_id, other.arg_set_id);
91     }
92   };
93   struct ColumnFlag {
94     static constexpr uint32_t ts = static_cast<uint32_t>(ColumnLegacy::Flag::kSorted) | ColumnType::ts::default_flags();
95     static constexpr uint32_t track_id = ColumnType::track_id::default_flags();
96     static constexpr uint32_t value = ColumnType::value::default_flags();
97     static constexpr uint32_t arg_set_id = ColumnType::arg_set_id::default_flags();
98   };
99 
100   class RowNumber;
101   class ConstRowReference;
102   class RowReference;
103 
104   class RowNumber : public macros_internal::AbstractRowNumber<
105       CounterTable, ConstRowReference, RowReference> {
106    public:
RowNumber(uint32_t row_number)107     explicit RowNumber(uint32_t row_number)
108         : AbstractRowNumber(row_number) {}
109   };
110   static_assert(std::is_trivially_destructible_v<RowNumber>,
111                 "Inheritance used without trivial destruction");
112 
113   class ConstRowReference : public macros_internal::AbstractConstRowReference<
114     CounterTable, RowNumber> {
115    public:
ConstRowReference(const CounterTable * table,uint32_t row_number)116     ConstRowReference(const CounterTable* table, uint32_t row_number)
117         : AbstractConstRowReference(table, row_number) {}
118 
id()119     ColumnType::id::type id() const {
120       return table()->id()[row_number_];
121     }
type()122     ColumnType::type::type type() const {
123       return table()->type()[row_number_];
124     }
ts()125     ColumnType::ts::type ts() const {
126       return table()->ts()[row_number_];
127     }
track_id()128     ColumnType::track_id::type track_id() const {
129       return table()->track_id()[row_number_];
130     }
value()131     ColumnType::value::type value() const {
132       return table()->value()[row_number_];
133     }
arg_set_id()134     ColumnType::arg_set_id::type arg_set_id() const {
135       return table()->arg_set_id()[row_number_];
136     }
137   };
138   static_assert(std::is_trivially_destructible_v<ConstRowReference>,
139                 "Inheritance used without trivial destruction");
140   class RowReference : public ConstRowReference {
141    public:
RowReference(const CounterTable * table,uint32_t row_number)142     RowReference(const CounterTable* table, uint32_t row_number)
143         : ConstRowReference(table, row_number) {}
144 
set_ts(ColumnType::ts::non_optional_type v)145     void set_ts(
146         ColumnType::ts::non_optional_type v) {
147       return mutable_table()->mutable_ts()->Set(row_number_, v);
148     }
set_track_id(ColumnType::track_id::non_optional_type v)149     void set_track_id(
150         ColumnType::track_id::non_optional_type v) {
151       return mutable_table()->mutable_track_id()->Set(row_number_, v);
152     }
set_value(ColumnType::value::non_optional_type v)153     void set_value(
154         ColumnType::value::non_optional_type v) {
155       return mutable_table()->mutable_value()->Set(row_number_, v);
156     }
set_arg_set_id(ColumnType::arg_set_id::non_optional_type v)157     void set_arg_set_id(
158         ColumnType::arg_set_id::non_optional_type v) {
159       return mutable_table()->mutable_arg_set_id()->Set(row_number_, v);
160     }
161 
162    private:
mutable_table()163     CounterTable* mutable_table() const {
164       return const_cast<CounterTable*>(table());
165     }
166   };
167   static_assert(std::is_trivially_destructible_v<RowReference>,
168                 "Inheritance used without trivial destruction");
169 
170   class ConstIterator;
171   class ConstIterator : public macros_internal::AbstractConstIterator<
172     ConstIterator, CounterTable, RowNumber, ConstRowReference> {
173    public:
id()174     ColumnType::id::type id() const {
175       const auto& col = table()->id();
176       return col.GetAtIdx(
177         iterator_.StorageIndexForColumn(col.index_in_table()));
178     }
type()179     ColumnType::type::type type() const {
180       const auto& col = table()->type();
181       return col.GetAtIdx(
182         iterator_.StorageIndexForColumn(col.index_in_table()));
183     }
ts()184     ColumnType::ts::type ts() const {
185       const auto& col = table()->ts();
186       return col.GetAtIdx(
187         iterator_.StorageIndexForColumn(col.index_in_table()));
188     }
track_id()189     ColumnType::track_id::type track_id() const {
190       const auto& col = table()->track_id();
191       return col.GetAtIdx(
192         iterator_.StorageIndexForColumn(col.index_in_table()));
193     }
value()194     ColumnType::value::type value() const {
195       const auto& col = table()->value();
196       return col.GetAtIdx(
197         iterator_.StorageIndexForColumn(col.index_in_table()));
198     }
arg_set_id()199     ColumnType::arg_set_id::type arg_set_id() const {
200       const auto& col = table()->arg_set_id();
201       return col.GetAtIdx(
202         iterator_.StorageIndexForColumn(col.index_in_table()));
203     }
204 
205    protected:
ConstIterator(const CounterTable * table,Table::Iterator iterator)206     explicit ConstIterator(const CounterTable* table,
207                            Table::Iterator iterator)
208         : AbstractConstIterator(table, std::move(iterator)) {}
209 
CurrentRowNumber()210     uint32_t CurrentRowNumber() const {
211       return iterator_.StorageIndexForLastOverlay();
212     }
213 
214    private:
215     friend class CounterTable;
216     friend class macros_internal::AbstractConstIterator<
217       ConstIterator, CounterTable, RowNumber, ConstRowReference>;
218   };
219   class Iterator : public ConstIterator {
220     public:
row_reference()221      RowReference row_reference() const {
222        return {const_cast<CounterTable*>(table()), CurrentRowNumber()};
223      }
224 
225     private:
226      friend class CounterTable;
227 
Iterator(CounterTable * table,Table::Iterator iterator)228      explicit Iterator(CounterTable* table, Table::Iterator iterator)
229         : ConstIterator(table, std::move(iterator)) {}
230   };
231 
232   struct IdAndRow {
233     Id id;
234     uint32_t row;
235     RowReference row_reference;
236     RowNumber row_number;
237   };
238 
GetColumns(CounterTable * self,const macros_internal::MacroTable * parent)239   static std::vector<ColumnLegacy> GetColumns(
240       CounterTable* self,
241       const macros_internal::MacroTable* parent) {
242     std::vector<ColumnLegacy> columns =
243         CopyColumnsFromParentOrAddRootColumns(self, parent);
244     uint32_t olay_idx = OverlayCount(parent);
245     AddColumnToVector(columns, "ts", &self->ts_, ColumnFlag::ts,
246                       static_cast<uint32_t>(columns.size()), olay_idx);
247     AddColumnToVector(columns, "track_id", &self->track_id_, ColumnFlag::track_id,
248                       static_cast<uint32_t>(columns.size()), olay_idx);
249     AddColumnToVector(columns, "value", &self->value_, ColumnFlag::value,
250                       static_cast<uint32_t>(columns.size()), olay_idx);
251     AddColumnToVector(columns, "arg_set_id", &self->arg_set_id_, ColumnFlag::arg_set_id,
252                       static_cast<uint32_t>(columns.size()), olay_idx);
253     return columns;
254   }
255 
CounterTable(StringPool * pool)256   PERFETTO_NO_INLINE explicit CounterTable(StringPool* pool)
257       : macros_internal::MacroTable(
258           pool,
259           GetColumns(this, nullptr),
260           nullptr),
261         ts_(ColumnStorage<ColumnType::ts::stored_type>::Create<false>()),
262         track_id_(ColumnStorage<ColumnType::track_id::stored_type>::Create<false>()),
263         value_(ColumnStorage<ColumnType::value::stored_type>::Create<false>()),
264         arg_set_id_(ColumnStorage<ColumnType::arg_set_id::stored_type>::Create<false>())
265 ,
266         id_storage_layer_(new column::IdStorage()),
267         type_storage_layer_(
268           new column::StringStorage(string_pool(), &type_.vector())),
269         ts_storage_layer_(
270         new column::NumericStorage<ColumnType::ts::non_optional_stored_type>(
271           &ts_.vector(),
272           ColumnTypeHelper<ColumnType::ts::stored_type>::ToColumnType(),
273           true)),
274         track_id_storage_layer_(
275         new column::NumericStorage<ColumnType::track_id::non_optional_stored_type>(
276           &track_id_.vector(),
277           ColumnTypeHelper<ColumnType::track_id::stored_type>::ToColumnType(),
278           false)),
279         value_storage_layer_(
280         new column::NumericStorage<ColumnType::value::non_optional_stored_type>(
281           &value_.vector(),
282           ColumnTypeHelper<ColumnType::value::stored_type>::ToColumnType(),
283           false)),
284         arg_set_id_storage_layer_(
285           new column::NumericStorage<ColumnType::arg_set_id::non_optional_stored_type>(
286             &arg_set_id_.non_null_vector(),
287             ColumnTypeHelper<ColumnType::arg_set_id::stored_type>::ToColumnType(),
288             false))
289 ,
290         arg_set_id_null_layer_(new column::NullOverlay(arg_set_id_.bv())) {
291     static_assert(
292         ColumnLegacy::IsFlagsAndTypeValid<ColumnType::ts::stored_type>(
293           ColumnFlag::ts),
294         "Column type and flag combination is not valid");
295       static_assert(
296         ColumnLegacy::IsFlagsAndTypeValid<ColumnType::track_id::stored_type>(
297           ColumnFlag::track_id),
298         "Column type and flag combination is not valid");
299       static_assert(
300         ColumnLegacy::IsFlagsAndTypeValid<ColumnType::value::stored_type>(
301           ColumnFlag::value),
302         "Column type and flag combination is not valid");
303       static_assert(
304         ColumnLegacy::IsFlagsAndTypeValid<ColumnType::arg_set_id::stored_type>(
305           ColumnFlag::arg_set_id),
306         "Column type and flag combination is not valid");
307     OnConstructionCompletedRegularConstructor(
308       {id_storage_layer_,type_storage_layer_,ts_storage_layer_,track_id_storage_layer_,value_storage_layer_,arg_set_id_storage_layer_},
309       {{},{},{},{},{},arg_set_id_null_layer_});
310   }
311   ~CounterTable() override;
312 
Name()313   static const char* Name() { return "__intrinsic_counter"; }
314 
ComputeStaticSchema()315   static Table::Schema ComputeStaticSchema() {
316     Table::Schema schema;
317     schema.columns.emplace_back(Table::Schema::Column{
318         "id", SqlValue::Type::kLong, true, true, false, false});
319     schema.columns.emplace_back(Table::Schema::Column{
320         "type", SqlValue::Type::kString, false, false, false, false});
321     schema.columns.emplace_back(Table::Schema::Column{
322         "ts", ColumnType::ts::SqlValueType(), false,
323         true,
324         false,
325         false});
326     schema.columns.emplace_back(Table::Schema::Column{
327         "track_id", ColumnType::track_id::SqlValueType(), false,
328         false,
329         false,
330         false});
331     schema.columns.emplace_back(Table::Schema::Column{
332         "value", ColumnType::value::SqlValueType(), false,
333         false,
334         false,
335         false});
336     schema.columns.emplace_back(Table::Schema::Column{
337         "arg_set_id", ColumnType::arg_set_id::SqlValueType(), false,
338         false,
339         false,
340         false});
341     return schema;
342   }
343 
IterateRows()344   ConstIterator IterateRows() const {
345     return ConstIterator(this, Table::IterateRows());
346   }
347 
IterateRows()348   Iterator IterateRows() { return Iterator(this, Table::IterateRows()); }
349 
FilterToIterator(const Query & q)350   ConstIterator FilterToIterator(const Query& q) const {
351     return ConstIterator(this, QueryToIterator(q));
352   }
353 
FilterToIterator(const Query & q)354   Iterator FilterToIterator(const Query& q) {
355     return Iterator(this, QueryToIterator(q));
356   }
357 
ShrinkToFit()358   void ShrinkToFit() {
359     type_.ShrinkToFit();
360     ts_.ShrinkToFit();
361     track_id_.ShrinkToFit();
362     value_.ShrinkToFit();
363     arg_set_id_.ShrinkToFit();
364   }
365 
366   ConstRowReference operator[](uint32_t r) const {
367     return ConstRowReference(this, r);
368   }
369   RowReference operator[](uint32_t r) { return RowReference(this, r); }
370   ConstRowReference operator[](RowNumber r) const {
371     return ConstRowReference(this, r.row_number());
372   }
373   RowReference operator[](RowNumber r) {
374     return RowReference(this, r.row_number());
375   }
376 
FindById(Id find_id)377   std::optional<ConstRowReference> FindById(Id find_id) const {
378     std::optional<uint32_t> row = id().IndexOf(find_id);
379     return row ? std::make_optional(ConstRowReference(this, *row))
380                : std::nullopt;
381   }
382 
FindById(Id find_id)383   std::optional<RowReference> FindById(Id find_id) {
384     std::optional<uint32_t> row = id().IndexOf(find_id);
385     return row ? std::make_optional(RowReference(this, *row)) : std::nullopt;
386   }
387 
Insert(const Row & row)388   IdAndRow Insert(const Row& row) {
389     uint32_t row_number = row_count();
390     Id id = Id{row_number};
391     type_.Append(string_pool()->InternString(row.type()));
392     mutable_ts()->Append(row.ts);
393     mutable_track_id()->Append(row.track_id);
394     mutable_value()->Append(row.value);
395     mutable_arg_set_id()->Append(row.arg_set_id);
396     UpdateSelfOverlayAfterInsert();
397     return IdAndRow{id, row_number, RowReference(this, row_number),
398                      RowNumber(row_number)};
399   }
400 
401 
402 
id()403   const IdColumn<CounterTable::Id>& id() const {
404     return static_cast<const ColumnType::id&>(columns()[ColumnIndex::id]);
405   }
type()406   const TypedColumn<StringPool::Id>& type() const {
407     return static_cast<const ColumnType::type&>(columns()[ColumnIndex::type]);
408   }
ts()409   const TypedColumn<int64_t>& ts() const {
410     return static_cast<const ColumnType::ts&>(columns()[ColumnIndex::ts]);
411   }
track_id()412   const TypedColumn<TrackTable::Id>& track_id() const {
413     return static_cast<const ColumnType::track_id&>(columns()[ColumnIndex::track_id]);
414   }
value()415   const TypedColumn<double>& value() const {
416     return static_cast<const ColumnType::value&>(columns()[ColumnIndex::value]);
417   }
arg_set_id()418   const TypedColumn<std::optional<uint32_t>>& arg_set_id() const {
419     return static_cast<const ColumnType::arg_set_id&>(columns()[ColumnIndex::arg_set_id]);
420   }
421 
mutable_ts()422   TypedColumn<int64_t>* mutable_ts() {
423     return static_cast<ColumnType::ts*>(
424         GetColumn(ColumnIndex::ts));
425   }
mutable_track_id()426   TypedColumn<TrackTable::Id>* mutable_track_id() {
427     return static_cast<ColumnType::track_id*>(
428         GetColumn(ColumnIndex::track_id));
429   }
mutable_value()430   TypedColumn<double>* mutable_value() {
431     return static_cast<ColumnType::value*>(
432         GetColumn(ColumnIndex::value));
433   }
mutable_arg_set_id()434   TypedColumn<std::optional<uint32_t>>* mutable_arg_set_id() {
435     return static_cast<ColumnType::arg_set_id*>(
436         GetColumn(ColumnIndex::arg_set_id));
437   }
438 
439  private:
440 
441 
442   ColumnStorage<ColumnType::ts::stored_type> ts_;
443   ColumnStorage<ColumnType::track_id::stored_type> track_id_;
444   ColumnStorage<ColumnType::value::stored_type> value_;
445   ColumnStorage<ColumnType::arg_set_id::stored_type> arg_set_id_;
446 
447   RefPtr<column::StorageLayer> id_storage_layer_;
448   RefPtr<column::StorageLayer> type_storage_layer_;
449   RefPtr<column::StorageLayer> ts_storage_layer_;
450   RefPtr<column::StorageLayer> track_id_storage_layer_;
451   RefPtr<column::StorageLayer> value_storage_layer_;
452   RefPtr<column::StorageLayer> arg_set_id_storage_layer_;
453 
454   RefPtr<column::OverlayLayer> arg_set_id_null_layer_;
455 };
456 
457 }  // namespace perfetto
458 
459 #endif  // SRC_TRACE_PROCESSOR_TABLES_COUNTER_TABLES_PY_H_
460