1 /*
2 * Copyright (C) 2019 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/counter_definitions_table.h"
18
19 #include <string>
20
21 #include "src/trace_processor/storage_columns.h"
22
23 namespace perfetto {
24 namespace trace_processor {
25
CounterDefinitionsTable(sqlite3 *,const TraceStorage * storage)26 CounterDefinitionsTable::CounterDefinitionsTable(sqlite3*,
27 const TraceStorage* storage)
28 : storage_(storage) {}
29
RegisterTable(sqlite3 * db,const TraceStorage * storage)30 void CounterDefinitionsTable::RegisterTable(sqlite3* db,
31 const TraceStorage* storage) {
32 Table::Register<CounterDefinitionsTable>(db, storage, "counter_definitions");
33 }
34
CreateStorageSchema()35 StorageSchema CounterDefinitionsTable::CreateStorageSchema() {
36 const auto& cs = storage_->counter_definitions();
37 return StorageSchema::Builder()
38 .AddGenericNumericColumn("counter_id", RowAccessor())
39 .AddStringColumn("name", &cs.name_ids(), &storage_->string_pool())
40 .AddNumericColumn("ref", &cs.refs())
41 .AddStringColumn("ref_type", &cs.types(), &GetRefTypeStringMap())
42 .Build({"counter_id"});
43 }
44
RowCount()45 uint32_t CounterDefinitionsTable::RowCount() {
46 return storage_->counter_definitions().size();
47 }
48
BestIndex(const QueryConstraints & qc,BestIndexInfo * info)49 int CounterDefinitionsTable::BestIndex(const QueryConstraints& qc,
50 BestIndexInfo* info) {
51 info->estimated_cost = EstimateCost(qc);
52
53 // Only the string columns are handled by SQLite
54 size_t name_index = schema().ColumnIndexFromName("name");
55 size_t ref_type_index = schema().ColumnIndexFromName("ref_type");
56 info->order_by_consumed = true;
57 for (size_t i = 0; i < qc.constraints().size(); i++) {
58 auto col = static_cast<size_t>(qc.constraints()[i].iColumn);
59 info->omit[i] = col != name_index && col != ref_type_index;
60 }
61
62 return SQLITE_OK;
63 }
64
EstimateCost(const QueryConstraints & qc)65 uint32_t CounterDefinitionsTable::EstimateCost(const QueryConstraints& qc) {
66 // If there is a constraint on the counter id, we can efficiently filter
67 // to a single row.
68 if (HasEqConstraint(qc, "counter_id"))
69 return 1;
70
71 auto eq_name = HasEqConstraint(qc, "name");
72 auto eq_ref = HasEqConstraint(qc, "ref");
73 auto eq_ref_type = HasEqConstraint(qc, "ref_type");
74
75 // If there is a constraint on all three columns, we are going to only return
76 // exaclty one row for sure so make the cost 1.
77 if (eq_name && eq_ref && eq_ref_type)
78 return 1;
79 else if (eq_name && eq_ref)
80 return 10;
81 else if (eq_name)
82 return 100;
83 return RowCount();
84 }
85
86 } // namespace trace_processor
87 } // namespace perfetto
88