• 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 "sched_slice_table.h"
17 
18 #include <cmath>
19 
20 namespace SysTuning {
21 namespace TraceStreamer {
22 enum class Index : int32_t {
23     ID = 0,
24     TYPE,
25     TS,
26     DUR,
27     TS_END,
28     CPU,
29     INTERNAL_TID,
30     INTERNAL_PID,
31     END_STATE,
32     PRIORITY,
33     ARGSETID
34 };
SchedSliceTable(const TraceDataCache * dataCache)35 SchedSliceTable::SchedSliceTable(const TraceDataCache* dataCache) : TableBase(dataCache)
36 {
37     tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
38     tableColumn_.push_back(TableBase::ColumnInfo("type", "TEXT"));
39     tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
40     tableColumn_.push_back(TableBase::ColumnInfo("dur", "INTEGER"));
41     tableColumn_.push_back(TableBase::ColumnInfo("ts_end", "INTEGER"));
42     tableColumn_.push_back(TableBase::ColumnInfo("cpu", "INTEGER"));
43     tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
44     tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
45     tableColumn_.push_back(TableBase::ColumnInfo("end_state", "TEXT"));
46     tableColumn_.push_back(TableBase::ColumnInfo("priority", "INTEGER"));
47     tableColumn_.push_back(TableBase::ColumnInfo("arg_setid", "INTEGER"));
48     tablePriKey_.push_back("id");
49 }
50 
~SchedSliceTable()51 SchedSliceTable::~SchedSliceTable() {}
52 
FilterByConstraint(FilterConstraints & schedfc,double & schedfilterCost,size_t schedrowCount,uint32_t schedcurrenti)53 void SchedSliceTable::FilterByConstraint(FilterConstraints& schedfc,
54                                          double& schedfilterCost,
55                                          size_t schedrowCount,
56                                          uint32_t schedcurrenti)
57 {
58     // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
59     // for loop
60     const auto& schedc = schedfc.GetConstraints()[schedcurrenti];
61     switch (static_cast<Index>(schedc.col)) {
62         case Index::ID: {
63             if (CanFilterId(schedc.op, schedrowCount)) {
64                 schedfc.UpdateConstraint(schedcurrenti, true);
65                 schedfilterCost += 1; // id can position by 1 step
66             } else {
67                 schedfilterCost += schedrowCount; // scan all rows
68             }
69             break;
70         }
71         case Index::TS: {
72             auto schedoldRowCount = schedrowCount;
73             if (CanFilterSorted(schedc.op, schedrowCount)) {
74                 schedfc.UpdateConstraint(schedcurrenti, true);
75                 schedfilterCost += log2(schedoldRowCount); // binary search
76             } else {
77                 schedfilterCost += schedoldRowCount;
78             }
79             break;
80         }
81         default:                              // other column
82             schedfilterCost += schedrowCount; // scan all rows
83             break;
84     }
85 }
86 
CanFilterSorted(const char op,size_t & schedRowCnt) const87 bool SchedSliceTable::CanFilterSorted(const char op, size_t& schedRowCnt) const
88 {
89     switch (op) {
90         case SQLITE_INDEX_CONSTRAINT_EQ:
91             schedRowCnt = schedRowCnt / log2(schedRowCnt);
92             break;
93         case SQLITE_INDEX_CONSTRAINT_GT:
94         case SQLITE_INDEX_CONSTRAINT_GE:
95         case SQLITE_INDEX_CONSTRAINT_LE:
96         case SQLITE_INDEX_CONSTRAINT_LT:
97             schedRowCnt = (schedRowCnt >> 1);
98             break;
99         default:
100             return false;
101     }
102     return true;
103 }
104 
CreateCursor()105 std::unique_ptr<TableBase::Cursor> SchedSliceTable::CreateCursor()
106 {
107     return std::make_unique<Cursor>(dataCache_, this);
108 }
109 
Cursor(const TraceDataCache * dataCache,TableBase * table)110 SchedSliceTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
111     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstSchedSliceData().Size())),
112       schedSliceObj_(dataCache->GetConstSchedSliceData())
113 {
114 }
115 
~Cursor()116 SchedSliceTable::Cursor::~Cursor() {}
117 
Filter(const FilterConstraints & fc,sqlite3_value ** argv)118 int32_t SchedSliceTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
119 {
120     // reset indexMap_
121     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
122 
123     if (rowCount_ <= 0) {
124         return SQLITE_OK;
125     }
126 
127     auto schedSliceTabCs = fc.GetConstraints();
128     std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
129     SwapIndexFront(schedSliceTabCs, sId);
130     for (size_t i = 0; i < schedSliceTabCs.size(); i++) {
131         const auto& c = schedSliceTabCs[i];
132         switch (static_cast<Index>(c.col)) {
133             case Index::ID:
134                 FilterId(c.op, argv[i]);
135                 break;
136             case Index::TS:
137                 FilterTS(c.op, argv[i], schedSliceObj_.TimeStampData());
138                 break;
139             case Index::CPU:
140                 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])), schedSliceObj_.CpusData());
141                 break;
142             case Index::INTERNAL_TID:
143                 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
144                                     schedSliceObj_.InternalTidsData());
145                 break;
146             case Index::INTERNAL_PID:
147                 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
148                                     schedSliceObj_.InternalPidsData());
149                 break;
150             case Index::DUR:
151                 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int64(argv[i])),
152                                     schedSliceObj_.DursData());
153                 break;
154             default:
155                 break;
156         }
157     }
158 
159     auto schedSliceOrderbys = fc.GetOrderBys();
160     for (auto i = schedSliceOrderbys.size(); i > 0;) {
161         i--;
162         switch (static_cast<Index>(schedSliceOrderbys[i].iColumn)) {
163             case Index::ID:
164             case Index::TS:
165                 indexMap_->SortBy(schedSliceOrderbys[i].desc);
166                 break;
167             default:
168                 break;
169         }
170     }
171 
172     return SQLITE_OK;
173 }
174 
Column(int32_t col) const175 int32_t SchedSliceTable::Cursor::Column(int32_t col) const
176 {
177     switch (static_cast<Index>(col)) {
178         case Index::ID:
179             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(CurrentRow()));
180             break;
181         case Index::TYPE:
182             sqlite3_result_text(context_, "sched_slice", STR_DEFAULT_LEN, nullptr);
183             break;
184         case Index::TS:
185             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.TimeStampData()[CurrentRow()]));
186             break;
187         case Index::DUR:
188             SetTypeColumnInt64(schedSliceObj_.DursData()[CurrentRow()], INVALID_UINT64);
189             break;
190         case Index::TS_END:
191             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.TsEndData()[CurrentRow()]));
192             break;
193         case Index::CPU:
194             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.CpusData()[CurrentRow()]));
195             break;
196         case Index::INTERNAL_TID:
197             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.InternalTidsData()[CurrentRow()]));
198             break;
199         case Index::INTERNAL_PID:
200             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.InternalPidsData()[CurrentRow()]));
201             break;
202         case Index::END_STATE: {
203             const std::string& str = dataCache_->GetConstSchedStateData(schedSliceObj_.EndStatesData()[CurrentRow()]);
204             sqlite3_result_text(context_, str.c_str(), STR_DEFAULT_LEN, nullptr);
205             break;
206         }
207         case Index::PRIORITY:
208             sqlite3_result_int64(context_, static_cast<sqlite3_int64>(schedSliceObj_.PriorityData()[CurrentRow()]));
209             break;
210         case Index::ARGSETID: {
211             const uint32_t& argSetId = schedSliceObj_.ArgSetData()[CurrentRow()];
212             if (argSetId != INVALID_UINT32) {
213                 sqlite3_result_int(context_, argSetId);
214             }
215             break;
216         }
217         default:
218             TS_LOGF("Unregistered column : %d", col);
219             break;
220     }
221     return SQLITE_OK;
222 }
223 
GetOrbyes(FilterConstraints & schedfc,EstimatedIndexInfo & schedei)224 void SchedSliceTable::GetOrbyes(FilterConstraints& schedfc, EstimatedIndexInfo& schedei)
225 {
226     auto schedorderbys = schedfc.GetOrderBys();
227     for (auto i = 0; i < schedorderbys.size(); i++) {
228         switch (static_cast<Index>(schedorderbys[i].iColumn)) {
229             case Index::ID:
230             case Index::TS:
231                 break;
232             default: // other columns can be sorted by SQLite
233                 schedei.isOrdered = false;
234                 break;
235         }
236     }
237 }
238 } // namespace TraceStreamer
239 } // namespace SysTuning
240