1 #ifndef SRC_TRACE_PROCESSOR_TABLES_FLOW_TABLES_PY_H_ 2 #define SRC_TRACE_PROCESSOR_TABLES_FLOW_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/slice_tables_py.h" 38 39 namespace perfetto::trace_processor::tables { 40 41 class FlowTable : 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 slice_out = 2; 56 static constexpr uint32_t slice_in = 3; 57 static constexpr uint32_t trace_id = 4; 58 static constexpr uint32_t arg_set_id = 5; 59 }; 60 struct ColumnType { 61 using id = IdColumn<FlowTable::Id>; 62 using type = TypedColumn<StringPool::Id>; 63 using slice_out = TypedColumn<SliceTable::Id>; 64 using slice_in = TypedColumn<SliceTable::Id>; 65 using trace_id = TypedColumn<std::optional<int64_t>>; 66 using arg_set_id = TypedColumn<uint32_t>; 67 }; 68 struct Row : public macros_internal::RootParentTable::Row { 69 Row(SliceTable::Id in_slice_out = {}, 70 SliceTable::Id in_slice_in = {}, 71 std::optional<int64_t> in_trace_id = {}, 72 uint32_t in_arg_set_id = {}, 73 std::nullptr_t = nullptr) RowRow74 : macros_internal::RootParentTable::Row(), 75 slice_out(in_slice_out), 76 slice_in(in_slice_in), 77 trace_id(in_trace_id), 78 arg_set_id(in_arg_set_id) { 79 type_ = "flow"; 80 } 81 SliceTable::Id slice_out; 82 SliceTable::Id slice_in; 83 std::optional<int64_t> trace_id; 84 uint32_t arg_set_id; 85 86 bool operator==(const FlowTable::Row& other) const { 87 return type() == other.type() && ColumnType::slice_out::Equals(slice_out, other.slice_out) && 88 ColumnType::slice_in::Equals(slice_in, other.slice_in) && 89 ColumnType::trace_id::Equals(trace_id, other.trace_id) && 90 ColumnType::arg_set_id::Equals(arg_set_id, other.arg_set_id); 91 } 92 }; 93 struct ColumnFlag { 94 static constexpr uint32_t slice_out = ColumnType::slice_out::default_flags(); 95 static constexpr uint32_t slice_in = ColumnType::slice_in::default_flags(); 96 static constexpr uint32_t trace_id = ColumnType::trace_id::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 FlowTable, 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 FlowTable, RowNumber> { 115 public: ConstRowReference(const FlowTable * table,uint32_t row_number)116 ConstRowReference(const FlowTable* 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 } slice_out()125 ColumnType::slice_out::type slice_out() const { 126 return table()->slice_out()[row_number_]; 127 } slice_in()128 ColumnType::slice_in::type slice_in() const { 129 return table()->slice_in()[row_number_]; 130 } trace_id()131 ColumnType::trace_id::type trace_id() const { 132 return table()->trace_id()[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 FlowTable * table,uint32_t row_number)142 RowReference(const FlowTable* table, uint32_t row_number) 143 : ConstRowReference(table, row_number) {} 144 set_slice_out(ColumnType::slice_out::non_optional_type v)145 void set_slice_out( 146 ColumnType::slice_out::non_optional_type v) { 147 return mutable_table()->mutable_slice_out()->Set(row_number_, v); 148 } set_slice_in(ColumnType::slice_in::non_optional_type v)149 void set_slice_in( 150 ColumnType::slice_in::non_optional_type v) { 151 return mutable_table()->mutable_slice_in()->Set(row_number_, v); 152 } set_trace_id(ColumnType::trace_id::non_optional_type v)153 void set_trace_id( 154 ColumnType::trace_id::non_optional_type v) { 155 return mutable_table()->mutable_trace_id()->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 FlowTable* mutable_table() const { 164 return const_cast<FlowTable*>(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, FlowTable, 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 } slice_out()184 ColumnType::slice_out::type slice_out() const { 185 const auto& col = table()->slice_out(); 186 return col.GetAtIdx( 187 iterator_.StorageIndexForColumn(col.index_in_table())); 188 } slice_in()189 ColumnType::slice_in::type slice_in() const { 190 const auto& col = table()->slice_in(); 191 return col.GetAtIdx( 192 iterator_.StorageIndexForColumn(col.index_in_table())); 193 } trace_id()194 ColumnType::trace_id::type trace_id() const { 195 const auto& col = table()->trace_id(); 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 FlowTable * table,Table::Iterator iterator)206 explicit ConstIterator(const FlowTable* 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 FlowTable; 216 friend class macros_internal::AbstractConstIterator< 217 ConstIterator, FlowTable, RowNumber, ConstRowReference>; 218 }; 219 class Iterator : public ConstIterator { 220 public: row_reference()221 RowReference row_reference() const { 222 return {const_cast<FlowTable*>(table()), CurrentRowNumber()}; 223 } 224 225 private: 226 friend class FlowTable; 227 Iterator(FlowTable * table,Table::Iterator iterator)228 explicit Iterator(FlowTable* 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(FlowTable * self,const macros_internal::MacroTable * parent)239 static std::vector<ColumnLegacy> GetColumns( 240 FlowTable* 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, "slice_out", &self->slice_out_, ColumnFlag::slice_out, 246 static_cast<uint32_t>(columns.size()), olay_idx); 247 AddColumnToVector(columns, "slice_in", &self->slice_in_, ColumnFlag::slice_in, 248 static_cast<uint32_t>(columns.size()), olay_idx); 249 AddColumnToVector(columns, "trace_id", &self->trace_id_, ColumnFlag::trace_id, 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 FlowTable(StringPool * pool)256 PERFETTO_NO_INLINE explicit FlowTable(StringPool* pool) 257 : macros_internal::MacroTable( 258 pool, 259 GetColumns(this, nullptr), 260 nullptr), 261 slice_out_(ColumnStorage<ColumnType::slice_out::stored_type>::Create<false>()), 262 slice_in_(ColumnStorage<ColumnType::slice_in::stored_type>::Create<false>()), 263 trace_id_(ColumnStorage<ColumnType::trace_id::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 slice_out_storage_layer_( 270 new column::NumericStorage<ColumnType::slice_out::non_optional_stored_type>( 271 &slice_out_.vector(), 272 ColumnTypeHelper<ColumnType::slice_out::stored_type>::ToColumnType(), 273 false)), 274 slice_in_storage_layer_( 275 new column::NumericStorage<ColumnType::slice_in::non_optional_stored_type>( 276 &slice_in_.vector(), 277 ColumnTypeHelper<ColumnType::slice_in::stored_type>::ToColumnType(), 278 false)), 279 trace_id_storage_layer_( 280 new column::NumericStorage<ColumnType::trace_id::non_optional_stored_type>( 281 &trace_id_.non_null_vector(), 282 ColumnTypeHelper<ColumnType::trace_id::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_.vector(), 287 ColumnTypeHelper<ColumnType::arg_set_id::stored_type>::ToColumnType(), 288 false)) 289 , 290 trace_id_null_layer_(new column::NullOverlay(trace_id_.bv())) { 291 static_assert( 292 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::slice_out::stored_type>( 293 ColumnFlag::slice_out), 294 "Column type and flag combination is not valid"); 295 static_assert( 296 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::slice_in::stored_type>( 297 ColumnFlag::slice_in), 298 "Column type and flag combination is not valid"); 299 static_assert( 300 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::trace_id::stored_type>( 301 ColumnFlag::trace_id), 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_,slice_out_storage_layer_,slice_in_storage_layer_,trace_id_storage_layer_,arg_set_id_storage_layer_}, 309 {{},{},{},{},trace_id_null_layer_,{}}); 310 } 311 ~FlowTable() override; 312 Name()313 static const char* Name() { return "flow"; } 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 "slice_out", ColumnType::slice_out::SqlValueType(), false, 323 false, 324 false, 325 false}); 326 schema.columns.emplace_back(Table::Schema::Column{ 327 "slice_in", ColumnType::slice_in::SqlValueType(), false, 328 false, 329 false, 330 false}); 331 schema.columns.emplace_back(Table::Schema::Column{ 332 "trace_id", ColumnType::trace_id::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 slice_out_.ShrinkToFit(); 361 slice_in_.ShrinkToFit(); 362 trace_id_.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_slice_out()->Append(row.slice_out); 393 mutable_slice_in()->Append(row.slice_in); 394 mutable_trace_id()->Append(row.trace_id); 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<FlowTable::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 } slice_out()409 const TypedColumn<SliceTable::Id>& slice_out() const { 410 return static_cast<const ColumnType::slice_out&>(columns()[ColumnIndex::slice_out]); 411 } slice_in()412 const TypedColumn<SliceTable::Id>& slice_in() const { 413 return static_cast<const ColumnType::slice_in&>(columns()[ColumnIndex::slice_in]); 414 } trace_id()415 const TypedColumn<std::optional<int64_t>>& trace_id() const { 416 return static_cast<const ColumnType::trace_id&>(columns()[ColumnIndex::trace_id]); 417 } arg_set_id()418 const TypedColumn<uint32_t>& arg_set_id() const { 419 return static_cast<const ColumnType::arg_set_id&>(columns()[ColumnIndex::arg_set_id]); 420 } 421 mutable_slice_out()422 TypedColumn<SliceTable::Id>* mutable_slice_out() { 423 return static_cast<ColumnType::slice_out*>( 424 GetColumn(ColumnIndex::slice_out)); 425 } mutable_slice_in()426 TypedColumn<SliceTable::Id>* mutable_slice_in() { 427 return static_cast<ColumnType::slice_in*>( 428 GetColumn(ColumnIndex::slice_in)); 429 } mutable_trace_id()430 TypedColumn<std::optional<int64_t>>* mutable_trace_id() { 431 return static_cast<ColumnType::trace_id*>( 432 GetColumn(ColumnIndex::trace_id)); 433 } mutable_arg_set_id()434 TypedColumn<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::slice_out::stored_type> slice_out_; 443 ColumnStorage<ColumnType::slice_in::stored_type> slice_in_; 444 ColumnStorage<ColumnType::trace_id::stored_type> trace_id_; 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> slice_out_storage_layer_; 450 RefPtr<column::StorageLayer> slice_in_storage_layer_; 451 RefPtr<column::StorageLayer> trace_id_storage_layer_; 452 RefPtr<column::StorageLayer> arg_set_id_storage_layer_; 453 454 RefPtr<column::OverlayLayer> trace_id_null_layer_; 455 }; 456 457 } // namespace perfetto 458 459 #endif // SRC_TRACE_PROCESSOR_TABLES_FLOW_TABLES_PY_H_ 460