• 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 "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