Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 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 | |
| 15 | from typing import List |
| 16 | from typing import Optional |
| 17 | |
| 18 | from python.generators.trace_processor_table.public import Alias |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 19 | from python.generators.trace_processor_table.public import ColumnFlag |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 20 | from python.generators.trace_processor_table.util import ParsedTable |
| 21 | from python.generators.trace_processor_table.util import ParsedColumn |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 22 | from python.generators.trace_processor_table.util import parse_type |
| 23 | from python.generators.trace_processor_table.util import typed_column_type |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 24 | |
| 25 | |
| 26 | class ColumnSerializer: |
| 27 | """Functions for serializing a single Column in a table into C++.""" |
| 28 | |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 29 | def __init__(self, table: ParsedTable, column: ParsedColumn, col_index: int): |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 30 | self.col_index = col_index |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 31 | self.parsed_col = column |
| 32 | self.col = self.parsed_col.column |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 33 | self.name = self.col.name |
| 34 | self.flags = self.col.flags |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 35 | self.typed_column_type = typed_column_type(table.table, self.parsed_col) |
| 36 | self.cpp_type = parse_type(table.table, |
| 37 | self.col.type).cpp_type_with_optionality() |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 38 | |
| 39 | self.is_implicit_id = self.parsed_col.is_implicit_id |
| 40 | self.is_implicit_type = self.parsed_col.is_implicit_type |
| 41 | self.is_ancestor = self.parsed_col.is_ancestor |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 42 | |
| 43 | def colindex(self) -> str: |
| 44 | return f' static constexpr uint32_t {self.name} = {self.col_index};' |
| 45 | |
| 46 | def coltype_enum(self) -> str: |
| 47 | return f' using {self.name} = {self.typed_column_type};' |
| 48 | |
| 49 | def row_field(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 50 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 51 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 52 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 53 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 54 | return f' {self.cpp_type} {self.name};' |
| 55 | |
| 56 | def row_param(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 57 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 58 | return None |
| 59 | return f'{self.cpp_type} in_{self.name} = {{}}' |
| 60 | |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 61 | def parent_row_initializer(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 62 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 63 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 64 | if not self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 65 | return None |
| 66 | return f'std::move(in_{self.name})' |
| 67 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 68 | def row_initializer(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 69 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 70 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 71 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 72 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 73 | return f'{self.name}(std::move(in_{self.name}))' |
| 74 | |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 75 | def const_row_ref_getter(self) -> Optional[str]: |
| 76 | return f'''ColumnType::{self.name}::type {self.name}() const {{ |
| 77 | return table_->{self.name}()[row_number_]; |
| 78 | }}''' |
| 79 | |
| 80 | def row_ref_getter(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 81 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 82 | return None |
| 83 | return f'''void set_{self.name}( |
| 84 | ColumnType::{self.name}::non_optional_type v) {{ |
| 85 | return mutable_table()->mutable_{self.name}()->Set(row_number_, v); |
| 86 | }}''' |
| 87 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 88 | def flag(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 89 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 90 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 91 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 92 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 93 | default = f'ColumnType::{self.name}::default_flags()' |
| 94 | if self.flags == ColumnFlag.NONE: |
| 95 | flags = default |
| 96 | else: |
| 97 | flags = f'static_cast<uint32_t>({to_cpp_flags(self.flags)}) | {default}' |
| 98 | return f''' |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 99 | static constexpr uint32_t {self.name} = {flags}; |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 100 | ''' |
| 101 | |
| 102 | def storage_init(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 103 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 104 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 105 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 106 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 107 | |
| 108 | storage = f'ColumnStorage<ColumnType::{self.name}::stored_type>' |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 109 | dense = str(ColumnFlag.DENSE in self.flags).lower() |
| 110 | return f'''{self.name}_({storage}::Create<{dense}>())''' |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 111 | |
| 112 | def column_init(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 113 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 114 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 115 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 116 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 117 | return f''' |
| 118 | columns_.emplace_back("{self.name}", &{self.name}_, ColumnFlag::{self.name}, |
| 119 | this, static_cast<uint32_t>(columns_.size()), |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 120 | olay_idx); |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 121 | ''' |
| 122 | |
| 123 | def shrink_to_fit(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 124 | if self.is_implicit_id: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 125 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 126 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 127 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 128 | return f' {self.name}_.ShrinkToFit();' |
| 129 | |
| 130 | def append(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 131 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 132 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 133 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 134 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 135 | return f' mutable_{self.name}()->Append(std::move(row.{self.name}));' |
| 136 | |
| 137 | def accessor(self) -> Optional[str]: |
| 138 | inner = f'columns_[ColumnIndex::{self.name}]' |
| 139 | return f''' |
| 140 | const {self.typed_column_type}& {self.name}() const {{ |
| 141 | return static_cast<const ColumnType::{self.name}&>({inner}); |
| 142 | }} |
| 143 | ''' |
| 144 | |
| 145 | def mutable_accessor(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 146 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 147 | return None |
| 148 | return f''' |
| 149 | {self.typed_column_type}* mutable_{self.name}() {{ |
| 150 | return static_cast<ColumnType::{self.name}*>( |
| 151 | &columns_[ColumnIndex::{self.name}]); |
| 152 | }} |
| 153 | ''' |
| 154 | |
| 155 | def storage(self) -> Optional[str]: |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 156 | if self.is_implicit_id or self.is_implicit_type: |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 157 | return None |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 158 | if self.is_ancestor: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 159 | return None |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 160 | name = self.name |
| 161 | return f' ColumnStorage<ColumnType::{name}::stored_type> {name}_;' |
| 162 | |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 163 | def iterator_getter(self) -> Optional[str]: |
| 164 | name = self.name |
| 165 | return f''' |
| 166 | ColumnType::{self.name}::type {name}() const {{ |
| 167 | const auto& col = table_->{name}(); |
| 168 | return col.GetAtIdx(its_[col.overlay_index()].index()); |
| 169 | }} |
| 170 | ''' |
| 171 | |
| 172 | def iterator_setter(self) -> Optional[str]: |
| 173 | if self.is_implicit_id or self.is_implicit_type: |
| 174 | return None |
| 175 | return f''' |
| 176 | void set_{self.name}(ColumnType::{self.name}::non_optional_type v) {{ |
| 177 | auto* col = mutable_table_->mutable_{self.name}(); |
| 178 | col->SetAtIdx(its_[col->overlay_index()].index(), v); |
| 179 | }} |
| 180 | ''' |
| 181 | |
| 182 | def static_schema(self) -> Optional[str]: |
| 183 | if self.is_implicit_id or self.is_implicit_type: |
| 184 | return None |
| 185 | return f''' |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 186 | schema.columns.emplace_back(Table::Schema::Column{{ |
| 187 | "{self.name}", ColumnType::{self.name}::SqlValueType(), false, |
| 188 | {str(ColumnFlag.SORTED in self.flags).lower()}, |
| 189 | {str(ColumnFlag.HIDDEN in self.flags).lower()}, |
| 190 | {str(ColumnFlag.SET_ID in self.flags).lower()}}}); |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 191 | ''' |
| 192 | |
| 193 | def row_eq(self) -> Optional[str]: |
| 194 | if self.is_implicit_id or self.is_implicit_type: |
| 195 | return None |
| 196 | return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})' |
| 197 | |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 198 | def extend_parent_param(self) -> Optional[str]: |
| 199 | if self.is_implicit_id or self.is_implicit_type: |
| 200 | return None |
| 201 | if self.is_ancestor: |
| 202 | return None |
| 203 | return f'ColumnStorage<ColumnType::{self.name}::stored_type> {self.name}' |
| 204 | |
| 205 | def extend_parent_param_arg(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'std::move({self.name})' |
| 211 | |
| 212 | def static_assert_flags(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''' |
| 218 | static_assert( |
| 219 | Column::IsFlagsAndTypeValid<ColumnType::{self.name}::stored_type>( |
| 220 | ColumnFlag::{self.name}), |
| 221 | "Column type and flag combination is not valid"); |
| 222 | ''' |
| 223 | |
| 224 | def extend_nullable_vector(self) -> Optional[str]: |
| 225 | if self.is_implicit_id or self.is_implicit_type: |
| 226 | return None |
| 227 | if self.is_ancestor: |
| 228 | return None |
| 229 | return f''' |
| 230 | PERFETTO_DCHECK({self.name}.size() == parent_overlay.size()); |
| 231 | {self.name}_ = std::move({self.name}); |
| 232 | ''' |
| 233 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 234 | |
| 235 | class TableSerializer(object): |
| 236 | """Functions for seralizing a single Table into C++.""" |
| 237 | |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 238 | def __init__(self, parsed: ParsedTable): |
| 239 | self.table = parsed.table |
| 240 | self.table_name = parsed.table.class_name |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 241 | self.column_serializers = [] |
| 242 | |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 243 | if parsed.table.parent: |
| 244 | self.parent_class_name = parsed.table.parent.class_name |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 245 | else: |
| 246 | self.parent_class_name = 'macros_internal::RootParentTable' |
| 247 | |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 248 | self.column_serializers = [] |
| 249 | for c in parsed.columns: |
| 250 | # Aliases should be ignored as they are handled in SQL currently. |
| 251 | if isinstance(c.column.type, Alias): |
| 252 | continue |
| 253 | self.column_serializers.append( |
| 254 | ColumnSerializer(parsed, c, len(self.column_serializers))) |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 255 | |
| 256 | def foreach_col(self, serialize_fn, delimiter='\n') -> str: |
| 257 | lines = [] |
| 258 | for c in self.column_serializers: |
| 259 | serialized = serialize_fn(c) |
| 260 | if serialized: |
| 261 | lines.append(serialized.lstrip('\n').rstrip()) |
| 262 | return delimiter.join(lines).strip() |
| 263 | |
| 264 | def id_defn(self) -> str: |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 265 | if self.table.parent: |
| 266 | return f''' |
| 267 | using Id = {self.table.parent.class_name}::Id; |
| 268 | ''' |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 269 | return ''' |
| 270 | struct Id : public BaseId { |
| 271 | Id() = default; |
| 272 | explicit constexpr Id(uint32_t v) : BaseId(v) {} |
| 273 | }; |
| 274 | static_assert(std::is_trivially_destructible<Id>::value, |
| 275 | "Inheritance used without trivial destruction"); |
| 276 | ''' |
| 277 | |
| 278 | def row_struct(self) -> str: |
| 279 | param = self.foreach_col( |
| 280 | ColumnSerializer.row_param, delimiter=',\n ') |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 281 | parent_row_init = self.foreach_col( |
| 282 | ColumnSerializer.parent_row_initializer, delimiter=', ') |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 283 | row_init = self.foreach_col( |
| 284 | ColumnSerializer.row_initializer, delimiter=',\n ') |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 285 | parent_separator = ',' if row_init else '' |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 286 | row_eq = self.foreach_col(ColumnSerializer.row_eq, delimiter=' &&\n ') |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 287 | return f''' |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 288 | struct Row : public {self.parent_class_name}::Row {{ |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 289 | Row({param}, |
| 290 | std::nullptr_t = nullptr) |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 291 | : {self.parent_class_name}::Row({parent_row_init}){parent_separator} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 292 | {row_init} {{ |
| 293 | type_ = "{self.table.sql_name}"; |
| 294 | }} |
| 295 | {self.foreach_col(ColumnSerializer.row_field)} |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 296 | |
| 297 | bool operator==(const {self.table_name}::Row& other) const {{ |
| 298 | return type() == other.type() && {row_eq}; |
| 299 | }} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 300 | }}; |
| 301 | ''' |
| 302 | |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 303 | def const_row_reference_struct(self) -> str: |
| 304 | row_ref_getters = self.foreach_col( |
| 305 | ColumnSerializer.const_row_ref_getter, delimiter='\n ') |
| 306 | return f''' |
| 307 | class ConstRowReference : public macros_internal::AbstractConstRowReference< |
| 308 | {self.table_name}, RowNumber> {{ |
| 309 | public: |
| 310 | ConstRowReference(const {self.table_name}* table, uint32_t row_number) |
| 311 | : AbstractConstRowReference(table, row_number) {{}} |
| 312 | |
| 313 | {row_ref_getters} |
| 314 | }}; |
| 315 | static_assert(std::is_trivially_destructible<ConstRowReference>::value, |
| 316 | "Inheritance used without trivial destruction"); |
| 317 | ''' |
| 318 | |
| 319 | def row_reference_struct(self) -> str: |
| 320 | row_ref_getters = self.foreach_col( |
| 321 | ColumnSerializer.row_ref_getter, delimiter='\n ') |
| 322 | return f''' |
| 323 | class RowReference : public ConstRowReference {{ |
| 324 | public: |
| 325 | RowReference(const {self.table_name}* table, uint32_t row_number) |
| 326 | : ConstRowReference(table, row_number) {{}} |
| 327 | |
| 328 | {row_ref_getters} |
| 329 | |
| 330 | private: |
| 331 | {self.table_name}* mutable_table() const {{ |
| 332 | return const_cast<{self.table_name}*>(table_); |
| 333 | }} |
| 334 | }}; |
| 335 | static_assert(std::is_trivially_destructible<RowReference>::value, |
| 336 | "Inheritance used without trivial destruction"); |
| 337 | ''' |
| 338 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 339 | def constructor(self) -> str: |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 340 | storage_init = self.foreach_col( |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 341 | ColumnSerializer.storage_init, delimiter=',\n ') |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 342 | if self.table.parent: |
| 343 | parent_param = f', {self.parent_class_name}* parent' |
| 344 | parent_arg = 'parent' |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 345 | parent_init = 'parent_(parent)' + (', ' if storage_init else '') |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 346 | else: |
| 347 | parent_param = '' |
| 348 | parent_arg = 'nullptr' |
| 349 | parent_init = '' |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 350 | col_init = self.foreach_col(ColumnSerializer.column_init) |
| 351 | if col_init: |
| 352 | olay = 'uint32_t olay_idx = static_cast<uint32_t>(overlays_.size()) - 1;' |
| 353 | else: |
| 354 | olay = '' |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 355 | return f''' |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 356 | explicit {self.table_name}(StringPool* pool{parent_param}) |
| 357 | : macros_internal::MacroTable(pool, {parent_arg}), |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 358 | {parent_init}{storage_init} {{ |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 359 | {self.foreach_col(ColumnSerializer.static_assert_flags)} |
Lalit Maganti | 0c99810 | 2023-04-24 12:30:49 +0100 | [diff] [blame] | 360 | {olay} |
| 361 | {col_init} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 362 | }} |
| 363 | ''' |
| 364 | |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 365 | def parent_field(self) -> str: |
| 366 | if self.table.parent: |
| 367 | return f''' |
| 368 | {self.parent_class_name}* parent_ = nullptr; |
| 369 | ''' |
| 370 | return '' |
| 371 | |
| 372 | def insert_common(self) -> str: |
| 373 | if self.table.parent: |
| 374 | return ''' |
| 375 | Id id = Id{parent_->Insert(row).id}; |
| 376 | UpdateOverlaysAfterParentInsert(); |
| 377 | ''' |
| 378 | return ''' |
| 379 | Id id = Id{row_number}; |
| 380 | type_.Append(string_pool_->InternString(row.type())); |
| 381 | ''' |
| 382 | |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 383 | def const_iterator(self) -> str: |
| 384 | iterator_getters = self.foreach_col( |
| 385 | ColumnSerializer.iterator_getter, delimiter='\n') |
| 386 | return f''' |
| 387 | class ConstIterator; |
| 388 | class ConstIterator : public macros_internal::AbstractConstIterator< |
| 389 | ConstIterator, {self.table_name}, RowNumber, ConstRowReference> {{ |
| 390 | public: |
| 391 | {iterator_getters} |
| 392 | |
| 393 | protected: |
| 394 | explicit ConstIterator(const {self.table_name}* table, |
| 395 | std::vector<ColumnStorageOverlay> overlays) |
| 396 | : AbstractConstIterator(table, std::move(overlays)) {{}} |
| 397 | |
| 398 | uint32_t CurrentRowNumber() const {{ |
| 399 | return its_.back().index(); |
| 400 | }} |
| 401 | |
| 402 | private: |
| 403 | friend class {self.table_name}; |
Daniele Di Proietto | e53bcd3 | 2023-08-03 17:24:26 +0000 | [diff] [blame] | 404 | friend class macros_internal::AbstractConstIterator< |
| 405 | ConstIterator, {self.table_name}, RowNumber, ConstRowReference>; |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 406 | }}; |
| 407 | ''' |
| 408 | |
| 409 | def iterator(self) -> str: |
| 410 | iterator_setters = self.foreach_col( |
| 411 | ColumnSerializer.iterator_setter, delimiter='\n') |
| 412 | return f''' |
| 413 | class Iterator : public ConstIterator {{ |
| 414 | public: |
| 415 | {iterator_setters} |
| 416 | |
| 417 | RowReference row_reference() const {{ |
| 418 | return RowReference(mutable_table_, CurrentRowNumber()); |
| 419 | }} |
| 420 | |
| 421 | private: |
| 422 | friend class {self.table_name}; |
| 423 | |
| 424 | explicit Iterator({self.table_name}* table, |
| 425 | std::vector<ColumnStorageOverlay> overlays) |
| 426 | : ConstIterator(table, std::move(overlays)), |
| 427 | mutable_table_(table) {{}} |
| 428 | |
| 429 | {self.table_name}* mutable_table_ = nullptr; |
| 430 | }}; |
| 431 | ''' |
| 432 | |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 433 | def extend(self) -> str: |
| 434 | if not self.table.parent: |
| 435 | return '' |
| 436 | params = self.foreach_col( |
| 437 | ColumnSerializer.extend_parent_param, delimiter='\n, ') |
| 438 | args = self.foreach_col( |
| 439 | ColumnSerializer.extend_parent_param_arg, delimiter=', ') |
| 440 | delim = ',' if params else '' |
| 441 | return f''' |
| 442 | static std::unique_ptr<Table> ExtendParent( |
| 443 | const {self.parent_class_name}& parent{delim} |
| 444 | {params}) {{ |
| 445 | return std::unique_ptr<Table>(new {self.table_name}( |
| 446 | parent.string_pool(), parent, RowMap(0, parent.row_count()){delim} |
| 447 | {args})); |
| 448 | }} |
| 449 | |
| 450 | static std::unique_ptr<Table> SelectAndExtendParent( |
| 451 | const {self.parent_class_name}& parent, |
| 452 | std::vector<{self.parent_class_name}::RowNumber> parent_overlay{delim} |
| 453 | {params}) {{ |
| 454 | std::vector<uint32_t> prs_untyped(parent_overlay.size()); |
| 455 | for (uint32_t i = 0; i < parent_overlay.size(); ++i) {{ |
| 456 | prs_untyped[i] = parent_overlay[i].row_number(); |
| 457 | }} |
| 458 | return std::unique_ptr<Table>(new {self.table_name}( |
| 459 | parent.string_pool(), parent, RowMap(std::move(prs_untyped)){delim} |
| 460 | {args})); |
| 461 | }} |
| 462 | ''' |
| 463 | |
| 464 | def extend_constructor(self) -> str: |
| 465 | if not self.table.parent: |
| 466 | return '' |
| 467 | params = self.foreach_col( |
| 468 | ColumnSerializer.extend_parent_param, delimiter='\n, ') |
| 469 | if params: |
| 470 | olay = 'uint32_t olay_idx = static_cast<uint32_t>(overlays_.size()) - 1;' |
| 471 | else: |
| 472 | olay = '' |
| 473 | return f''' |
| 474 | {self.table_name}(StringPool* pool, |
| 475 | const {self.parent_class_name}& parent, |
| 476 | const RowMap& parent_overlay{',' if params else ''} |
| 477 | {params}) |
| 478 | : macros_internal::MacroTable(pool, parent, parent_overlay) {{ |
| 479 | {self.foreach_col(ColumnSerializer.static_assert_flags)} |
| 480 | {self.foreach_col(ColumnSerializer.extend_nullable_vector)} |
| 481 | |
| 482 | {olay} |
| 483 | {self.foreach_col(ColumnSerializer.column_init)} |
| 484 | }} |
| 485 | ''' |
| 486 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 487 | def serialize(self) -> str: |
| 488 | return f''' |
| 489 | class {self.table_name} : public macros_internal::MacroTable {{ |
| 490 | public: |
| 491 | {self.id_defn().lstrip()} |
| 492 | struct ColumnIndex {{ |
| 493 | {self.foreach_col(ColumnSerializer.colindex)} |
| 494 | }}; |
| 495 | struct ColumnType {{ |
| 496 | {self.foreach_col(ColumnSerializer.coltype_enum)} |
| 497 | }}; |
| 498 | {self.row_struct().strip()} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 499 | struct ColumnFlag {{ |
| 500 | {self.foreach_col(ColumnSerializer.flag)} |
| 501 | }}; |
| 502 | |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 503 | class RowNumber; |
| 504 | class ConstRowReference; |
| 505 | class RowReference; |
| 506 | |
| 507 | class RowNumber : public macros_internal::AbstractRowNumber< |
| 508 | {self.table_name}, ConstRowReference, RowReference> {{ |
| 509 | public: |
| 510 | explicit RowNumber(uint32_t row_number) |
| 511 | : AbstractRowNumber(row_number) {{}} |
| 512 | }}; |
| 513 | static_assert(std::is_trivially_destructible<RowNumber>::value, |
| 514 | "Inheritance used without trivial destruction"); |
| 515 | |
| 516 | {self.const_row_reference_struct().strip()} |
| 517 | {self.row_reference_struct().strip()} |
| 518 | |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 519 | {self.const_iterator().strip()} |
| 520 | {self.iterator().strip()} |
| 521 | |
| 522 | struct IdAndRow {{ |
| 523 | Id id; |
| 524 | uint32_t row; |
| 525 | RowReference row_reference; |
| 526 | RowNumber row_number; |
| 527 | }}; |
| 528 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 529 | {self.constructor().strip()} |
| 530 | ~{self.table_name}() override; |
| 531 | |
| 532 | static const char* Name() {{ return "{self.table.sql_name}"; }} |
| 533 | |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 534 | static Table::Schema ComputeStaticSchema() {{ |
| 535 | Table::Schema schema; |
| 536 | schema.columns.emplace_back(Table::Schema::Column{{ |
| 537 | "id", SqlValue::Type::kLong, true, true, false, false}}); |
| 538 | schema.columns.emplace_back(Table::Schema::Column{{ |
| 539 | "type", SqlValue::Type::kString, false, false, false, false}}); |
| 540 | {self.foreach_col(ColumnSerializer.static_schema)} |
| 541 | return schema; |
| 542 | }} |
| 543 | |
| 544 | ConstIterator IterateRows() const {{ |
| 545 | return ConstIterator(this, CopyOverlays()); |
| 546 | }} |
| 547 | |
| 548 | Iterator IterateRows() {{ return Iterator(this, CopyOverlays()); }} |
| 549 | |
| 550 | ConstIterator FilterToIterator( |
| 551 | const std::vector<Constraint>& cs, |
| 552 | RowMap::OptimizeFor opt = RowMap::OptimizeFor::kMemory) const {{ |
| 553 | return ConstIterator(this, FilterAndApplyToOverlays(cs, opt)); |
| 554 | }} |
| 555 | |
| 556 | Iterator FilterToIterator( |
| 557 | const std::vector<Constraint>& cs, |
| 558 | RowMap::OptimizeFor opt = RowMap::OptimizeFor::kMemory) {{ |
| 559 | return Iterator(this, FilterAndApplyToOverlays(cs, opt)); |
| 560 | }} |
| 561 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 562 | void ShrinkToFit() {{ |
| 563 | {self.foreach_col(ColumnSerializer.shrink_to_fit)} |
| 564 | }} |
| 565 | |
Lalit Maganti | 4e2303c | 2023-03-29 15:28:36 +0100 | [diff] [blame] | 566 | std::optional<ConstRowReference> FindById(Id find_id) const {{ |
| 567 | std::optional<uint32_t> row = id().IndexOf(find_id); |
| 568 | return row ? std::make_optional(ConstRowReference(this, *row)) |
| 569 | : std::nullopt; |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 570 | }} |
| 571 | |
Lalit Maganti | 4e2303c | 2023-03-29 15:28:36 +0100 | [diff] [blame] | 572 | std::optional<RowReference> FindById(Id find_id) {{ |
| 573 | std::optional<uint32_t> row = id().IndexOf(find_id); |
| 574 | return row ? std::make_optional(RowReference(this, *row)) : std::nullopt; |
Lalit Maganti | e2a7456 | 2023-03-16 18:07:25 +0000 | [diff] [blame] | 575 | }} |
| 576 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 577 | IdAndRow Insert(const Row& row) {{ |
| 578 | uint32_t row_number = row_count(); |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 579 | {self.insert_common().strip()} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 580 | {self.foreach_col(ColumnSerializer.append)} |
| 581 | UpdateSelfOverlayAfterInsert(); |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 582 | return IdAndRow{{std::move(id), row_number, RowReference(this, row_number), |
| 583 | RowNumber(row_number)}}; |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 584 | }} |
| 585 | |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 586 | {self.extend().strip()} |
| 587 | |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 588 | {self.foreach_col(ColumnSerializer.accessor)} |
| 589 | |
| 590 | {self.foreach_col(ColumnSerializer.mutable_accessor)} |
| 591 | |
| 592 | private: |
Lalit Maganti | 3df8a7e | 2023-04-25 14:18:17 +0100 | [diff] [blame] | 593 | {self.extend_constructor().strip()} |
Lalit Maganti | 157d710 | 2023-03-17 20:07:41 +0000 | [diff] [blame] | 594 | {self.parent_field().strip()} |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 595 | {self.foreach_col(ColumnSerializer.storage)} |
| 596 | }}; |
| 597 | '''.strip('\n') |
| 598 | |
| 599 | |
Lalit Maganti | 746fc2b | 2023-03-24 13:21:24 +0000 | [diff] [blame] | 600 | def serialize_header(ifdef_guard: str, tables: List[ParsedTable], |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 601 | include_paths: List[str]) -> str: |
| 602 | """Serializes a table header file containing the given set of tables.""" |
| 603 | include_paths_str = '\n'.join([f'#include "{i}"' for i in include_paths]) |
| 604 | tables_str = '\n\n'.join([TableSerializer(t).serialize() for t in tables]) |
| 605 | return f''' |
| 606 | #ifndef {ifdef_guard} |
| 607 | #define {ifdef_guard} |
| 608 | |
Lalit Maganti | 9de9949 | 2023-04-25 15:31:05 +0100 | [diff] [blame] | 609 | #include "src/trace_processor/tables/macros_internal.h" |
Lalit Maganti | 16117cc | 2022-12-21 15:33:21 +0000 | [diff] [blame] | 610 | |
| 611 | {include_paths_str} |
| 612 | |
| 613 | namespace perfetto {{ |
| 614 | namespace trace_processor {{ |
| 615 | namespace tables {{ |
| 616 | |
| 617 | {tables_str.strip()} |
| 618 | |
| 619 | }} // namespace tables |
| 620 | }} // namespace trace_processor |
| 621 | }} // namespace perfetto |
| 622 | |
| 623 | #endif // {ifdef_guard} |
| 624 | '''.strip() |
Lalit Maganti | e1d4d44 | 2023-03-23 21:43:33 +0000 | [diff] [blame] | 625 | |
| 626 | |
| 627 | def to_cpp_flags(raw_flag: ColumnFlag) -> str: |
| 628 | """Converts a ColumnFlag to the C++ flags which it represents |
| 629 | |
| 630 | It is not valid to call this function with ColumnFlag.NONE as in this case |
| 631 | defaults for that column should be implicitly used.""" |
| 632 | |
| 633 | assert raw_flag != ColumnFlag.NONE |
| 634 | flags = [] |
| 635 | if ColumnFlag.SORTED in raw_flag: |
| 636 | flags.append('Column::Flag::kSorted') |
| 637 | if ColumnFlag.HIDDEN in raw_flag: |
| 638 | flags.append('Column::Flag::kHidden') |
| 639 | if ColumnFlag.DENSE in raw_flag: |
| 640 | flags.append('Column::Flag::kDense') |
| 641 | if ColumnFlag.SET_ID in raw_flag: |
| 642 | flags.append('Column::Flag::kSetId') |
| 643 | return ' | '.join(flags) |