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