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