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 "native_hook_frame_table.h"
17
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t { ID = 0, CALLCHAIN_ID, DEPTH, IP, SYMBOL_ID, FILE_ID, OFFSET, SYMBOL_OFFSET, VADDR };
NativeHookFrameTable(const TraceDataCache * dataCache)21 NativeHookFrameTable::NativeHookFrameTable(const TraceDataCache *dataCache) : TableBase(dataCache)
22 {
23 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
24 tableColumn_.push_back(TableBase::ColumnInfo("callchain_id", "INTEGER"));
25 tableColumn_.push_back(TableBase::ColumnInfo("depth", "INTEGER"));
26 tableColumn_.push_back(TableBase::ColumnInfo("ip", "INTEGER"));
27 tableColumn_.push_back(TableBase::ColumnInfo("symbol_id", "INTEGER"));
28 tableColumn_.push_back(TableBase::ColumnInfo("file_id", "INTEGER"));
29 tableColumn_.push_back(TableBase::ColumnInfo("offset", "INTEGER"));
30 tableColumn_.push_back(TableBase::ColumnInfo("symbol_offset", "INTEGER"));
31 tableColumn_.push_back(TableBase::ColumnInfo("vaddr", "TEXT"));
32 tablePriKey_.push_back("id");
33 }
34
~NativeHookFrameTable()35 NativeHookFrameTable::~NativeHookFrameTable() {}
36
FilterByConstraint(FilterConstraints & framefc,double & framefilterCost,size_t framerowCount,uint32_t framecurrenti)37 void NativeHookFrameTable::FilterByConstraint(FilterConstraints &framefc,
38 double &framefilterCost,
39 size_t framerowCount,
40 uint32_t framecurrenti)
41 {
42 const auto &framec = framefc.GetConstraints()[framecurrenti];
43 switch (static_cast<Index>(framec.col)) {
44 case Index::ID: {
45 if (CanFilterId(framec.op, framerowCount)) {
46 framefc.UpdateConstraint(framecurrenti, true);
47 framefilterCost += 1; // id can position by 1 step
48 } else {
49 framefilterCost += framerowCount; // scan all rows
50 }
51 break;
52 }
53 default: // other column
54 framefilterCost += framerowCount; // scan all rows
55 break;
56 }
57 }
58
CreateCursor()59 std::unique_ptr<TableBase::Cursor> NativeHookFrameTable::CreateCursor()
60 {
61 return std::make_unique<Cursor>(dataCache_, this);
62 }
63
Cursor(const TraceDataCache * dataCache,TableBase * table)64 NativeHookFrameTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
65 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstNativeHookFrameData().Size())),
66 nativeHookFrameInfoObj_(dataCache->GetConstNativeHookFrameData())
67 {
68 }
69
~Cursor()70 NativeHookFrameTable::Cursor::~Cursor() {}
71
Filter(const FilterConstraints & fc,sqlite3_value ** argv)72 int32_t NativeHookFrameTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
73 {
74 // reset indexMap_
75 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
76
77 if (rowCount_ <= 0) {
78 return SQLITE_OK;
79 }
80
81 auto nativeHookFrameCs = fc.GetConstraints();
82 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::ID)};
83 SwapIndexFront(nativeHookFrameCs, sId);
84 for (size_t i = 0; i < nativeHookFrameCs.size(); i++) {
85 const auto &c = nativeHookFrameCs[i];
86 switch (static_cast<Index>(c.col)) {
87 case Index::ID:
88 FilterId(c.op, argv[c.idxInaConstraint]);
89 break;
90 case Index::CALLCHAIN_ID:
91 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int64(argv[c.idxInaConstraint])),
92 nativeHookFrameInfoObj_.CallChainIds());
93 break;
94 case Index::SYMBOL_ID:
95 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int64(argv[c.idxInaConstraint])),
96 nativeHookFrameInfoObj_.SymbolNames());
97 break;
98 case Index::FILE_ID:
99 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int64(argv[c.idxInaConstraint])),
100 nativeHookFrameInfoObj_.FilePaths());
101 break;
102 default:
103 break;
104 }
105 }
106
107 auto nativeHookFrameOrderbys = fc.GetOrderBys();
108 for (auto i = nativeHookFrameOrderbys.size(); i > 0;) {
109 i--;
110 switch (static_cast<Index>(nativeHookFrameOrderbys[i].iColumn)) {
111 case Index::ID:
112 indexMap_->SortBy(nativeHookFrameOrderbys[i].desc);
113 break;
114 default:
115 break;
116 }
117 }
118
119 return SQLITE_OK;
120 }
121
Column(int32_t nativeHookFrameCol) const122 int32_t NativeHookFrameTable::Cursor::Column(int32_t nativeHookFrameCol) const
123 {
124 switch (static_cast<Index>(nativeHookFrameCol)) {
125 case Index::ID:
126 sqlite3_result_int64(context_, static_cast<int32_t>(CurrentRow()));
127 break;
128 case Index::CALLCHAIN_ID:
129 SetTypeColumn(nativeHookFrameInfoObj_.CallChainIds()[CurrentRow()], INVALID_UINT32, INVALID_CALL_CHAIN_ID);
130 break;
131 case Index::DEPTH:
132 sqlite3_result_int(context_, static_cast<int32_t>(nativeHookFrameInfoObj_.Depths()[CurrentRow()]));
133 break;
134 case Index::IP:
135 SetTypeColumnInt64(nativeHookFrameInfoObj_.Ips()[CurrentRow()], INVALID_UINT64);
136 break;
137 case Index::SYMBOL_ID:
138 SetTypeColumnInt64(nativeHookFrameInfoObj_.SymbolNames()[CurrentRow()], INVALID_UINT64);
139 break;
140 case Index::FILE_ID: {
141 SetTypeColumnInt64(nativeHookFrameInfoObj_.FilePaths()[CurrentRow()], INVALID_UINT64);
142 break;
143 }
144 case Index::OFFSET: {
145 SetTypeColumnInt64(nativeHookFrameInfoObj_.Offsets()[CurrentRow()], INVALID_UINT64);
146 break;
147 }
148 case Index::SYMBOL_OFFSET: {
149 SetTypeColumnInt64(nativeHookFrameInfoObj_.SymbolOffsets()[CurrentRow()], INVALID_UINT64);
150 break;
151 }
152 case Index::VADDR: {
153 SetTypeColumnTextNotEmpty(nativeHookFrameInfoObj_.Vaddrs()[CurrentRow()].empty(),
154 nativeHookFrameInfoObj_.Vaddrs()[CurrentRow()].c_str());
155 break;
156 }
157 default:
158 TS_LOGF("Unregistered nativeHookFrameCol : %d", nativeHookFrameCol);
159 break;
160 }
161 return SQLITE_OK;
162 }
163
GetOrbyes(FilterConstraints & framefc,EstimatedIndexInfo & frameei)164 void NativeHookFrameTable::GetOrbyes(FilterConstraints &framefc, EstimatedIndexInfo &frameei)
165 {
166 auto frameorderbys = framefc.GetOrderBys();
167 for (auto i = 0; i < frameorderbys.size(); i++) {
168 switch (static_cast<Index>(frameorderbys[i].iColumn)) {
169 case Index::ID:
170 break;
171 default: // other columns can be sorted by SQLite
172 frameei.isOrdered = false;
173 break;
174 }
175 }
176 }
177 } // namespace TraceStreamer
178 } // namespace SysTuning
179