1# Copyright (C) 2022 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15from typing import List 16from typing import Optional 17 18from python.generators.trace_processor_table.public import Alias 19from python.generators.trace_processor_table.public import ColumnFlag 20from python.generators.trace_processor_table.util import ParsedTable 21from python.generators.trace_processor_table.util import ParsedColumn 22from python.generators.trace_processor_table.util import data_layer_type 23from python.generators.trace_processor_table.util import parse_type 24from python.generators.trace_processor_table.util import typed_column_type 25 26 27class ColumnSerializer: 28 """Functions for serializing a single Column in a table into C++.""" 29 30 def __init__(self, table: ParsedTable, column: ParsedColumn, col_index: int): 31 self.col_index = col_index 32 self.parsed_col = column 33 self.col = self.parsed_col.column 34 self.name = self.col.name 35 self.flags = self.col.flags 36 37 parsed_type = parse_type(table.table, self.col.type) 38 39 self.typed_column_type = typed_column_type(table.table, self.parsed_col) 40 self.cpp_type = parsed_type.cpp_type_with_optionality() 41 self.data_layer_type = data_layer_type(table.table, self.parsed_col) 42 43 self.is_implicit_id = self.parsed_col.is_implicit_id 44 self.is_ancestor = self.parsed_col.is_ancestor 45 self.is_string = parsed_type.cpp_type == 'StringPool::Id' 46 self.is_optional = parsed_type.is_optional 47 48 def colindex(self) -> str: 49 return f' static constexpr uint32_t {self.name} = {self.col_index};' 50 51 def coltype_enum(self) -> str: 52 return f' using {self.name} = {self.typed_column_type};' 53 54 def row_field(self) -> Optional[str]: 55 if self.is_implicit_id: 56 return None 57 if self.is_ancestor: 58 return None 59 return f' {self.cpp_type} {self.name};' 60 61 def row_param(self) -> Optional[str]: 62 if self.is_implicit_id: 63 return None 64 return f'{self.cpp_type} in_{self.name} = {{}}' 65 66 def parent_row_initializer(self) -> Optional[str]: 67 if self.is_implicit_id: 68 return None 69 if not self.is_ancestor: 70 return None 71 return f'in_{self.name}' 72 73 def row_initializer(self) -> Optional[str]: 74 if self.is_implicit_id: 75 return None 76 if self.is_ancestor: 77 return None 78 return f'{self.name}(in_{self.name})' 79 80 def const_row_ref_getter(self) -> Optional[str]: 81 return f'''ColumnType::{self.name}::type {self.name}() const {{ 82 return table()->{self.name}()[row_number_]; 83 }}''' 84 85 def row_ref_getter(self) -> Optional[str]: 86 if self.is_implicit_id: 87 return None 88 return f'''void set_{self.name}( 89 ColumnType::{self.name}::non_optional_type v) {{ 90 return mutable_table()->mutable_{self.name}()->Set(row_number_, v); 91 }}''' 92 93 def flag(self) -> Optional[str]: 94 if self.is_implicit_id: 95 return None 96 if self.is_ancestor: 97 return None 98 default = f'ColumnType::{self.name}::default_flags()' 99 if self.flags == ColumnFlag.NONE: 100 flags = default 101 else: 102 flags = f'static_cast<uint32_t>({to_cpp_flags(self.flags)}) | {default}' 103 return f''' 104 static constexpr uint32_t {self.name} = {flags}; 105 ''' 106 107 def storage_init(self) -> Optional[str]: 108 if self.is_implicit_id: 109 return None 110 if self.is_ancestor: 111 return None 112 113 storage = f'ColumnStorage<ColumnType::{self.name}::stored_type>' 114 dense = str(ColumnFlag.DENSE in self.flags).lower() 115 return f'''{self.name}_({storage}::Create<{dense}>())''' 116 117 def column_init(self) -> Optional[str]: 118 if self.is_implicit_id: 119 return None 120 if self.is_ancestor: 121 return None 122 return f''' 123 AddColumnToVector(columns, "{self.name}", &self->{self.name}_, ColumnFlag::{self.name}, 124 static_cast<uint32_t>(columns.size()), olay_idx); 125 ''' 126 127 def shrink_to_fit(self) -> Optional[str]: 128 if self.is_implicit_id: 129 return None 130 if self.is_ancestor: 131 return None 132 return f' {self.name}_.ShrinkToFit();' 133 134 def append(self) -> Optional[str]: 135 if self.is_implicit_id: 136 return None 137 if self.is_ancestor: 138 return None 139 return f' mutable_{self.name}()->Append(row.{self.name});' 140 141 def accessor(self) -> Optional[str]: 142 inner = f'columns()[ColumnIndex::{self.name}]' 143 return f''' 144 const {self.typed_column_type}& {self.name}() const {{ 145 return static_cast<const ColumnType::{self.name}&>({inner}); 146 }} 147 ''' 148 149 def mutable_accessor(self) -> Optional[str]: 150 if self.is_implicit_id: 151 return None 152 return f''' 153 {self.typed_column_type}* mutable_{self.name}() {{ 154 return static_cast<ColumnType::{self.name}*>( 155 GetColumn(ColumnIndex::{self.name})); 156 }} 157 ''' 158 159 def storage(self) -> Optional[str]: 160 if self.is_implicit_id: 161 return None 162 if self.is_ancestor: 163 return None 164 name = self.name 165 return f' ColumnStorage<ColumnType::{name}::stored_type> {name}_;' 166 167 def iterator_getter(self) -> Optional[str]: 168 name = self.name 169 return f''' 170 ColumnType::{self.name}::type {name}() const {{ 171 const auto& col = table()->{name}(); 172 return col.GetAtIdx( 173 iterator_.StorageIndexForColumn(col.index_in_table())); 174 }} 175 ''' 176 177 def static_schema(self) -> Optional[str]: 178 if self.is_implicit_id: 179 return None 180 return f''' 181 schema.columns.emplace_back(Table::Schema::Column{{ 182 "{self.name}", ColumnType::{self.name}::SqlValueType(), false, 183 {str(ColumnFlag.SORTED in self.flags).lower()}, 184 {str(ColumnFlag.HIDDEN in self.flags).lower()}, 185 {str(ColumnFlag.SET_ID in self.flags).lower()}}}); 186 ''' 187 188 def row_eq(self) -> Optional[str]: 189 if self.is_implicit_id: 190 return None 191 return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})' 192 193 def extend_parent_param(self) -> Optional[str]: 194 if self.is_implicit_id: 195 return None 196 if self.is_ancestor: 197 return None 198 return f'ColumnStorage<ColumnType::{self.name}::stored_type> {self.name}' 199 200 def extend_parent_param_arg(self) -> Optional[str]: 201 if self.is_implicit_id: 202 return None 203 if self.is_ancestor: 204 return None 205 return f'std::move({self.name})' 206 207 def static_assert_flags(self) -> Optional[str]: 208 if self.is_implicit_id: 209 return None 210 if self.is_ancestor: 211 return None 212 return f''' 213 static_assert( 214 ColumnLegacy::IsFlagsAndTypeValid<ColumnType::{self.name}::stored_type>( 215 ColumnFlag::{self.name}), 216 "Column type and flag combination is not valid"); 217 ''' 218 219 def extend_nullable_vector(self) -> Optional[str]: 220 if self.is_implicit_id: 221 return None 222 if self.is_ancestor: 223 return None 224 return f''' 225 PERFETTO_DCHECK({self.name}.size() == parent_overlay.size()); 226 {self.name}_ = std::move({self.name}); 227 ''' 228 229 def storage_layer(self) -> Optional[str]: 230 if self.is_ancestor: 231 return None 232 return f''' 233 RefPtr<column::StorageLayer> {self.name}_storage_layer_; 234 ''' 235 236 def null_layer(self) -> Optional[str]: 237 if self.is_ancestor: 238 return None 239 if not self.is_optional or self.is_string: 240 return f'' 241 return f''' 242 RefPtr<column::OverlayLayer> {self.name}_null_layer_; 243 ''' 244 245 def storage_layer_create(self) -> str: 246 if self.is_ancestor: 247 return f'''const_parent_->storage_layers()[ColumnIndex::{self.name}]''' 248 return f'''{self.name}_storage_layer_''' 249 250 def null_layer_create(self) -> str: 251 if not self.is_optional or self.is_string: 252 return f'{{}}' 253 if self.is_ancestor: 254 return f'''const_parent_->null_layers()[ColumnIndex::{self.name}]''' 255 return f'''{self.name}_null_layer_''' 256 257 def storage_layer_init(self) -> str: 258 if self.is_ancestor: 259 return f'' 260 if self.is_implicit_id: 261 return f'{self.name}_storage_layer_(new column::IdStorage())' 262 if self.is_string: 263 return f'''{self.name}_storage_layer_( 264 new column::StringStorage(string_pool(), &{self.name}_.vector()))''' 265 if ColumnFlag.SET_ID in self.flags: 266 return f'''{self.name}_storage_layer_( 267 new column::SetIdStorage(&{self.name}_.vector()))''' 268 if self.is_optional: 269 return f'''{self.name}_storage_layer_( 270 new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>( 271 &{self.name}_.non_null_vector(), 272 ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(), 273 {str(ColumnFlag.SORTED in self.flags).lower()}))''' 274 return f'''{self.name}_storage_layer_( 275 new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>( 276 &{self.name}_.vector(), 277 ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(), 278 {str(ColumnFlag.SORTED in self.flags).lower()}))''' 279 280 def null_layer_init(self) -> str: 281 if self.is_ancestor: 282 return f'' 283 if not self.is_optional or self.is_string: 284 return f'' 285 if ColumnFlag.DENSE in self.flags: 286 return f'''{self.name}_null_layer_(new column::DenseNullOverlay({self.name}_.bv()))''' 287 return f'''{self.name}_null_layer_(new column::NullOverlay({self.name}_.bv()))''' 288 289 290class TableSerializer(object): 291 """Functions for seralizing a single Table into C++.""" 292 293 def __init__(self, parsed: ParsedTable): 294 self.table = parsed.table 295 self.table_name = parsed.table.class_name 296 self.column_serializers = [] 297 298 if parsed.table.parent: 299 self.parent_class_name = parsed.table.parent.class_name 300 else: 301 self.parent_class_name = 'macros_internal::RootParentTable' 302 303 self.column_serializers = [] 304 for c in parsed.columns: 305 # Aliases should be ignored as they are handled in SQL currently. 306 if isinstance(c.column.type, Alias): 307 continue 308 self.column_serializers.append( 309 ColumnSerializer(parsed, c, len(self.column_serializers))) 310 311 def foreach_col(self, serialize_fn, delimiter='\n') -> str: 312 lines = [] 313 for c in self.column_serializers: 314 serialized = serialize_fn(c) 315 if serialized: 316 lines.append(serialized.lstrip('\n').rstrip()) 317 return delimiter.join(lines).strip() 318 319 def id_defn(self) -> str: 320 if self.table.parent: 321 return f''' 322 using Id = {self.table.parent.class_name}::Id; 323 ''' 324 return ''' 325 struct Id : public BaseId { 326 Id() = default; 327 explicit constexpr Id(uint32_t v) : BaseId(v) {} 328 }; 329 static_assert(std::is_trivially_destructible_v<Id>, 330 "Inheritance used without trivial destruction"); 331 ''' 332 333 def row_struct(self) -> str: 334 param = self.foreach_col( 335 ColumnSerializer.row_param, delimiter=',\n ') 336 parent_row_init = self.foreach_col( 337 ColumnSerializer.parent_row_initializer, delimiter=', ') 338 row_init = self.foreach_col( 339 ColumnSerializer.row_initializer, delimiter=',\n ') 340 parent_separator = ',' if row_init else '' 341 row_eq = self.foreach_col(ColumnSerializer.row_eq, delimiter=' &&\n ') 342 return f''' 343 struct Row : public {self.parent_class_name}::Row {{ 344 Row({param}, 345 std::nullptr_t = nullptr) 346 : {self.parent_class_name}::Row({parent_row_init}){parent_separator} 347 {row_init} {{}} 348 {self.foreach_col(ColumnSerializer.row_field)} 349 350 bool operator==(const {self.table_name}::Row& other) const {{ 351 return {row_eq}; 352 }} 353 }}; 354 ''' 355 356 def const_row_reference_struct(self) -> str: 357 row_ref_getters = self.foreach_col( 358 ColumnSerializer.const_row_ref_getter, delimiter='\n ') 359 return f''' 360 class ConstRowReference : public macros_internal::AbstractConstRowReference< 361 {self.table_name}, RowNumber> {{ 362 public: 363 ConstRowReference(const {self.table_name}* table, uint32_t row_number) 364 : AbstractConstRowReference(table, row_number) {{}} 365 366 {row_ref_getters} 367 }}; 368 static_assert(std::is_trivially_destructible_v<ConstRowReference>, 369 "Inheritance used without trivial destruction"); 370 ''' 371 372 def row_reference_struct(self) -> str: 373 row_ref_getters = self.foreach_col( 374 ColumnSerializer.row_ref_getter, delimiter='\n ') 375 return f''' 376 class RowReference : public ConstRowReference {{ 377 public: 378 RowReference(const {self.table_name}* table, uint32_t row_number) 379 : ConstRowReference(table, row_number) {{}} 380 381 {row_ref_getters} 382 383 private: 384 {self.table_name}* mutable_table() const {{ 385 return const_cast<{self.table_name}*>(table()); 386 }} 387 }}; 388 static_assert(std::is_trivially_destructible_v<RowReference>, 389 "Inheritance used without trivial destruction"); 390 ''' 391 392 def constructor(self) -> str: 393 storage_init = self.foreach_col( 394 ColumnSerializer.storage_init, delimiter=',\n ') 395 storage_layer_init = self.foreach_col( 396 ColumnSerializer.storage_layer_init, delimiter=',\n ') 397 storage_layer_sep = '\n,' if storage_layer_init else '' 398 null_layer_init = self.foreach_col( 399 ColumnSerializer.null_layer_init, delimiter=',\n ') 400 null_layer_sep = '\n,' if null_layer_init else '' 401 if self.table.parent: 402 parent_param = f', {self.parent_class_name}* parent' 403 parent_arg = 'parent' 404 parent_init = 'parent_(parent), const_parent_(parent)' + ( 405 ', ' if storage_init else '') 406 else: 407 parent_param = '' 408 parent_arg = 'nullptr' 409 parent_init = '' 410 col_init = self.foreach_col(ColumnSerializer.column_init) 411 if col_init: 412 olay = 'uint32_t olay_idx = OverlayCount(parent);' 413 else: 414 olay = '' 415 storage_layer_create = self.foreach_col( 416 ColumnSerializer.storage_layer_create, delimiter=',') 417 null_layer_create = self.foreach_col( 418 ColumnSerializer.null_layer_create, delimiter=',') 419 return f''' 420 static std::vector<ColumnLegacy> GetColumns( 421 {self.table_name}* self, 422 const macros_internal::MacroTable* parent) {{ 423 std::vector<ColumnLegacy> columns = 424 CopyColumnsFromParentOrAddRootColumns(parent); 425 {olay} 426 {col_init} 427 base::ignore_result(self); 428 return columns; 429 }} 430 431 PERFETTO_NO_INLINE explicit {self.table_name}(StringPool* pool{parent_param}) 432 : macros_internal::MacroTable( 433 pool, 434 GetColumns(this, {parent_arg}), 435 {parent_arg}), 436 {parent_init}{storage_init}{storage_layer_sep} 437 {storage_layer_init}{null_layer_sep} 438 {null_layer_init} {{ 439 {self.foreach_col(ColumnSerializer.static_assert_flags)} 440 OnConstructionCompletedRegularConstructor( 441 {{{storage_layer_create}}}, 442 {{{null_layer_create}}}); 443 }} 444 ''' 445 446 def parent_field(self) -> str: 447 if self.table.parent: 448 return f''' 449 {self.parent_class_name}* parent_ = nullptr; 450 const {self.parent_class_name}* const_parent_ = nullptr; 451 ''' 452 return '' 453 454 def insert_common(self) -> str: 455 if self.table.parent: 456 return ''' 457 Id id = Id{parent_->Insert(row).id}; 458 UpdateOverlaysAfterParentInsert(); 459 ''' 460 return ''' 461 Id id = Id{row_number}; 462 ''' 463 464 def const_iterator(self) -> str: 465 iterator_getters = self.foreach_col( 466 ColumnSerializer.iterator_getter, delimiter='\n') 467 return f''' 468 class ConstIterator; 469 class ConstIterator : public macros_internal::AbstractConstIterator< 470 ConstIterator, {self.table_name}, RowNumber, ConstRowReference> {{ 471 public: 472 {iterator_getters} 473 474 protected: 475 explicit ConstIterator(const {self.table_name}* table, 476 Table::Iterator iterator) 477 : AbstractConstIterator(table, std::move(iterator)) {{}} 478 479 uint32_t CurrentRowNumber() const {{ 480 return iterator_.StorageIndexForLastOverlay(); 481 }} 482 483 private: 484 friend class {self.table_name}; 485 friend class macros_internal::AbstractConstIterator< 486 ConstIterator, {self.table_name}, RowNumber, ConstRowReference>; 487 }}; 488 ''' 489 490 def iterator(self) -> str: 491 return f''' 492 class Iterator : public ConstIterator {{ 493 public: 494 RowReference row_reference() const {{ 495 return {{const_cast<{self.table_name}*>(table()), CurrentRowNumber()}}; 496 }} 497 498 private: 499 friend class {self.table_name}; 500 501 explicit Iterator({self.table_name}* table, Table::Iterator iterator) 502 : ConstIterator(table, std::move(iterator)) {{}} 503 }}; 504 ''' 505 506 def extend(self) -> str: 507 if not self.table.parent: 508 return '' 509 params = self.foreach_col( 510 ColumnSerializer.extend_parent_param, delimiter='\n, ') 511 args = self.foreach_col( 512 ColumnSerializer.extend_parent_param_arg, delimiter=', ') 513 delim = ',' if params else '' 514 return f''' 515 static std::unique_ptr<{self.table_name}> ExtendParent( 516 const {self.parent_class_name}& parent{delim} 517 {params}) {{ 518 return std::unique_ptr<{self.table_name}>(new {self.table_name}( 519 parent.string_pool(), parent, RowMap(0, parent.row_count()){delim} 520 {args})); 521 }} 522 523 static std::unique_ptr<{self.table_name}> SelectAndExtendParent( 524 const {self.parent_class_name}& parent, 525 std::vector<{self.parent_class_name}::RowNumber> parent_overlay{delim} 526 {params}) {{ 527 std::vector<uint32_t> prs_untyped(parent_overlay.size()); 528 for (uint32_t i = 0; i < parent_overlay.size(); ++i) {{ 529 prs_untyped[i] = parent_overlay[i].row_number(); 530 }} 531 return std::unique_ptr<{self.table_name}>(new {self.table_name}( 532 parent.string_pool(), parent, RowMap(std::move(prs_untyped)){delim} 533 {args})); 534 }} 535 ''' 536 537 def extend_constructor(self) -> str: 538 if not self.table.parent: 539 return '' 540 storage_layer_init = self.foreach_col( 541 ColumnSerializer.storage_layer_init, delimiter=',\n ') 542 storage_layer_sep = '\n,' if storage_layer_init else '' 543 null_layer_init = self.foreach_col( 544 ColumnSerializer.null_layer_init, delimiter=',\n ') 545 null_layer_sep = '\n,' if null_layer_init else '' 546 params = self.foreach_col( 547 ColumnSerializer.extend_parent_param, delimiter='\n, ') 548 storage_layer_create = self.foreach_col( 549 ColumnSerializer.storage_layer_create, delimiter=',') 550 null_layer_create = self.foreach_col( 551 ColumnSerializer.null_layer_create, delimiter=',') 552 return f''' 553 {self.table_name}(StringPool* pool, 554 const {self.parent_class_name}& parent, 555 const RowMap& parent_overlay{',' if params else ''} 556 {params}) 557 : macros_internal::MacroTable( 558 pool, 559 GetColumns(this, &parent), 560 parent, 561 parent_overlay), 562 const_parent_(&parent){storage_layer_sep} 563 {storage_layer_init}{null_layer_sep} 564 {null_layer_init} {{ 565 {self.foreach_col(ColumnSerializer.static_assert_flags)} 566 {self.foreach_col(ColumnSerializer.extend_nullable_vector)} 567 568 std::vector<RefPtr<column::OverlayLayer>> overlay_layers(OverlayCount(&parent) + 1); 569 for (uint32_t i = 0; i < overlay_layers.size(); ++i) {{ 570 if (overlays()[i].row_map().IsIndexVector()) {{ 571 overlay_layers[i].reset(new column::ArrangementOverlay( 572 overlays()[i].row_map().GetIfIndexVector(), 573 column::DataLayerChain::Indices::State::kNonmonotonic)); 574 }} else if (overlays()[i].row_map().IsBitVector()) {{ 575 overlay_layers[i].reset(new column::SelectorOverlay( 576 overlays()[i].row_map().GetIfBitVector())); 577 }} else if (overlays()[i].row_map().IsRange()) {{ 578 overlay_layers[i].reset(new column::RangeOverlay( 579 overlays()[i].row_map().GetIfIRange())); 580 }} 581 }} 582 583 OnConstructionCompleted( 584 {{{storage_layer_create}}}, {{{null_layer_create}}}, std::move(overlay_layers)); 585 }} 586 ''' 587 588 def column_count(self) -> str: 589 return str(len(self.column_serializers)) 590 591 def serialize(self) -> str: 592 return f''' 593class {self.table_name} : public macros_internal::MacroTable {{ 594 public: 595 static constexpr uint32_t kColumnCount = {self.column_count().strip()}; 596 597 {self.id_defn().lstrip()} 598 struct ColumnIndex {{ 599 {self.foreach_col(ColumnSerializer.colindex)} 600 }}; 601 struct ColumnType {{ 602 {self.foreach_col(ColumnSerializer.coltype_enum)} 603 }}; 604 {self.row_struct().strip()} 605 struct ColumnFlag {{ 606 {self.foreach_col(ColumnSerializer.flag)} 607 }}; 608 609 class RowNumber; 610 class ConstRowReference; 611 class RowReference; 612 613 class RowNumber : public macros_internal::AbstractRowNumber< 614 {self.table_name}, ConstRowReference, RowReference> {{ 615 public: 616 explicit RowNumber(uint32_t row_number) 617 : AbstractRowNumber(row_number) {{}} 618 }}; 619 static_assert(std::is_trivially_destructible_v<RowNumber>, 620 "Inheritance used without trivial destruction"); 621 622 {self.const_row_reference_struct().strip()} 623 {self.row_reference_struct().strip()} 624 625 {self.const_iterator().strip()} 626 {self.iterator().strip()} 627 628 struct IdAndRow {{ 629 Id id; 630 uint32_t row; 631 RowReference row_reference; 632 RowNumber row_number; 633 }}; 634 635 {self.constructor().strip()} 636 ~{self.table_name}() override; 637 638 static const char* Name() {{ return "{self.table.sql_name}"; }} 639 640 static Table::Schema ComputeStaticSchema() {{ 641 Table::Schema schema; 642 schema.columns.emplace_back(Table::Schema::Column{{ 643 "id", SqlValue::Type::kLong, true, true, false, false}}); 644 {self.foreach_col(ColumnSerializer.static_schema)} 645 return schema; 646 }} 647 648 ConstIterator IterateRows() const {{ 649 return ConstIterator(this, Table::IterateRows()); 650 }} 651 652 Iterator IterateRows() {{ return Iterator(this, Table::IterateRows()); }} 653 654 ConstIterator FilterToIterator(const Query& q) const {{ 655 return ConstIterator(this, QueryToIterator(q)); 656 }} 657 658 Iterator FilterToIterator(const Query& q) {{ 659 return Iterator(this, QueryToIterator(q)); 660 }} 661 662 void ShrinkToFit() {{ 663 {self.foreach_col(ColumnSerializer.shrink_to_fit)} 664 }} 665 666 ConstRowReference operator[](uint32_t r) const {{ 667 return ConstRowReference(this, r); 668 }} 669 RowReference operator[](uint32_t r) {{ return RowReference(this, r); }} 670 ConstRowReference operator[](RowNumber r) const {{ 671 return ConstRowReference(this, r.row_number()); 672 }} 673 RowReference operator[](RowNumber r) {{ 674 return RowReference(this, r.row_number()); 675 }} 676 677 std::optional<ConstRowReference> FindById(Id find_id) const {{ 678 std::optional<uint32_t> row = id().IndexOf(find_id); 679 return row ? std::make_optional(ConstRowReference(this, *row)) 680 : std::nullopt; 681 }} 682 683 std::optional<RowReference> FindById(Id find_id) {{ 684 std::optional<uint32_t> row = id().IndexOf(find_id); 685 return row ? std::make_optional(RowReference(this, *row)) : std::nullopt; 686 }} 687 688 IdAndRow Insert(const Row& row) {{ 689 uint32_t row_number = row_count(); 690 {self.insert_common().strip()} 691 {self.foreach_col(ColumnSerializer.append)} 692 UpdateSelfOverlayAfterInsert(); 693 return IdAndRow{{id, row_number, RowReference(this, row_number), 694 RowNumber(row_number)}}; 695 }} 696 697 {self.extend().strip()} 698 699 {self.foreach_col(ColumnSerializer.accessor)} 700 701 {self.foreach_col(ColumnSerializer.mutable_accessor)} 702 703 private: 704 {self.extend_constructor().strip()} 705 {self.parent_field().strip()} 706 {self.foreach_col(ColumnSerializer.storage)} 707 708 {self.foreach_col(ColumnSerializer.storage_layer)} 709 710 {self.foreach_col(ColumnSerializer.null_layer)} 711}}; 712 '''.strip('\n') 713 714 715def serialize_header(ifdef_guard: str, tables: List[ParsedTable], 716 include_paths: List[str]) -> str: 717 """Serializes a table header file containing the given set of tables.""" 718 # Replace the backslash with forward slash when building on Windows. 719 # Caused b/327985369 without the replace. 720 include_paths_str = '\n'.join([f'#include "{i}"' for i in include_paths 721 ]).replace("\\", "/") 722 tables_str = '\n\n'.join([TableSerializer(t).serialize() for t in tables]) 723 return f''' 724#ifndef {ifdef_guard} 725#define {ifdef_guard} 726 727#include <array> 728#include <cstddef> 729#include <cstdint> 730#include <memory> 731#include <optional> 732#include <type_traits> 733#include <utility> 734#include <vector> 735 736#include "perfetto/base/logging.h" 737#include "perfetto/trace_processor/basic_types.h" 738#include "perfetto/trace_processor/ref_counted.h" 739#include "src/trace_processor/containers/bit_vector.h" 740#include "src/trace_processor/containers/row_map.h" 741#include "src/trace_processor/containers/string_pool.h" 742#include "src/trace_processor/db/column/arrangement_overlay.h" 743#include "src/trace_processor/db/column/data_layer.h" 744#include "src/trace_processor/db/column/dense_null_overlay.h" 745#include "src/trace_processor/db/column/numeric_storage.h" 746#include "src/trace_processor/db/column/id_storage.h" 747#include "src/trace_processor/db/column/null_overlay.h" 748#include "src/trace_processor/db/column/range_overlay.h" 749#include "src/trace_processor/db/column/selector_overlay.h" 750#include "src/trace_processor/db/column/set_id_storage.h" 751#include "src/trace_processor/db/column/string_storage.h" 752#include "src/trace_processor/db/column/types.h" 753#include "src/trace_processor/db/column_storage.h" 754#include "src/trace_processor/db/column.h" 755#include "src/trace_processor/db/table.h" 756#include "src/trace_processor/db/typed_column.h" 757#include "src/trace_processor/db/typed_column_internal.h" 758#include "src/trace_processor/tables/macros_internal.h" 759 760{include_paths_str} 761 762namespace perfetto::trace_processor::tables {{ 763 764{tables_str.strip()} 765 766}} // namespace perfetto 767 768#endif // {ifdef_guard} 769 '''.strip() 770 771 772def to_cpp_flags(raw_flag: ColumnFlag) -> str: 773 """Converts a ColumnFlag to the C++ flags which it represents 774 775 It is not valid to call this function with ColumnFlag.NONE as in this case 776 defaults for that column should be implicitly used.""" 777 778 assert raw_flag != ColumnFlag.NONE 779 flags = [] 780 if ColumnFlag.SORTED in raw_flag: 781 flags.append('ColumnLegacy::Flag::kSorted') 782 if ColumnFlag.HIDDEN in raw_flag: 783 flags.append('ColumnLegacy::Flag::kHidden') 784 if ColumnFlag.DENSE in raw_flag: 785 flags.append('ColumnLegacy::Flag::kDense') 786 if ColumnFlag.SET_ID in raw_flag: 787 flags.append('ColumnLegacy::Flag::kSetId') 788 return ' | '.join(flags) 789