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