• 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 "bio_latency_sample_table.h"
17 
18 namespace SysTuning {
19 namespace TraceStreamer {
20 namespace {
21 enum Index {
22     ID = 0,
23     CALLCHAIN_ID,
24     TYPE,
25     IPID,
26     ITID,
27     START_TS,
28     END_TS,
29     LATENCY_DUR,
30     TIER,
31     SIZE,
32     BLOCK_NUMBER,
33     PATH,
34     DUR_PER_4K,
35 };
36 }
BioLatencySampleTable(const TraceDataCache * dataCache)37 BioLatencySampleTable::BioLatencySampleTable(const TraceDataCache* dataCache) : TableBase(dataCache)
38 {
39     tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
40     tableColumn_.push_back(TableBase::ColumnInfo("callchain_id", "INTEGER"));
41     tableColumn_.push_back(TableBase::ColumnInfo("type", "INTEGER"));
42     tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
43     tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
44     tableColumn_.push_back(TableBase::ColumnInfo("start_ts", "INTEGER"));
45     tableColumn_.push_back(TableBase::ColumnInfo("end_ts", "INTEGER"));
46     tableColumn_.push_back(TableBase::ColumnInfo("latency_dur", "INTEGER"));
47     tableColumn_.push_back(TableBase::ColumnInfo("tier", "INTEGER"));
48     tableColumn_.push_back(TableBase::ColumnInfo("size", "INTEGER"));
49     tableColumn_.push_back(TableBase::ColumnInfo("block_number", "TEXT"));
50     tableColumn_.push_back(TableBase::ColumnInfo("path_id", "TEXT"));
51     tableColumn_.push_back(TableBase::ColumnInfo("dur_per_4k", "INTEGER"));
52     tablePriKey_.push_back("id");
53 }
54 
~BioLatencySampleTable()55 BioLatencySampleTable::~BioLatencySampleTable() {}
56 
EstimateFilterCost(FilterConstraints & fc,EstimatedIndexInfo & ei)57 void BioLatencySampleTable::EstimateFilterCost(FilterConstraints& fc, EstimatedIndexInfo& ei)
58 {
59     constexpr double filterBaseCost = 1000.0; // set-up and tear-down
60     constexpr double indexCost = 2.0;
61     ei.estimatedCost = filterBaseCost;
62 
63     auto rowCount = dataCache_->GetConstHidumpData().Size();
64     if (rowCount == 0 || rowCount == 1) {
65         ei.estimatedRows = rowCount;
66         ei.estimatedCost += indexCost * rowCount;
67         return;
68     }
69 
70     double filterCost = 0.0;
71     auto constraints = fc.GetConstraints();
72     if (constraints.empty()) { // scan all rows
73         filterCost = rowCount;
74     } else {
75         FilterByConstraint(fc, filterCost, rowCount);
76     }
77     ei.estimatedCost += filterCost;
78     ei.estimatedRows = rowCount;
79     ei.estimatedCost += rowCount * indexCost;
80 
81     ei.isOrdered = true;
82     auto orderbys = fc.GetOrderBys();
83     for (auto i = 0; i < orderbys.size(); i++) {
84         switch (orderbys[i].iColumn) {
85             case ID:
86                 break;
87             default: // other columns can be sorted by SQLite
88                 ei.isOrdered = false;
89                 break;
90         }
91     }
92 }
93 
FilterByConstraint(FilterConstraints & fc,double & filterCost,size_t rowCount)94 void BioLatencySampleTable::FilterByConstraint(FilterConstraints& fc, double& filterCost, size_t rowCount)
95 {
96     auto fcConstraints = fc.GetConstraints();
97     for (int i = 0; i < static_cast<int>(fcConstraints.size()); i++) {
98         if (rowCount <= 1) {
99             // only one row or nothing, needn't filter by constraint
100             filterCost += rowCount;
101             break;
102         }
103         const auto& c = fcConstraints[i];
104         switch (c.col) {
105             case ID: {
106                 if (CanFilterId(c.op, rowCount)) {
107                     fc.UpdateConstraint(i, true);
108                     filterCost += 1; // id can position by 1 step
109                 } else {
110                     filterCost += rowCount; // scan all rows
111                 }
112                 break;
113             }
114             default:                    // other column
115                 filterCost += rowCount; // scan all rows
116                 break;
117         }
118     }
119 }
120 
CanFilterId(const char op,size_t & rowCount)121 bool BioLatencySampleTable::CanFilterId(const char op, size_t& rowCount)
122 {
123     switch (op) {
124         case SQLITE_INDEX_CONSTRAINT_EQ:
125             rowCount = 1;
126             break;
127         case SQLITE_INDEX_CONSTRAINT_GT:
128         case SQLITE_INDEX_CONSTRAINT_GE:
129         case SQLITE_INDEX_CONSTRAINT_LE:
130         case SQLITE_INDEX_CONSTRAINT_LT:
131             // assume filter out a half of rows
132             rowCount = (rowCount >> 1);
133             break;
134         default:
135             return false;
136     }
137     return true;
138 }
139 
CreateCursor()140 std::unique_ptr<TableBase::Cursor> BioLatencySampleTable::CreateCursor()
141 {
142     return std::make_unique<Cursor>(dataCache_, this);
143 }
144 
Cursor(const TraceDataCache * dataCache,TableBase * table)145 BioLatencySampleTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
146     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstBioLatencySampleData().Size())),
147       bioLatencySampleObj_(dataCache->GetConstBioLatencySampleData())
148 {
149 }
150 
~Cursor()151 BioLatencySampleTable::Cursor::~Cursor() {}
152 
Filter(const FilterConstraints & fc,sqlite3_value ** argv)153 int BioLatencySampleTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
154 {
155     // reset indexMap_
156     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
157 
158     if (rowCount_ <= 0) {
159         return SQLITE_OK;
160     }
161 
162     auto& cs = fc.GetConstraints();
163     for (size_t i = 0; i < cs.size(); i++) {
164         const auto& c = cs[i];
165         switch (c.col) {
166             case ID:
167                 FilterId(c.op, argv[i]);
168                 break;
169             default:
170                 break;
171         }
172     }
173 
174     auto orderbys = fc.GetOrderBys();
175     for (auto i = orderbys.size(); i > 0;) {
176         i--;
177         switch (orderbys[i].iColumn) {
178             case ID:
179                 indexMap_->SortBy(orderbys[i].desc);
180                 break;
181             default:
182                 break;
183         }
184     }
185 
186     return SQLITE_OK;
187 }
188 
Column(int column) const189 int BioLatencySampleTable::Cursor::Column(int column) const
190 {
191     switch (column) {
192         case ID:
193             sqlite3_result_int64(context_, static_cast<int32_t>(bioLatencySampleObj_.IdsData()[CurrentRow()]));
194             break;
195         case CALLCHAIN_ID:
196             sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.CallChainIds()[CurrentRow()]));
197             break;
198         case TYPE:
199             sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.Types()[CurrentRow()]));
200             break;
201         case IPID: {
202             if (bioLatencySampleObj_.Ipids()[CurrentRow()] != INVALID_UINT64) {
203                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.Ipids()[CurrentRow()]));
204             }
205             break;
206         }
207         case ITID: {
208             if (bioLatencySampleObj_.Itids()[CurrentRow()] != INVALID_UINT64) {
209                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.Itids()[CurrentRow()]));
210             }
211             break;
212         }
213         case START_TS: {
214             if (bioLatencySampleObj_.StartTs()[CurrentRow()] != INVALID_UINT64) {
215                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.StartTs()[CurrentRow()]));
216             }
217             break;
218         }
219         case END_TS: {
220             if (bioLatencySampleObj_.EndTs()[CurrentRow()] != INVALID_UINT64) {
221                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.EndTs()[CurrentRow()]));
222             }
223             break;
224         }
225         case LATENCY_DUR: {
226             if (bioLatencySampleObj_.LatencyDurs()[CurrentRow()] != INVALID_UINT64) {
227                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.LatencyDurs()[CurrentRow()]));
228             }
229             break;
230         }
231         case TIER: {
232             if (bioLatencySampleObj_.Tiers()[CurrentRow()] != INVALID_UINT32) {
233                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.Tiers()[CurrentRow()]));
234             }
235             break;
236         }
237         case SIZE: {
238             if (bioLatencySampleObj_.Sizes()[CurrentRow()] != INVALID_UINT64) {
239                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.Sizes()[CurrentRow()]));
240             }
241             break;
242         }
243         case BLOCK_NUMBER: {
244             if (bioLatencySampleObj_.BlockNumbers()[CurrentRow()] != INVALID_UINT64) {
245                 auto returnValueIndex0 = bioLatencySampleObj_.BlockNumbers()[CurrentRow()];
246                 sqlite3_result_text(context_, dataCache_->GetDataFromDict(returnValueIndex0).c_str(), STR_DEFAULT_LEN,
247                                     nullptr);
248             }
249             break;
250         }
251         case PATH: {
252             if (bioLatencySampleObj_.FilePathIds()[CurrentRow()] != INVALID_UINT64) {
253                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.FilePathIds()[CurrentRow()]));
254             }
255             break;
256         }
257         case DUR_PER_4K: {
258             if (bioLatencySampleObj_.DurPer4k()[CurrentRow()] != INVALID_UINT64) {
259                 sqlite3_result_int64(context_, static_cast<int64_t>(bioLatencySampleObj_.DurPer4k()[CurrentRow()]));
260             }
261             break;
262         }
263         default:
264             TS_LOGF("Unregistered column : %d", column);
265             break;
266     }
267     return SQLITE_OK;
268 }
269 } // namespace TraceStreamer
270 } // namespace SysTuning
271