1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/tables/macros_internal.h"
18
19 #include <cstdint>
20 #include <initializer_list>
21 #include <type_traits>
22 #include <utility>
23 #include <vector>
24
25 #include "perfetto/base/logging.h"
26 #include "perfetto/public/compiler.h"
27 #include "perfetto/trace_processor/ref_counted.h"
28 #include "src/trace_processor/containers/bit_vector.h"
29 #include "src/trace_processor/containers/row_map.h"
30 #include "src/trace_processor/containers/string_pool.h"
31 #include "src/trace_processor/db/column.h"
32 #include "src/trace_processor/db/column/overlay_layer.h"
33 #include "src/trace_processor/db/column/selector_overlay.h"
34 #include "src/trace_processor/db/column/storage_layer.h"
35 #include "src/trace_processor/db/column_storage_overlay.h"
36
37 namespace perfetto::trace_processor::macros_internal {
38
MacroTable(StringPool * pool,std::vector<ColumnLegacy> columns,const MacroTable * parent)39 PERFETTO_NO_INLINE MacroTable::MacroTable(StringPool* pool,
40 std::vector<ColumnLegacy> columns,
41 const MacroTable* parent)
42 : Table(pool, 0u, std::move(columns), EmptyOverlaysFromParent(parent)),
43 allow_inserts_(true),
44 parent_(parent) {}
45
MacroTable(StringPool * pool,std::vector<ColumnLegacy> columns,const MacroTable & parent,const RowMap & parent_overlay)46 PERFETTO_NO_INLINE MacroTable::MacroTable(StringPool* pool,
47 std::vector<ColumnLegacy> columns,
48 const MacroTable& parent,
49 const RowMap& parent_overlay)
50 : Table(pool,
51 parent_overlay.size(),
52 std::move(columns),
53 SelectedOverlaysFromParent(parent, parent_overlay)),
54 allow_inserts_(false),
55 parent_(&parent) {}
56
UpdateOverlaysAfterParentInsert()57 PERFETTO_NO_INLINE void MacroTable::UpdateOverlaysAfterParentInsert() {
58 CopyLastInsertFrom(parent_->overlays());
59 }
60
UpdateSelfOverlayAfterInsert()61 PERFETTO_NO_INLINE void MacroTable::UpdateSelfOverlayAfterInsert() {
62 IncrementRowCountAndAddToLastOverlay();
63 }
64
65 PERFETTO_NO_INLINE std::vector<ColumnLegacy>
CopyColumnsFromParentOrAddRootColumns(MacroTable * self,const MacroTable * parent)66 MacroTable::CopyColumnsFromParentOrAddRootColumns(MacroTable* self,
67 const MacroTable* parent) {
68 std::vector<ColumnLegacy> columns;
69 if (parent) {
70 for (const ColumnLegacy& col : parent->columns()) {
71 columns.emplace_back(col, col.index_in_table(), col.overlay_index());
72 }
73 } else {
74 columns.emplace_back(ColumnLegacy::IdColumn(0, 0));
75 columns.emplace_back("type", &self->type_, ColumnLegacy::kNonNull, 1, 0);
76 }
77 return columns;
78 }
79
OnConstructionCompletedRegularConstructor(std::initializer_list<RefPtr<column::StorageLayer>> storage_layers,std::initializer_list<RefPtr<column::OverlayLayer>> null_layers)80 PERFETTO_NO_INLINE void MacroTable::OnConstructionCompletedRegularConstructor(
81 std::initializer_list<RefPtr<column::StorageLayer>> storage_layers,
82 std::initializer_list<RefPtr<column::OverlayLayer>> null_layers) {
83 std::vector<RefPtr<column::OverlayLayer>> overlay_layers(
84 OverlayCount(parent_) + 1);
85 for (uint32_t i = 0; i < overlay_layers.size() - 1; ++i) {
86 PERFETTO_CHECK(overlays()[i].row_map().IsBitVector());
87 overlay_layers[i].reset(
88 new column::SelectorOverlay(overlays()[i].row_map().GetIfBitVector()));
89 }
90 Table::OnConstructionCompleted(storage_layers, null_layers,
91 std::move(overlay_layers));
92 }
93
94 PERFETTO_NO_INLINE std::vector<ColumnStorageOverlay>
EmptyOverlaysFromParent(const MacroTable * parent)95 MacroTable::EmptyOverlaysFromParent(const MacroTable* parent) {
96 std::vector<ColumnStorageOverlay> overlays(parent ? parent->overlays().size()
97 : 0);
98 for (auto& overlay : overlays) {
99 overlay = ColumnStorageOverlay(BitVector());
100 }
101 overlays.emplace_back();
102 return overlays;
103 }
104
105 PERFETTO_NO_INLINE std::vector<ColumnStorageOverlay>
SelectedOverlaysFromParent(const macros_internal::MacroTable & parent,const RowMap & rm)106 MacroTable::SelectedOverlaysFromParent(
107 const macros_internal::MacroTable& parent,
108 const RowMap& rm) {
109 std::vector<ColumnStorageOverlay> overlays;
110 for (const auto& overlay : parent.overlays()) {
111 overlays.emplace_back(overlay.SelectRows(rm));
112 PERFETTO_DCHECK(overlays.back().size() == rm.size());
113 }
114 overlays.emplace_back(rm.size());
115 return overlays;
116 }
117
BaseConstIterator(const MacroTable * table,Table::Iterator iterator)118 BaseConstIterator::BaseConstIterator(const MacroTable* table,
119 Table::Iterator iterator)
120 : iterator_(std::move(iterator)), table_(table) {
121 static_assert(std::is_base_of<Table, MacroTable>::value,
122 "Template param should be a subclass of Table.");
123 }
124
operator bool() const125 BaseConstIterator::operator bool() const {
126 return bool(iterator_);
127 }
128
operator ++()129 BaseConstIterator& BaseConstIterator::operator++() {
130 ++iterator_;
131 return *this;
132 }
133
BaseRowReference(const MacroTable * table,uint32_t row_number)134 BaseRowReference::BaseRowReference(const MacroTable* table, uint32_t row_number)
135 : table_(table), row_number_(row_number) {}
136
137 } // namespace perfetto::trace_processor::macros_internal
138