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