• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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