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
22 namespace perfetto {
23 namespace trace_processor {
24
25 namespace {
26
GetDescribeSliceInputValues(const std::vector<Constraint> & cs)27 DescribeSliceGenerator::InputValues GetDescribeSliceInputValues(
28 const std::vector<Constraint>& cs) {
29 using DST = tables::DescribeSliceTable;
30
31 auto slice_id_fn = [](const Constraint& c) {
32 return c.col_idx == static_cast<uint32_t>(DST::ColumnIndex::slice_id) &&
33 c.op == FilterOp::kEq;
34 };
35 auto slice_id_it = std::find_if(cs.begin(), cs.end(), slice_id_fn);
36
37 // We should always have valid iterators here because BestIndex should only
38 // allow the constraint set to be chosen when we have an equality constraint
39 // on both ts and upid.
40 PERFETTO_CHECK(slice_id_it != cs.end());
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 util::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 ? util::OkStatus()
68 : util::ErrStatus("Failed to find required constraints");
69 }
70
ComputeTable(const std::vector<Constraint> & cs,const std::vector<Order> &)71 std::unique_ptr<Table> DescribeSliceGenerator::ComputeTable(
72 const std::vector<Constraint>& cs,
73 const std::vector<Order>&) {
74 auto input = GetDescribeSliceInputValues(cs);
75 const auto& slices = context_->storage->slice_table();
76
77 base::Optional<SliceDescription> opt_desc;
78 auto status = DescribeSlice(slices, SliceId{input.slice_id_value}, &opt_desc);
79 if (!status.ok())
80 return nullptr;
81
82 auto* pool = context_->storage->mutable_string_pool();
83 std::unique_ptr<tables::DescribeSliceTable> table(
84 new tables::DescribeSliceTable(pool, nullptr));
85
86 if (opt_desc) {
87 tables::DescribeSliceTable::Row row;
88 row.description = context_->storage->InternString(
89 base::StringView(opt_desc->description));
90 row.doc_link =
91 context_->storage->InternString(base::StringView(opt_desc->doc_link));
92 row.slice_id = input.slice_id_value;
93 table->Insert(row);
94 }
95 // We need to explicitly std::move as clang complains about a bug in old
96 // compilers otherwise (-Wreturn-std-move-in-c++11).
97 return std::move(table);
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