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