• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
18 #define SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
19 
20 #include "perfetto/base/status.h"
21 #include "src/trace_processor/containers/bit_vector.h"
22 #include "src/trace_processor/db/table.h"
23 #include "src/trace_processor/prelude/table_functions/table_function.h"
24 #include "src/trace_processor/sqlite/query_cache.h"
25 #include "src/trace_processor/sqlite/sqlite_table.h"
26 
27 namespace perfetto {
28 namespace trace_processor {
29 
30 enum class DbSqliteTableComputation {
31   // Mode when the table is static (i.e. passed in at construction
32   // time).
33   kStatic,
34 
35   // Mode when table is dynamically computed at filter time.
36   kDynamic,
37 };
38 
39 struct DbSqliteTableContext {
40   QueryCache* cache;
41   DbSqliteTableComputation computation;
42 
43   // Only valid when computation == TableComputation::kStatic.
44   const Table* static_table;
45 
46   // Only valid when computation == TableComputation::kDynamic.
47   std::unique_ptr<TableFunction> generator;
48 };
49 
50 // Implements the SQLite table interface for db tables.
51 class DbSqliteTable final
52     : public TypedSqliteTable<DbSqliteTable, DbSqliteTableContext> {
53  public:
54   using TableComputation = DbSqliteTableComputation;
55   using Context = DbSqliteTableContext;
56 
57   class Cursor final : public SqliteTable::BaseCursor {
58    public:
59     Cursor(DbSqliteTable*, QueryCache*);
60     ~Cursor() final;
61 
62     Cursor(Cursor&&) noexcept = default;
63     Cursor& operator=(Cursor&&) = default;
64 
65     // Implementation of SqliteTable::Cursor.
66     base::Status Filter(const QueryConstraints& qc,
67                         sqlite3_value** argv,
68                         FilterHistory);
69     base::Status Next();
70     bool Eof();
71     base::Status Column(sqlite3_context*, int N);
72 
73    private:
74     enum class Mode {
75       kSingleRow,
76       kTable,
77     };
78 
79     // Tries to create a sorted table to cache in |sorted_cache_table_| if the
80     // constraint set matches the requirements.
81     void TryCacheCreateSortedTable(const QueryConstraints&, FilterHistory);
82 
SourceTable()83     const Table* SourceTable() const {
84       // Try and use the sorted cache table (if it exists) to speed up the
85       // sorting. Otherwise, just use the original table.
86       return sorted_cache_table_ ? &*sorted_cache_table_ : upstream_table_;
87     }
88 
89     Cursor(const Cursor&) = delete;
90     Cursor& operator=(const Cursor&) = delete;
91 
92     DbSqliteTable* db_sqlite_table_ = nullptr;
93     QueryCache* cache_ = nullptr;
94 
95     const Table* upstream_table_ = nullptr;
96 
97     // Only valid for |db_sqlite_table_->computation_| ==
98     // TableComputation::kDynamic.
99     std::unique_ptr<Table> dynamic_table_;
100 
101     // Only valid for Mode::kSingleRow.
102     std::optional<uint32_t> single_row_;
103 
104     // Only valid for Mode::kTable.
105     std::optional<Table> db_table_;
106     std::optional<Table::Iterator> iterator_;
107 
108     bool eof_ = true;
109 
110     // Stores a sorted version of |db_table_| sorted on a repeated equals
111     // constraint. This allows speeding up repeated subqueries in joins
112     // significantly.
113     std::shared_ptr<Table> sorted_cache_table_;
114 
115     // Stores the count of repeated equality queries to decide whether it is
116     // wortwhile to sort |db_table_| to create |sorted_cache_table_|.
117     uint32_t repeated_cache_count_ = 0;
118 
119     Mode mode_ = Mode::kSingleRow;
120 
121     std::vector<Constraint> constraints_;
122     std::vector<Order> orders_;
123   };
124   struct QueryCost {
125     double cost;
126     uint32_t rows;
127   };
128 
129   DbSqliteTable(sqlite3*, Context context);
130   virtual ~DbSqliteTable() final;
131 
132   // Table implementation.
133   base::Status Init(int, const char* const*, SqliteTable::Schema*) final;
134   std::unique_ptr<SqliteTable::BaseCursor> CreateCursor() final;
135   base::Status ModifyConstraints(QueryConstraints*) final;
136   int BestIndex(const QueryConstraints&, BestIndexInfo*) final;
137 
138   // These static functions are useful to allow other callers to make use
139   // of them.
140   static SqliteTable::Schema ComputeSchema(const Table::Schema&,
141                                            const char* table_name);
142   static void ModifyConstraints(const Table::Schema&, QueryConstraints*);
143   static void BestIndex(const Table::Schema&,
144                         uint32_t row_count,
145                         const QueryConstraints&,
146                         BestIndexInfo*);
147 
148   // static for testing.
149   static QueryCost EstimateCost(const Table::Schema&,
150                                 uint32_t row_count,
151                                 const QueryConstraints& qc);
152 
153  private:
154   QueryCache* cache_ = nullptr;
155 
156   TableComputation computation_ = TableComputation::kStatic;
157 
158   // Only valid after Init has completed.
159   Table::Schema schema_;
160 
161   // Only valid when computation_ == TableComputation::kStatic.
162   const Table* static_table_ = nullptr;
163 
164   // Only valid when computation_ == TableComputation::kDynamic.
165   std::unique_ptr<TableFunction> generator_;
166 };
167 
168 }  // namespace trace_processor
169 }  // namespace perfetto
170 
171 #endif  // SRC_TRACE_PROCESSOR_SQLITE_DB_SQLITE_TABLE_H_
172