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 "frame_slice_table.h"
17
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t {
21 ID = 0,
22 TS,
23 VSYNC,
24 IPID,
25 ITID,
26 CALLSTACK_ID,
27 DUR,
28 SRC,
29 DST,
30 TYPE,
31 TYPE_DESC,
32 FLAG,
33 DEPTH,
34 FRAME_NO
35 };
FrameSliceTable(const TraceDataCache * dataCache)36 FrameSliceTable::FrameSliceTable(const TraceDataCache* dataCache) : TableBase(dataCache)
37 {
38 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
39 tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
40 tableColumn_.push_back(TableBase::ColumnInfo("vsync", "INTEGER"));
41 tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
42 tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
43 tableColumn_.push_back(TableBase::ColumnInfo("callstack_id", "INTEGER"));
44 tableColumn_.push_back(TableBase::ColumnInfo("dur", "INTEGER"));
45 tableColumn_.push_back(TableBase::ColumnInfo("src", "TEXT"));
46 tableColumn_.push_back(TableBase::ColumnInfo("dst", "INTEGER"));
47 tableColumn_.push_back(TableBase::ColumnInfo("type", "INTEGER"));
48 tableColumn_.push_back(TableBase::ColumnInfo("type_desc", "TEXT"));
49 tableColumn_.push_back(TableBase::ColumnInfo("flag", "INTEGER"));
50 tableColumn_.push_back(TableBase::ColumnInfo("depth", "INTEGER"));
51 tableColumn_.push_back(TableBase::ColumnInfo("frame_no", "INTEGER"));
52 tablePriKey_.push_back("id");
53 }
54
~FrameSliceTable()55 FrameSliceTable::~FrameSliceTable() {}
56
FilterByConstraint(FilterConstraints & slicefc,double & slicefilterCost,size_t slicerowCount,uint32_t slicecurrenti)57 void FrameSliceTable::FilterByConstraint(FilterConstraints& slicefc,
58 double& slicefilterCost,
59 size_t slicerowCount,
60 uint32_t slicecurrenti)
61 {
62 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
63 // for loop
64 const auto& slicec = slicefc.GetConstraints()[slicecurrenti];
65 switch (static_cast<Index>(slicec.col)) {
66 case Index::ID: {
67 if (CanFilterId(slicec.op, slicerowCount)) {
68 slicefc.UpdateConstraint(slicecurrenti, true);
69 slicefilterCost += 1; // id can position by 1 step
70 } else {
71 slicefilterCost += slicerowCount; // scan all rows
72 }
73 break;
74 }
75 default: // other column
76 slicefilterCost += slicerowCount; // scan all rows
77 break;
78 }
79 }
80
CreateCursor()81 std::unique_ptr<TableBase::Cursor> FrameSliceTable::CreateCursor()
82 {
83 return std::make_unique<Cursor>(dataCache_, this);
84 }
85
Cursor(const TraceDataCache * dataCache,TableBase * table)86 FrameSliceTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
87 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstFrameSliceData().Size())),
88 frameSliceObj_(dataCache->GetConstFrameSliceData())
89 {
90 }
91
~Cursor()92 FrameSliceTable::Cursor::~Cursor() {}
93
Filter(const FilterConstraints & fc,sqlite3_value ** argv)94 int32_t FrameSliceTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
95 {
96 // reset indexMap_
97 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
98
99 if (rowCount_ <= 0) {
100 return SQLITE_OK;
101 }
102
103 HandleIndex(fc, argv);
104
105 auto frameSliceTabOrderbys = fc.GetOrderBys();
106 for (auto i = frameSliceTabOrderbys.size(); i > 0;) {
107 i--;
108 switch (static_cast<Index>(frameSliceTabOrderbys[i].iColumn)) {
109 case Index::ID:
110 indexMap_->SortBy(frameSliceTabOrderbys[i].desc);
111 break;
112 default:
113 break;
114 }
115 }
116
117 return SQLITE_OK;
118 }
HandleIndex(const FilterConstraints & fc,sqlite3_value ** argv)119 void FrameSliceTable::Cursor::HandleIndex(const FilterConstraints& fc, sqlite3_value** argv)
120 {
121 auto& cs = fc.GetConstraints();
122 for (size_t i = 0; i < cs.size(); i++) {
123 const auto& c = cs[i];
124 switch (static_cast<Index>(c.col)) {
125 case Index::ID:
126 FilterId(c.op, argv[i]);
127 break;
128 case Index::ITID:
129 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
130 frameSliceObj_.InternalTidsData());
131 break;
132 case Index::IPID:
133 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])), frameSliceObj_.Ipids());
134 break;
135 case Index::VSYNC:
136 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])), frameSliceObj_.VsyncIds());
137 break;
138 case Index::CALLSTACK_ID:
139 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int(argv[i])),
140 frameSliceObj_.CallStackIds());
141 break;
142 case Index::DUR:
143 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int(argv[i])), frameSliceObj_.Durs());
144 break;
145 case Index::TYPE:
146 indexMap_->MixRange(c.op, static_cast<uint8_t>(sqlite3_value_int(argv[i])), frameSliceObj_.Types());
147 break;
148 case Index::FLAG:
149 indexMap_->MixRange(c.op, static_cast<uint8_t>(sqlite3_value_int(argv[i])), frameSliceObj_.Flags());
150 break;
151 case Index::DEPTH:
152 indexMap_->MixRange(c.op, static_cast<uint8_t>(sqlite3_value_int(argv[i])), frameSliceObj_.Depths());
153 break;
154 case Index::FRAME_NO:
155 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])), frameSliceObj_.FrameNos());
156 break;
157 default:
158 break;
159 }
160 }
161 }
Column(int32_t column) const162 int32_t FrameSliceTable::Cursor::Column(int32_t column) const
163 {
164 switch (static_cast<Index>(column)) {
165 case Index::ID:
166 sqlite3_result_int64(context_, static_cast<int32_t>(CurrentRow()));
167 break;
168 case Index::TS:
169 SetTypeColumnInt64(frameSliceObj_.TimeStampData()[CurrentRow()], INVALID_UINT64);
170 break;
171 case Index::VSYNC:
172 sqlite3_result_int64(context_, static_cast<int32_t>(frameSliceObj_.VsyncIds()[CurrentRow()]));
173 break;
174 case Index::IPID:
175 sqlite3_result_int64(context_, static_cast<int32_t>(frameSliceObj_.Ipids()[CurrentRow()]));
176 break;
177 case Index::ITID:
178 sqlite3_result_int64(context_, static_cast<int32_t>(frameSliceObj_.InternalTidsData()[CurrentRow()]));
179 break;
180 case Index::CALLSTACK_ID:
181 SetTypeColumnInt64(frameSliceObj_.CallStackIds()[CurrentRow()], INVALID_UINT64);
182 break;
183 case Index::DUR:
184 SetTypeColumnInt64(frameSliceObj_.Durs()[CurrentRow()], INVALID_UINT64);
185 break;
186 default:
187 HandleTypeColumns(column);
188 }
189
190 return SQLITE_OK;
191 }
HandleTypeColumns(int32_t column) const192 void FrameSliceTable::Cursor::HandleTypeColumns(int32_t column) const
193 {
194 switch (static_cast<Index>(column)) {
195 case Index::SRC:
196 sqlite3_result_text(context_, frameSliceObj_.Srcs()[CurrentRow()].c_str(),
197 frameSliceObj_.Srcs()[CurrentRow()].length(), nullptr);
198 break;
199 case Index::DST:
200 SetTypeColumnInt64(frameSliceObj_.Dsts()[CurrentRow()], INVALID_UINT64);
201 break;
202 case Index::TYPE:
203 SetTypeColumnInt64(frameSliceObj_.Types()[CurrentRow()], INVALID_UINT64);
204 break;
205 case Index::TYPE_DESC:
206 sqlite3_result_text(context_, frameSliceObj_.Types()[CurrentRow()] == 0 ? "actural" : "expect",
207 STR_DEFAULT_LEN, nullptr);
208 break;
209 case Index::FLAG:
210 SetTypeColumnInt32(frameSliceObj_.Flags()[CurrentRow()], INVALID_UINT8);
211 break;
212 case Index::DEPTH:
213 SetTypeColumnInt32(frameSliceObj_.Depths()[CurrentRow()], INVALID_UINT8);
214 break;
215 case Index::FRAME_NO:
216 SetTypeColumnInt32(frameSliceObj_.FrameNos()[CurrentRow()], INVALID_UINT32);
217 break;
218 default:
219 TS_LOGF("Unregistered column : %d", column);
220 break;
221 }
222 }
GetOrbyes(FilterConstraints & slicefc,EstimatedIndexInfo & sliceei)223 void FrameSliceTable::GetOrbyes(FilterConstraints& slicefc, EstimatedIndexInfo& sliceei)
224 {
225 auto sliceorderbys = slicefc.GetOrderBys();
226 for (auto i = 0; i < sliceorderbys.size(); i++) {
227 switch (static_cast<Index>(sliceorderbys[i].iColumn)) {
228 case Index::ID:
229 break;
230 default: // other columns can be sorted by SQLite
231 sliceei.isOrdered = false;
232 break;
233 }
234 }
235 }
236 } // namespace TraceStreamer
237 } // namespace SysTuning
238