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 "raw_table.h"
17 namespace SysTuning {
18 namespace TraceStreamer {
19 enum class Index : int32_t { ID = 0, TYPE, TS, NAME, CPU, INTERNAL_TID };
20 enum RawType { RAW_CPU_IDLE = 1, RAW_SCHED_WAKEUP = 2, RAW_SCHED_WAKING = 3 };
GetNameIndex(const std::string & name)21 uint32_t GetNameIndex(const std::string& name)
22 {
23 if (name == "cpu_idle") {
24 return RAW_CPU_IDLE;
25 } else if (name == "sched_wakeup") {
26 return RAW_SCHED_WAKEUP;
27 } else if (name == "sched_waking") {
28 return RAW_SCHED_WAKING;
29 } else {
30 return INVALID_UINT32;
31 }
32 }
RawTable(const TraceDataCache * dataCache)33 RawTable::RawTable(const TraceDataCache* dataCache) : TableBase(dataCache)
34 {
35 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
36 tableColumn_.push_back(TableBase::ColumnInfo("type", "TEXT"));
37 tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
38 tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT"));
39 tableColumn_.push_back(TableBase::ColumnInfo("cpu", "INTEGER"));
40 tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
41 tablePriKey_.push_back("id");
42 }
43
~RawTable()44 RawTable::~RawTable() {}
45
FilterByConstraint(FilterConstraints & rawfc,double & rawfilterCost,size_t rawrowCount,uint32_t rawcurrenti)46 void RawTable::FilterByConstraint(FilterConstraints& rawfc,
47 double& rawfilterCost,
48 size_t rawrowCount,
49 uint32_t rawcurrenti)
50 {
51 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
52 // for loop
53 const auto& rawc = rawfc.GetConstraints()[rawcurrenti];
54 switch (static_cast<Index>(rawc.col)) {
55 case Index::ID: {
56 if (CanFilterId(rawc.op, rawrowCount)) {
57 rawfc.UpdateConstraint(rawcurrenti, true);
58 rawfilterCost += 1; // id can position by 1 step
59 } else {
60 rawfilterCost += rawrowCount; // scan all rows
61 }
62 break;
63 }
64 default: // other column
65 rawfilterCost += rawrowCount; // scan all rows
66 break;
67 }
68 }
69
CreateCursor()70 std::unique_ptr<TableBase::Cursor> RawTable::CreateCursor()
71 {
72 return std::make_unique<Cursor>(dataCache_, this);
73 }
74
Cursor(const TraceDataCache * dataCache,TableBase * table)75 RawTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
76 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstRawTableData().Size())),
77 rawObj_(dataCache->GetConstRawTableData())
78 {
79 }
80
~Cursor()81 RawTable::Cursor::~Cursor() {}
Filter(const FilterConstraints & fc,sqlite3_value ** argv)82 int32_t RawTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
83 {
84 // reset indexMap_
85 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
86
87 if (rowCount_ <= 0) {
88 return SQLITE_OK;
89 }
90
91 auto RawTableCs = fc.GetConstraints();
92 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
93 SwapIndexFront(RawTableCs, sId);
94 for (size_t i = 0; i < RawTableCs.size(); i++) {
95 const auto& c = RawTableCs[i];
96 switch (static_cast<Index>(c.col)) {
97 case Index::ID:
98 FilterId(c.op, argv[i]);
99 break;
100 case Index::NAME:
101 indexMap_->MixRange(
102 c.op, GetNameIndex(std::string(reinterpret_cast<const char*>(sqlite3_value_text(argv[i])))),
103 rawObj_.NameData());
104 break;
105 case Index::TS:
106 FilterTS(c.op, argv[i], rawObj_.TimeStampData());
107 break;
108 case Index::INTERNAL_TID:
109 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
110 rawObj_.InternalTidsData());
111 break;
112 default:
113 break;
114 }
115 }
116
117 auto rawTableOrderbys = fc.GetOrderBys();
118 for (auto i = rawTableOrderbys.size(); i > 0;) {
119 i--;
120 switch (static_cast<Index>(rawTableOrderbys[i].iColumn)) {
121 case Index::ID:
122 indexMap_->SortBy(rawTableOrderbys[i].desc);
123 break;
124 default:
125 break;
126 }
127 }
128
129 return SQLITE_OK;
130 }
131
Column(int32_t column) const132 int32_t RawTable::Cursor::Column(int32_t column) const
133 {
134 switch (static_cast<Index>(column)) {
135 case Index::ID:
136 sqlite3_result_int64(context_, static_cast<int32_t>(CurrentRow()));
137 break;
138 case Index::TYPE:
139 sqlite3_result_text(context_, "raw", STR_DEFAULT_LEN, nullptr);
140 break;
141 case Index::TS:
142 sqlite3_result_int64(context_, static_cast<int64_t>(rawObj_.TimeStampData()[CurrentRow()]));
143 break;
144 case Index::NAME: {
145 if (rawObj_.NameData()[CurrentRow()] == RAW_CPU_IDLE) {
146 sqlite3_result_text(context_, "cpu_idle", STR_DEFAULT_LEN, nullptr);
147 } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKEUP) {
148 sqlite3_result_text(context_, "sched_wakeup", STR_DEFAULT_LEN, nullptr);
149 } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKING) {
150 sqlite3_result_text(context_, "sched_waking", STR_DEFAULT_LEN, nullptr);
151 }
152 break;
153 }
154 case Index::CPU:
155 sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.CpuData()[CurrentRow()]));
156 break;
157 case Index::INTERNAL_TID:
158 sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.InternalTidsData()[CurrentRow()]));
159 break;
160 default:
161 TS_LOGF("Unregistered column : %d", column);
162 break;
163 }
164 return SQLITE_OK;
165 }
GetOrbyes(FilterConstraints & rawfc,EstimatedIndexInfo & rawei)166 void RawTable::GetOrbyes(FilterConstraints& rawfc, EstimatedIndexInfo& rawei)
167 {
168 auto raworderbys = rawfc.GetOrderBys();
169 for (auto i = 0; i < raworderbys.size(); i++) {
170 switch (static_cast<Index>(raworderbys[i].iColumn)) {
171 case Index::ID:
172 break;
173 default: // other columns can be sorted by SQLite
174 rawei.isOrdered = false;
175 break;
176 }
177 }
178 }
179 } // namespace TraceStreamer
180 } // namespace SysTuning
181