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 "file_system_sample_table.h"
17
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t {
21 ID = 0,
22 CALLCHAIN_ID,
23 TYPE,
24 IPID,
25 ITID,
26 START_TS,
27 END_TS,
28 DUR,
29 RETURN_VALUE,
30 ERROR_VALUE,
31 FD,
32 FILE_ID,
33 SIZE,
34 FIRST_ARGUMENT,
35 SECOND_ARGUMENT,
36 THIRD_ARGUMENT,
37 FOURTH_ARGUMENT,
38 };
FileSystemSampleTable(const TraceDataCache * dataCache)39 FileSystemSampleTable::FileSystemSampleTable(const TraceDataCache* dataCache) : TableBase(dataCache)
40 {
41 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
42 tableColumn_.push_back(TableBase::ColumnInfo("callchain_id", "INTEGER"));
43 tableColumn_.push_back(TableBase::ColumnInfo("type", "INTEGER"));
44 tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
45 tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
46 tableColumn_.push_back(TableBase::ColumnInfo("start_ts", "INTEGER"));
47 tableColumn_.push_back(TableBase::ColumnInfo("end_ts", "INTEGER"));
48 tableColumn_.push_back(TableBase::ColumnInfo("dur", "INTEGER"));
49 tableColumn_.push_back(TableBase::ColumnInfo("return_value", "TEXT"));
50 tableColumn_.push_back(TableBase::ColumnInfo("error_code", "TEXT"));
51 tableColumn_.push_back(TableBase::ColumnInfo("fd", "INTEGER"));
52 tableColumn_.push_back(TableBase::ColumnInfo("file_id", "INTEGER"));
53 tableColumn_.push_back(TableBase::ColumnInfo("size", "INTEGER"));
54 tableColumn_.push_back(TableBase::ColumnInfo("first_argument", "TEXT"));
55 tableColumn_.push_back(TableBase::ColumnInfo("second_argument", "TEXT"));
56 tableColumn_.push_back(TableBase::ColumnInfo("third_argument", "TEXT"));
57 tableColumn_.push_back(TableBase::ColumnInfo("fourth_argument", "TEXT"));
58 tablePriKey_.push_back("id");
59 }
60
~FileSystemSampleTable()61 FileSystemSampleTable::~FileSystemSampleTable() {}
62
FilterByConstraint(FilterConstraints & sysfc,double & sysfilterCost,size_t sysrowCount,uint32_t syscurrenti)63 void FileSystemSampleTable::FilterByConstraint(FilterConstraints& sysfc,
64 double& sysfilterCost,
65 size_t sysrowCount,
66 uint32_t syscurrenti)
67 {
68 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
69 // for loop
70 const auto& sysc = sysfc.GetConstraints()[syscurrenti];
71 switch (static_cast<Index>(sysc.col)) {
72 case Index::ID: {
73 if (CanFilterId(sysc.op, sysrowCount)) {
74 sysfc.UpdateConstraint(syscurrenti, true);
75 sysfilterCost += 1; // id can position by 1 step
76 } else {
77 sysfilterCost += sysrowCount; // scan all rows
78 }
79 break;
80 }
81 default: // other column
82 sysfilterCost += sysrowCount; // scan all rows
83 break;
84 }
85 }
86
CreateCursor()87 std::unique_ptr<TableBase::Cursor> FileSystemSampleTable::CreateCursor()
88 {
89 return std::make_unique<Cursor>(dataCache_, this);
90 }
91
Cursor(const TraceDataCache * dataCache,TableBase * table)92 FileSystemSampleTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
93 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstFileSystemSample().Size())),
94 fileSystemSampleTableObj_(dataCache->GetConstFileSystemSample())
95 {
96 }
97
~Cursor()98 FileSystemSampleTable::Cursor::~Cursor() {}
99
Filter(const FilterConstraints & fc,sqlite3_value ** argv)100 int32_t FileSystemSampleTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
101 {
102 // reset indexMap_
103 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
104
105 if (rowCount_ <= 0) {
106 return SQLITE_OK;
107 }
108
109 auto fileSystemSampleCs = fc.GetConstraints();
110 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::ID)};
111 SwapIndexFront(fileSystemSampleCs, sId);
112 for (size_t i = 0; i < fileSystemSampleCs.size(); i++) {
113 const auto& c = fileSystemSampleCs[i];
114 switch (static_cast<Index>(c.col)) {
115 case Index::ID:
116 FilterId(c.op, argv[i]);
117 break;
118 case Index::TYPE:
119 indexMap_->MixRange(c.op, static_cast<uint16_t>(sqlite3_value_int(argv[i])),
120 fileSystemSampleTableObj_.Types());
121 break;
122 default:
123 break;
124 }
125 }
126
127 auto fileSystemSampleOrderbys = fc.GetOrderBys();
128 for (auto i = fileSystemSampleOrderbys.size(); i > 0;) {
129 i--;
130 switch (static_cast<Index>(fileSystemSampleOrderbys[i].iColumn)) {
131 case Index::ID:
132 indexMap_->SortBy(fileSystemSampleOrderbys[i].desc);
133 break;
134 default:
135 break;
136 }
137 }
138 return SQLITE_OK;
139 }
140
Column(int32_t column) const141 int32_t FileSystemSampleTable::Cursor::Column(int32_t column) const
142 {
143 switch (static_cast<Index>(column)) {
144 case Index::ID:
145 sqlite3_result_int64(context_, static_cast<int32_t>(fileSystemSampleTableObj_.IdsData()[CurrentRow()]));
146 break;
147 case Index::CALLCHAIN_ID:
148 SetTypeColumn(fileSystemSampleTableObj_.CallChainIds()[CurrentRow()], INVALID_UINT32,
149 INVALID_CALL_CHAIN_ID);
150 break;
151 case Index::TYPE:
152 SetTypeColumnInt64(fileSystemSampleTableObj_.Types()[CurrentRow()], INVALID_UINT64);
153 break;
154 case Index::IPID:
155 SetTypeColumnInt64(fileSystemSampleTableObj_.Ipids()[CurrentRow()], INVALID_UINT64);
156 break;
157 case Index::ITID:
158 SetTypeColumnInt64(fileSystemSampleTableObj_.Itids()[CurrentRow()], INVALID_UINT64);
159 break;
160 case Index::START_TS:
161 SetTypeColumnInt64(fileSystemSampleTableObj_.StartTs()[CurrentRow()], INVALID_UINT64);
162 break;
163 case Index::END_TS:
164 SetTypeColumnInt64(fileSystemSampleTableObj_.EndTs()[CurrentRow()], INVALID_UINT64);
165 break;
166 case Index::DUR:
167 SetTypeColumnInt64(fileSystemSampleTableObj_.Durs()[CurrentRow()], INVALID_UINT64);
168 break;
169 case Index::RETURN_VALUE:
170 SetTypeColumnText(fileSystemSampleTableObj_.ReturnValues()[CurrentRow()], INVALID_UINT64);
171 break;
172 case Index::ERROR_VALUE:
173 SetTypeColumnText(fileSystemSampleTableObj_.ErrorCodes()[CurrentRow()], INVALID_UINT64);
174 break;
175 default:
176 HandleTypeColumns(column);
177 break;
178 }
179 return SQLITE_OK;
180 }
HandleTypeColumns(int32_t fileSysSampleCol) const181 void FileSystemSampleTable::Cursor::HandleTypeColumns(int32_t fileSysSampleCol) const
182 {
183 switch (static_cast<Index>(fileSysSampleCol)) {
184 case Index::FD:
185 SetTypeColumnInt64(fileSystemSampleTableObj_.Fds()[CurrentRow()], INVALID_UINT64);
186 break;
187 case Index::FILE_ID:
188 SetTypeColumnInt64(fileSystemSampleTableObj_.FileIds()[CurrentRow()], INVALID_UINT64);
189 break;
190 case Index::SIZE:
191 SetTypeColumnInt64(fileSystemSampleTableObj_.Sizes()[CurrentRow()], MAX_SIZE_T);
192
193 break;
194 case Index::FIRST_ARGUMENT:
195 SetTypeColumnText(fileSystemSampleTableObj_.FirstArguments()[CurrentRow()], INVALID_UINT64);
196 break;
197 case Index::SECOND_ARGUMENT:
198 SetTypeColumnText(fileSystemSampleTableObj_.SecondArguments()[CurrentRow()], INVALID_UINT64);
199 break;
200 case Index::THIRD_ARGUMENT:
201 SetTypeColumnText(fileSystemSampleTableObj_.ThirdArguments()[CurrentRow()], INVALID_UINT64);
202 break;
203 case Index::FOURTH_ARGUMENT:
204 SetTypeColumnText(fileSystemSampleTableObj_.FourthArguments()[CurrentRow()], INVALID_UINT64);
205 break;
206 default:
207 TS_LOGF("Unregistered fileSysSampleCol : %d", fileSysSampleCol);
208 break;
209 }
210 }
GetOrbyes(FilterConstraints & sysfc,EstimatedIndexInfo & sysei)211 void FileSystemSampleTable::GetOrbyes(FilterConstraints& sysfc, EstimatedIndexInfo& sysei)
212 {
213 auto sysOrderbys = sysfc.GetOrderBys();
214 for (auto i = 0; i < sysOrderbys.size(); i++) {
215 switch (static_cast<Index>(sysOrderbys[i].iColumn)) {
216 case Index::ID:
217 break;
218 default: // other columns can be sorted by SQLite
219 sysei.isOrdered = false;
220 break;
221 }
222 }
223 }
224 } // namespace TraceStreamer
225 } // namespace SysTuning
226