• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_statistic_table.h"
17 
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t {
21     ID = 0,
22     CALLCHAIN_ID,
23     IPID,
24     TS,
25     MEMORY_TYPE,
26     MEMORY_SUB_TYPE,
27     APPLY_COUNT,
28     RELEASE_COUNT,
29     APPLY_SIZE,
30     RELEASE_SIZE,
31     LAST_LIB_ID,
32     LAST_SYMBOL_ID
33 };
NativeHookStatisticTable(const TraceDataCache * dataCache)34 NativeHookStatisticTable::NativeHookStatisticTable(const TraceDataCache *dataCache) : TableBase(dataCache)
35 {
36     tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
37     tableColumn_.push_back(TableBase::ColumnInfo("callchain_id", "INTEGER"));
38     tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
39     tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
40     tableColumn_.push_back(TableBase::ColumnInfo("type", "INTEGER"));
41     tableColumn_.push_back(TableBase::ColumnInfo("sub_type_id", "INTEGER"));
42     tableColumn_.push_back(TableBase::ColumnInfo("apply_count", "INTEGER"));
43     tableColumn_.push_back(TableBase::ColumnInfo("release_count", "INTEGER"));
44     tableColumn_.push_back(TableBase::ColumnInfo("apply_size", "INTEGER"));
45     tableColumn_.push_back(TableBase::ColumnInfo("release_size", "INTEGER"));
46     tableColumn_.push_back(TableBase::ColumnInfo("last_lib_id", "INTEGER"));
47     tableColumn_.push_back(TableBase::ColumnInfo("last_symbol_id", "INTEGER"));
48     tablePriKey_.push_back("id");
49 }
50 
~NativeHookStatisticTable()51 NativeHookStatisticTable::~NativeHookStatisticTable() {}
52 
FilterByConstraint(FilterConstraints & statisticfc,double & statisticfilterCost,size_t statisticrowCount,uint32_t statisticcurrenti)53 void NativeHookStatisticTable::FilterByConstraint(FilterConstraints &statisticfc,
54                                                   double &statisticfilterCost,
55                                                   size_t statisticrowCount,
56                                                   uint32_t statisticcurrenti)
57 {
58     // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
59     // for loop
60     const auto &statisticc = statisticfc.GetConstraints()[statisticcurrenti];
61     switch (static_cast<Index>(statisticc.col)) {
62         case Index::ID: {
63             if (CanFilterId(statisticc.op, statisticrowCount)) {
64                 statisticfc.UpdateConstraint(statisticcurrenti, true);
65                 statisticfilterCost += 1; // id can position by 1 step
66             } else {
67                 statisticfilterCost += statisticrowCount; // scan all rows
68             }
69             break;
70         }
71         default:                                      // other column
72             statisticfilterCost += statisticrowCount; // scan all rows
73             break;
74     }
75 }
76 
CreateCursor()77 std::unique_ptr<TableBase::Cursor> NativeHookStatisticTable::CreateCursor()
78 {
79     return std::make_unique<Cursor>(dataCache_, this);
80 }
81 
Cursor(const TraceDataCache * dataCache,TableBase * table)82 NativeHookStatisticTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
83     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstNativeHookStatisticData().Size())),
84       nativeHookStatisticInfoObj_(dataCache->GetConstNativeHookStatisticData())
85 {
86 }
87 
~Cursor()88 NativeHookStatisticTable::Cursor::~Cursor() {}
89 
Filter(const FilterConstraints & fc,sqlite3_value ** argv)90 int32_t NativeHookStatisticTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
91 {
92     // reset indexMap_
93     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
94 
95     if (rowCount_ <= 0) {
96         return SQLITE_OK;
97     }
98 
99     auto nativeHookStatisticCs = fc.GetConstraints();
100     std::set<uint32_t> sId = {static_cast<uint32_t>(Index::ID)};
101     SwapIndexFront(nativeHookStatisticCs, sId);
102     for (size_t i = 0; i < nativeHookStatisticCs.size(); i++) {
103         const auto &c = nativeHookStatisticCs[i];
104         switch (static_cast<Index>(c.col)) {
105             case Index::ID:
106                 FilterId(c.op, argv[c.idxInaConstraint]);
107                 break;
108             case Index::CALLCHAIN_ID:
109                 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int64(argv[c.idxInaConstraint])),
110                                     nativeHookStatisticInfoObj_.CallChainIds());
111                 break;
112             default:
113                 break;
114         }
115     }
116 
117     auto nativeHookStatisticOrderbys = fc.GetOrderBys();
118     for (auto i = nativeHookStatisticOrderbys.size(); i > 0;) {
119         i--;
120         switch (static_cast<Index>(nativeHookStatisticOrderbys[i].iColumn)) {
121             case Index::ID:
122                 indexMap_->SortBy(nativeHookStatisticOrderbys[i].desc);
123                 break;
124             default:
125                 break;
126         }
127     }
128 
129     return SQLITE_OK;
130 }
131 
Column(int32_t column) const132 int32_t NativeHookStatisticTable::Cursor::Column(int32_t column) const
133 {
134     switch (static_cast<Index>(column)) {
135         case Index::ID:
136             sqlite3_result_int64(context_, static_cast<int32_t>(nativeHookStatisticInfoObj_.IdsData()[CurrentRow()]));
137             break;
138         case Index::CALLCHAIN_ID:
139             SetTypeColumn(nativeHookStatisticInfoObj_.CallChainIds()[CurrentRow()], INVALID_UINT32,
140                           INVALID_CALL_CHAIN_ID);
141             break;
142         case Index::IPID:
143             SetTypeColumnInt64(nativeHookStatisticInfoObj_.Ipids()[CurrentRow()], INVALID_UINT32);
144             break;
145         case Index::TS:
146             SetTypeColumnInt64(nativeHookStatisticInfoObj_.TimeStampData()[CurrentRow()], INVALID_UINT64);
147             break;
148         case Index::MEMORY_TYPE:
149             SetTypeColumnInt64(nativeHookStatisticInfoObj_.MemoryTypes()[CurrentRow()], INVALID_UINT64);
150             break;
151         case Index::MEMORY_SUB_TYPE:
152             SetTypeColumnInt64(nativeHookStatisticInfoObj_.MemorySubTypes()[CurrentRow()], INVALID_UINT64);
153             break;
154         case Index::APPLY_COUNT:
155             SetTypeColumnInt64(nativeHookStatisticInfoObj_.ApplyCounts()[CurrentRow()], INVALID_UINT64);
156             break;
157         case Index::RELEASE_COUNT:
158             SetTypeColumnInt64(nativeHookStatisticInfoObj_.ReleaseCounts()[CurrentRow()], INVALID_UINT64);
159             break;
160         case Index::APPLY_SIZE:
161             SetTypeColumnInt64(nativeHookStatisticInfoObj_.ApplySizes()[CurrentRow()], INVALID_UINT64);
162             break;
163         case Index::RELEASE_SIZE:
164             SetTypeColumnInt64(nativeHookStatisticInfoObj_.ReleaseSizes()[CurrentRow()], INVALID_UINT64);
165             break;
166         case Index::LAST_LIB_ID:
167             SetTypeColumnInt64(nativeHookStatisticInfoObj_.LastCallerPathIndexs()[CurrentRow()], INVALID_DATAINDEX);
168             break;
169         case Index::LAST_SYMBOL_ID:
170             SetTypeColumnInt64(nativeHookStatisticInfoObj_.LastSymbolIndexs()[CurrentRow()], INVALID_DATAINDEX);
171             break;
172         default:
173             TS_LOGF("Unregistered column : %d", column);
174             break;
175     }
176     return SQLITE_OK;
177 }
178 
GetOrbyes(FilterConstraints & statisticfc,EstimatedIndexInfo & statisticei)179 void NativeHookStatisticTable::GetOrbyes(FilterConstraints &statisticfc, EstimatedIndexInfo &statisticei)
180 {
181     auto statisticorderbys = statisticfc.GetOrderBys();
182     for (auto i = 0; i < statisticorderbys.size(); i++) {
183         switch (static_cast<Index>(statisticorderbys[i].iColumn)) {
184             case Index::ID:
185                 break;
186             default: // other columns can be sorted by SQLite
187                 statisticei.isOrdered = false;
188                 break;
189         }
190     }
191 }
192 } // namespace TraceStreamer
193 } // namespace SysTuning
194