1 /*
2 * Copyright (C) 2020 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/dynamic/describe_slice_generator.h"
18
19 #include "src/trace_processor/analysis/describe_slice.h"
20 #include "src/trace_processor/types/trace_processor_context.h"
21 #include "src/trace_processor/util/status_macros.h"
22
23 namespace perfetto {
24 namespace trace_processor {
25
26 namespace {
27
GetDescribeSliceInputValues(const std::vector<Constraint> & cs)28 DescribeSliceGenerator::InputValues GetDescribeSliceInputValues(
29 const std::vector<Constraint>& cs) {
30 using DST = tables::DescribeSliceTable;
31
32 auto slice_id_fn = [](const Constraint& c) {
33 return c.col_idx == static_cast<uint32_t>(DST::ColumnIndex::slice_id) &&
34 c.op == FilterOp::kEq;
35 };
36 auto slice_id_it = std::find_if(cs.begin(), cs.end(), slice_id_fn);
37
38 PERFETTO_CHECK(slice_id_it != cs.end());
39 // TODO(rsavitski): consider checking type of the SqlValue, as erroneous
40 // queries that pass a null here (or otherwise unexpected type) will crash.
41
42 uint32_t slice_id_value = static_cast<uint32_t>(slice_id_it->value.AsLong());
43 return DescribeSliceGenerator::InputValues{slice_id_value};
44 }
45
46 } // namespace
47
DescribeSliceGenerator(TraceProcessorContext * context)48 DescribeSliceGenerator::DescribeSliceGenerator(TraceProcessorContext* context)
49 : context_(context) {}
50
51 DescribeSliceGenerator::~DescribeSliceGenerator() = default;
52
ValidateConstraints(const QueryConstraints & qc)53 base::Status DescribeSliceGenerator::ValidateConstraints(
54 const QueryConstraints& qc) {
55 using T = tables::DescribeSliceTable;
56
57 const auto& cs = qc.constraints();
58
59 auto slice_id_fn = [](const QueryConstraints::Constraint& c) {
60 return c.column == static_cast<int>(T::ColumnIndex::slice_id) &&
61 c.op == SQLITE_INDEX_CONSTRAINT_EQ;
62 };
63 bool has_slice_id_cs =
64 std::find_if(cs.begin(), cs.end(), slice_id_fn) != cs.end();
65
66 return has_slice_id_cs
67 ? base::OkStatus()
68 : base::ErrStatus("Failed to find required constraints");
69 }
70
ComputeTable(const std::vector<Constraint> & cs,const std::vector<Order> &,const BitVector &,std::unique_ptr<Table> & table_return)71 base::Status DescribeSliceGenerator::ComputeTable(
72 const std::vector<Constraint>& cs,
73 const std::vector<Order>&,
74 const BitVector&,
75 std::unique_ptr<Table>& table_return) {
76 auto input = GetDescribeSliceInputValues(cs);
77 const auto& slices = context_->storage->slice_table();
78
79 base::Optional<SliceDescription> opt_desc;
80 RETURN_IF_ERROR(
81 DescribeSlice(slices, SliceId{input.slice_id_value}, &opt_desc));
82
83 auto* pool = context_->storage->mutable_string_pool();
84 std::unique_ptr<tables::DescribeSliceTable> table(
85 new tables::DescribeSliceTable(pool, nullptr));
86
87 if (opt_desc) {
88 tables::DescribeSliceTable::Row row;
89 row.description = context_->storage->InternString(
90 base::StringView(opt_desc->description));
91 row.doc_link =
92 context_->storage->InternString(base::StringView(opt_desc->doc_link));
93 row.slice_id = input.slice_id_value;
94 table->Insert(row);
95 }
96 table_return = std::move(table);
97 return base::OkStatus();
98 }
99
CreateSchema()100 Table::Schema DescribeSliceGenerator::CreateSchema() {
101 return tables::DescribeSliceTable::Schema();
102 }
103
TableName()104 std::string DescribeSliceGenerator::TableName() {
105 return "describe_slice";
106 }
107
EstimateRowCount()108 uint32_t DescribeSliceGenerator::EstimateRowCount() {
109 return 1;
110 }
111
112 } // namespace trace_processor
113 } // namespace perfetto
114