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