• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "symbols_table.h"
17 #include "trace_data_cache.h"
18 
19 namespace SysTuning {
20 namespace TraceStreamer {
21 enum Index { ID = 0, STR, ADDR };
SymbolsTable(const TraceDataCache * dataCache)22 SymbolsTable::SymbolsTable(const TraceDataCache* dataCache) : TableBase(dataCache)
23 {
24     tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
25     tableColumn_.push_back(TableBase::ColumnInfo("funcname", "TEXT"));
26     tableColumn_.push_back(TableBase::ColumnInfo("addr", "INTEGER"));
27     tablePriKey_.push_back("id");
28 }
29 
~SymbolsTable()30 SymbolsTable::~SymbolsTable() {}
31 
EstimateFilterCost(FilterConstraints & fc,EstimatedIndexInfo & ei)32 void SymbolsTable::EstimateFilterCost(FilterConstraints& fc, EstimatedIndexInfo& ei)
33 {
34     constexpr double filterBaseCost = 1000.0; // set-up and tear-down
35     constexpr double indexCost = 2.0;
36     ei.estimatedCost = filterBaseCost;
37 
38     size_t rowCount = dataCache_->GetConstSymbolsData().Size();
39     if (rowCount == 0 || rowCount == 1) {
40         ei.estimatedRows = rowCount;
41         ei.estimatedCost += indexCost * rowCount;
42         return;
43     }
44 
45     double filterCost = 0.0;
46     auto constraints = fc.GetConstraints();
47     if (constraints.empty()) { // scan all rows
48         filterCost = rowCount;
49     } else {
50         FilterByConstraint(fc, filterCost, rowCount);
51     }
52     ei.estimatedCost += filterCost;
53     ei.estimatedRows = rowCount;
54     ei.estimatedCost += rowCount * indexCost;
55 
56     ei.isOrdered = true;
57     auto orderbys = fc.GetOrderBys();
58     for (auto i = 0; i < orderbys.size(); i++) {
59         switch (orderbys[i].iColumn) {
60             case ID:
61                 break;
62             default: // other columns can be sorted by SQLite
63                 ei.isOrdered = false;
64                 break;
65         }
66     }
67 }
68 
FilterByConstraint(FilterConstraints & fc,double & filterCost,size_t rowCount)69 void SymbolsTable::FilterByConstraint(FilterConstraints& fc, double& filterCost, size_t rowCount)
70 {
71     auto fcConstraints = fc.GetConstraints();
72     for (int32_t i = 0; i < static_cast<int32_t>(fcConstraints.size()); i++) {
73         if (rowCount <= 1) {
74             // only one row or nothing, needn't filter by constraint
75             filterCost += rowCount;
76             break;
77         }
78         const auto& c = fcConstraints[i];
79         switch (c.col) {
80             case ID: {
81                 if (CanFilterId(c.op, rowCount)) {
82                     fc.UpdateConstraint(i, true);
83                     filterCost += 1; // id can position by 1 step
84                 } else {
85                     filterCost += rowCount; // scan all rows
86                 }
87                 break;
88             }
89             default:                    // other column
90                 filterCost += rowCount; // scan all rows
91                 break;
92         }
93     }
94 }
95 
CreateCursor()96 std::unique_ptr<TableBase::Cursor> SymbolsTable::CreateCursor()
97 {
98     return std::make_unique<Cursor>(dataCache_, this);
99 }
100 
Cursor(const TraceDataCache * dataCache,TableBase * table)101 SymbolsTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
102     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstSymbolsData().Size()))
103 {
104 }
105 
~Cursor()106 SymbolsTable::Cursor::~Cursor() {}
107 
Filter(const FilterConstraints & fc,sqlite3_value ** argv)108 int32_t SymbolsTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
109 {
110     // reset indexMap_
111     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
112 
113     if (rowCount_ <= 0) {
114         return SQLITE_OK;
115     }
116 
117     auto& cs = fc.GetConstraints();
118     for (size_t i = 0; i < cs.size(); i++) {
119         const auto& c = cs[i];
120         switch (c.col) {
121             case ID:
122                 FilterId(c.op, argv[i]);
123                 break;
124             default:
125                 break;
126         }
127     }
128 
129     auto orderbys = fc.GetOrderBys();
130     for (auto i = orderbys.size(); i > 0;) {
131         i--;
132         switch (orderbys[i].iColumn) {
133             case ID:
134                 indexMap_->SortBy(orderbys[i].desc);
135                 break;
136             default:
137                 break;
138         }
139     }
140 
141     return SQLITE_OK;
142 }
143 
Column(int32_t col) const144 int32_t SymbolsTable::Cursor::Column(int32_t col) const
145 {
146     DataIndex index = static_cast<DataIndex>(CurrentRow());
147     switch (col) {
148         case ID:
149             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(CurrentRow()));
150             break;
151         case STR:
152             sqlite3_result_text(
153                 context_,
154                 dataCache_->GetDataFromDict(dataCache_->GetConstSymbolsData().GetConstFuncNames()[index]).c_str(),
155                 STR_DEFAULT_LEN, nullptr);
156             break;
157         case ADDR:
158             sqlite3_result_int64(context_,
159                                  static_cast<sqlite3_int64>(dataCache_->GetConstSymbolsData().GetConstAddrs()[index]));
160             break;
161         default:
162             TS_LOGF("Unknown column %d", col);
163             break;
164     }
165     return SQLITE_OK;
166 }
167 } // namespace TraceStreamer
168 } // namespace SysTuning
169