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 "process_measure_filter_table.h"
17
18 #include <cmath>
19
20 namespace SysTuning {
21 namespace TraceStreamer {
22 enum class Index : int32_t { ID = 0, TYPE, NAME, INTERNAL_PID };
ProcessMeasureFilterTable(const TraceDataCache * dataCache)23 ProcessMeasureFilterTable::ProcessMeasureFilterTable(const TraceDataCache* dataCache) : TableBase(dataCache)
24 {
25 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
26 tableColumn_.push_back(TableBase::ColumnInfo("type", "TEXT"));
27 tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT"));
28 tableColumn_.push_back(TableBase::ColumnInfo("ipid", "INTEGER"));
29 tablePriKey_.push_back("id");
30 }
31
~ProcessMeasureFilterTable()32 ProcessMeasureFilterTable::~ProcessMeasureFilterTable() {}
33
FilterByConstraint(FilterConstraints & filterfc,double & filterfilterCost,size_t filterrowCount,uint32_t filtercurrenti)34 void ProcessMeasureFilterTable::FilterByConstraint(FilterConstraints& filterfc,
35 double& filterfilterCost,
36 size_t filterrowCount,
37 uint32_t filtercurrenti)
38 {
39 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
40 // for loop
41 const auto& filterc = filterfc.GetConstraints()[filtercurrenti];
42 switch (static_cast<Index>(filterc.col)) {
43 case Index::ID: {
44 auto filteroldRowCount = filterrowCount;
45 if (CanFilterSorted(filterc.op, filterrowCount)) {
46 filterfc.UpdateConstraint(filtercurrenti, true);
47 filterfilterCost += log2(filteroldRowCount); // binary search
48 } else {
49 filterfilterCost += filteroldRowCount;
50 }
51 break;
52 }
53 default: // other column
54 filterfilterCost += filterrowCount; // scan all rows
55 break;
56 }
57 }
58
CanFilterSorted(const char op,size_t & procRowCnt) const59 bool ProcessMeasureFilterTable::CanFilterSorted(const char op, size_t& procRowCnt) const
60 {
61 switch (op) {
62 case SQLITE_INDEX_CONSTRAINT_EQ:
63 procRowCnt = procRowCnt / log2(procRowCnt);
64 break;
65 case SQLITE_INDEX_CONSTRAINT_GT:
66 case SQLITE_INDEX_CONSTRAINT_GE:
67 case SQLITE_INDEX_CONSTRAINT_LE:
68 case SQLITE_INDEX_CONSTRAINT_LT:
69 procRowCnt = (procRowCnt >> 1);
70 break;
71 default:
72 return false;
73 }
74 return true;
75 }
76
CreateCursor()77 std::unique_ptr<TableBase::Cursor> ProcessMeasureFilterTable::CreateCursor()
78 {
79 return std::make_unique<Cursor>(dataCache_, this);
80 }
81
Cursor(const TraceDataCache * dataCache,TableBase * table)82 ProcessMeasureFilterTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
83 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstProcessMeasureFilterData().Size()))
84 {
85 }
86
~Cursor()87 ProcessMeasureFilterTable::Cursor::~Cursor() {}
88
Filter(const FilterConstraints & fc,sqlite3_value ** argv)89 int32_t ProcessMeasureFilterTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
90 {
91 // reset indexMap_
92 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
93
94 if (rowCount_ <= 0) {
95 return SQLITE_OK;
96 }
97
98 auto& procMeasureFilterCs = fc.GetConstraints();
99 for (size_t i = 0; i < procMeasureFilterCs.size(); i++) {
100 const auto& c = procMeasureFilterCs[i];
101 switch (static_cast<Index>(c.col)) {
102 case Index::ID:
103 indexMap_->MixRange(c.op, static_cast<uint64_t>(sqlite3_value_int64(argv[i])),
104 dataCache_->GetConstProcessMeasureFilterData().IdsData());
105 break;
106 case Index::INTERNAL_PID:
107 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
108 dataCache_->GetConstProcessMeasureFilterData().UpidsData());
109 break;
110 case Index::NAME:
111 indexMap_->MixRange(c.op,
112 dataCache_->GetConstDataIndex(
113 std::string(reinterpret_cast<const char*>(sqlite3_value_text(argv[i])))),
114 dataCache_->GetConstProcessMeasureFilterData().NamesData());
115 break;
116 default:
117 break;
118 }
119 }
120
121 auto procMeasureFilterOrderbys = fc.GetOrderBys();
122 for (auto i = procMeasureFilterOrderbys.size(); i > 0;) {
123 i--;
124 switch (static_cast<Index>(procMeasureFilterOrderbys[i].iColumn)) {
125 case Index::ID:
126 indexMap_->SortBy(procMeasureFilterOrderbys[i].desc);
127 break;
128 default:
129 break;
130 }
131 }
132
133 return SQLITE_OK;
134 }
135
Column(int32_t col) const136 int32_t ProcessMeasureFilterTable::Cursor::Column(int32_t col) const
137 {
138 switch (static_cast<Index>(col)) {
139 case Index::ID:
140 sqlite3_result_int64(context_, static_cast<sqlite3_int64>(
141 dataCache_->GetConstProcessMeasureFilterData().IdsData()[CurrentRow()]));
142 break;
143 case Index::TYPE:
144 sqlite3_result_text(context_, "process_measure_filter", STR_DEFAULT_LEN, nullptr);
145 break;
146 case Index::NAME: {
147 size_t strId =
148 static_cast<size_t>(dataCache_->GetConstProcessMeasureFilterData().NamesData()[CurrentRow()]);
149 sqlite3_result_text(context_, dataCache_->GetDataFromDict(strId).c_str(), STR_DEFAULT_LEN, nullptr);
150 break;
151 }
152 case Index::INTERNAL_PID:
153 sqlite3_result_int64(
154 context_,
155 static_cast<sqlite3_int64>(dataCache_->GetConstProcessMeasureFilterData().UpidsData()[CurrentRow()]));
156 break;
157 default:
158 TS_LOGF("Unregistered column : %d", col);
159 break;
160 }
161 return SQLITE_OK;
162 }
GetOrbyes(FilterConstraints & filterfc,EstimatedIndexInfo & filterei)163 void ProcessMeasureFilterTable::GetOrbyes(FilterConstraints& filterfc, EstimatedIndexInfo& filterei)
164 {
165 auto procMeasurefilterOrdbys = filterfc.GetOrderBys();
166 for (auto i = 0; i < procMeasurefilterOrdbys.size(); i++) {
167 switch (static_cast<Index>(procMeasurefilterOrdbys[i].iColumn)) {
168 case Index::ID:
169 break;
170 default: // other columns can be sorted by SQLite
171 filterei.isOrdered = false;
172 break;
173 }
174 }
175 }
176 } // namespace TraceStreamer
177 } // namespace SysTuning
178