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 "irq_table.h"
17
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t {
21 ID = 0,
22 TS,
23 DURS,
24 CALL_IDS,
25 CAT,
26 NAME,
27 DEPTH,
28 COOKIE_ID,
29 PARENT_ID,
30 ARGSET,
31 CHAIN_IDS,
32 SPAN_IDS,
33 PARENT_SPAN_IDS,
34 FLAG,
35 ARGS
36 };
IrqTable(const TraceDataCache * dataCache)37 IrqTable::IrqTable(const TraceDataCache* dataCache) : TableBase(dataCache)
38 {
39 tableColumn_.emplace_back(TableBase::ColumnInfo("id", "INTEGER"));
40 tableColumn_.emplace_back(TableBase::ColumnInfo("ts", "INTEGER"));
41 tableColumn_.emplace_back(TableBase::ColumnInfo("dur", "INTEGER"));
42 tableColumn_.emplace_back(TableBase::ColumnInfo("callid", "INTEGER"));
43 tableColumn_.emplace_back(TableBase::ColumnInfo("cat", "TEXT"));
44 tableColumn_.emplace_back(TableBase::ColumnInfo("name", "TEXT"));
45 tableColumn_.emplace_back(TableBase::ColumnInfo("depth", "INTEGER"));
46 tableColumn_.emplace_back(TableBase::ColumnInfo("cookie", "INTEGER"));
47 tableColumn_.emplace_back(TableBase::ColumnInfo("parent_id", "INTEGER"));
48 tableColumn_.emplace_back(TableBase::ColumnInfo("argsetid", "INTEGER"));
49 tableColumn_.emplace_back(TableBase::ColumnInfo("spanId", "TEXT"));
50 tableColumn_.emplace_back(TableBase::ColumnInfo("parentSpanId", "TEXT"));
51 tableColumn_.emplace_back(TableBase::ColumnInfo("flag", "TEXT"));
52 tableColumn_.emplace_back(TableBase::ColumnInfo("args", "TEXT"));
53 tablePriKey_.emplace_back("callid");
54 tablePriKey_.emplace_back("ts");
55 tablePriKey_.emplace_back("depth");
56 }
57
~IrqTable()58 IrqTable::~IrqTable() {}
59
FilterByConstraint(FilterConstraints & irqfc,double & irqfilterCost,size_t irqrowCount,uint32_t irqcurrenti)60 void IrqTable::FilterByConstraint(FilterConstraints& irqfc,
61 double& irqfilterCost,
62 size_t irqrowCount,
63 uint32_t irqcurrenti)
64 {
65 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
66 // for loop
67 const auto& irqc = irqfc.GetConstraints()[irqcurrenti];
68 switch (static_cast<Index>(irqc.col)) {
69 case Index::ID: {
70 if (CanFilterId(irqc.op, irqrowCount)) {
71 irqfc.UpdateConstraint(irqcurrenti, true);
72 irqfilterCost += 1; // id can position by 1 step
73 } else {
74 irqfilterCost += irqrowCount; // scan all rows
75 }
76 break;
77 }
78 default: // other column
79 irqfilterCost += irqrowCount; // scan all rows
80 break;
81 }
82 }
83
CreateCursor()84 std::unique_ptr<TableBase::Cursor> IrqTable::CreateCursor()
85 {
86 return std::make_unique<Cursor>(dataCache_, this);
87 }
88
Cursor(const TraceDataCache * dataCache,TableBase * table)89 IrqTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
90 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstIrqData().Size())),
91 slicesObj_(dataCache->GetConstIrqData())
92 {
93 }
94
~Cursor()95 IrqTable::Cursor::~Cursor() {}
96
Filter(const FilterConstraints & fc,sqlite3_value ** argv)97 int32_t IrqTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
98 {
99 // reset indexMap_
100 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
101
102 if (rowCount_ <= 0) {
103 return SQLITE_OK;
104 }
105
106 auto& irqCs = fc.GetConstraints();
107 for (size_t i = 0; i < irqCs.size(); i++) {
108 const auto& c = irqCs[i];
109 switch (static_cast<Index>(c.col)) {
110 case Index::ID:
111 FilterId(c.op, argv[i]);
112 break;
113 default:
114 break;
115 }
116 }
117
118 auto irqTableOrderbys = fc.GetOrderBys();
119 for (auto i = irqTableOrderbys.size(); i > 0;) {
120 i--;
121 switch (static_cast<Index>(irqTableOrderbys[i].iColumn)) {
122 case Index::ID:
123 indexMap_->SortBy(irqTableOrderbys[i].desc);
124 break;
125 default:
126 break;
127 }
128 }
129
130 return SQLITE_OK;
131 }
132
Column(int32_t column) const133 int32_t IrqTable::Cursor::Column(int32_t column) const
134 {
135 switch (static_cast<Index>(column)) {
136 case Index::ID:
137 sqlite3_result_int64(context_, CurrentRow());
138 break;
139 case Index::TS:
140 SetTypeColumnInt64(slicesObj_.TimeStampData()[CurrentRow()], INVALID_UINT64);
141 break;
142 case Index::DURS:
143 SetTypeColumnInt64(slicesObj_.DursData()[CurrentRow()], INVALID_UINT64);
144 break;
145 case Index::CALL_IDS:
146 SetTypeColumnInt64(slicesObj_.CallIds()[CurrentRow()], INVALID_UINT64);
147 break;
148 case Index::CAT: {
149 SetTypeColumnText(slicesObj_.CatsData()[CurrentRow()], INVALID_UINT64);
150 break;
151 }
152 case Index::NAME: {
153 SetTypeColumnText(slicesObj_.NamesData()[CurrentRow()], INVALID_UINT64);
154 break;
155 }
156 case Index::DEPTH:
157 sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.Depths()[CurrentRow()]));
158 break;
159 default:
160 HandleTypeColumns(column);
161 }
162 return SQLITE_OK;
163 }
HandleTypeColumns(int32_t column) const164 void IrqTable::Cursor::HandleTypeColumns(int32_t column) const
165 {
166 switch (static_cast<Index>(column)) {
167 case Index::COOKIE_ID:
168 SetTypeColumnInt64(slicesObj_.Cookies()[CurrentRow()], INVALID_UINT64);
169 break;
170 case Index::PARENT_ID: {
171 if (slicesObj_.ParentIdData()[CurrentRow()].has_value()) {
172 sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.ParentIdData()[CurrentRow()].value()));
173 }
174 break;
175 }
176 case Index::ARGSET:
177 SetTypeColumnInt64(slicesObj_.ArgSetIdsData()[CurrentRow()], INVALID_UINT32);
178 break;
179 case Index::CHAIN_IDS:
180 sqlite3_result_text(context_, slicesObj_.ChainIds()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
181 break;
182 case Index::SPAN_IDS:
183 sqlite3_result_text(context_, slicesObj_.SpanIds()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
184 break;
185 case Index::PARENT_SPAN_IDS:
186 sqlite3_result_text(context_, slicesObj_.ParentSpanIds()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
187 break;
188 case Index::FLAG:
189 sqlite3_result_text(context_, slicesObj_.Flags()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
190 break;
191 case Index::ARGS:
192 sqlite3_result_text(context_, slicesObj_.ArgsData()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
193 break;
194 default:
195 TS_LOGF("Unregistered column : %d", column);
196 break;
197 }
198 }
GetOrbyes(FilterConstraints & irqfc,EstimatedIndexInfo & irqei)199 void IrqTable::GetOrbyes(FilterConstraints& irqfc, EstimatedIndexInfo& irqei)
200 {
201 auto irqorderbys = irqfc.GetOrderBys();
202 for (auto i = 0; i < irqorderbys.size(); i++) {
203 switch (static_cast<Index>(irqorderbys[i].iColumn)) {
204 case Index::ID:
205 break;
206 default: // other columns can be sorted by SQLite
207 irqei.isOrdered = false;
208 break;
209 }
210 }
211 }
212 } // namespace TraceStreamer
213 } // namespace SysTuning
214