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 "measure_table.h"
17 #include <cmath>
18
19 namespace SysTuning {
20 namespace TraceStreamer {
21 enum class Index : int32_t { TYPE = 0, TS, DUR, VALUE, FILTER_ID };
MeasureTable(const TraceDataCache * dataCache)22 MeasureTable::MeasureTable(const TraceDataCache* dataCache) : TableBase(dataCache)
23 {
24 tableColumn_.push_back(TableBase::ColumnInfo("type", "TEXT"));
25 tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
26 tableColumn_.push_back(TableBase::ColumnInfo("dur", "INTEGER"));
27 tableColumn_.push_back(TableBase::ColumnInfo("value", "INTEGER"));
28 tableColumn_.push_back(TableBase::ColumnInfo("filter_id", "INTEGER"));
29 tablePriKey_.push_back("ts");
30 tablePriKey_.push_back("filter_id");
31 }
32
~MeasureTable()33 MeasureTable::~MeasureTable() {}
34
CreateCursor()35 std::unique_ptr<TableBase::Cursor> MeasureTable::CreateCursor()
36 {
37 return std::make_unique<Cursor>(dataCache_, this);
38 }
39
Cursor(const TraceDataCache * dataCache,TableBase * table)40 MeasureTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
41 : TableBase::Cursor(
42 dataCache,
43 table,
44 static_cast<uint32_t>(table->name_ == "measure" || table->name_ == "_measure"
45 ? dataCache->GetConstMeasureData().Size()
46 : (table->name_ == "process_measure" || table->name_ == "_process_measure"
47 ? dataCache->GetConstProcessMeasureData().Size()
48 : dataCache->GetConstSysMemMeasureData().Size()))),
49 measureObj(table->name_ == "measure" || table->name_ == "_measure"
50 ? dataCache->GetConstMeasureData()
51 : (table->name_ == "process_measure" || table->name_ == "_process_measure"
52 ? dataCache->GetConstProcessMeasureData()
53 : dataCache->GetConstSysMemMeasureData()))
54 {
55 }
56
~Cursor()57 MeasureTable::Cursor::~Cursor() {}
58
FilterByConstraint(FilterConstraints & measurefc,double & measurefilterCost,size_t measurerowCount,uint32_t measurecurrenti)59 void MeasureTable::FilterByConstraint(FilterConstraints& measurefc,
60 double& measurefilterCost,
61 size_t measurerowCount,
62 uint32_t measurecurrenti)
63 {
64 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
65 // for loop
66 const auto& measurec = measurefc.GetConstraints()[measurecurrenti];
67 switch (static_cast<Index>(measurec.col)) {
68 case Index::TS: {
69 auto measureoldRowCount = measurerowCount;
70 if (CanFilterSorted(measurec.op, measurerowCount)) {
71 measurefc.UpdateConstraint(measurecurrenti, true);
72 measurefilterCost += log2(measureoldRowCount); // binary search
73 } else {
74 measurefilterCost += measureoldRowCount;
75 }
76 break;
77 }
78 default: // other column
79 measurefilterCost += measurerowCount; // scan all rows
80 break;
81 }
82 }
83
CanFilterSorted(const char op,size_t & measureRowCnt) const84 bool MeasureTable::CanFilterSorted(const char op, size_t& measureRowCnt) const
85 {
86 switch (op) {
87 case SQLITE_INDEX_CONSTRAINT_EQ:
88 measureRowCnt = measureRowCnt / log2(measureRowCnt);
89 break;
90 case SQLITE_INDEX_CONSTRAINT_GT:
91 case SQLITE_INDEX_CONSTRAINT_GE:
92 case SQLITE_INDEX_CONSTRAINT_LE:
93 case SQLITE_INDEX_CONSTRAINT_LT:
94 measureRowCnt = (measureRowCnt >> 1);
95 break;
96 default:
97 return false;
98 }
99 return true;
100 }
101
Filter(const FilterConstraints & fc,sqlite3_value ** argv)102 int32_t MeasureTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
103 {
104 // reset
105 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
106
107 if (rowCount_ <= 0) {
108 return SQLITE_OK;
109 }
110 auto measureTabCs = fc.GetConstraints();
111 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
112 SwapIndexFront(measureTabCs, sId);
113 for (size_t i = 0; i < measureTabCs.size(); i++) {
114 const auto& c = measureTabCs[i];
115 switch (static_cast<Index>(c.col)) {
116 case Index::TS:
117 FilterTS(c.op, argv[i], measureObj.TimeStampData());
118 break;
119 case Index::FILTER_ID:
120 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])), measureObj.FilterIdData());
121 break;
122 default:
123 break;
124 }
125 }
126
127 auto orderbys = fc.GetOrderBys();
128 for (auto i = orderbys.size(); i > 0;) {
129 i--;
130 switch (static_cast<Index>(orderbys[i].iColumn)) {
131 case Index::TS:
132 indexMap_->SortBy(orderbys[i].desc);
133 break;
134 case Index::FILTER_ID:
135 indexMap_->SortBy(orderbys[i].desc);
136 break;
137 default:
138 break;
139 }
140 }
141
142 return SQLITE_OK;
143 }
144
Column(int32_t column) const145 int32_t MeasureTable::Cursor::Column(int32_t column) const
146 {
147 switch (static_cast<Index>(column)) {
148 case Index::TYPE:
149 sqlite3_result_text(context_, "measure", STR_DEFAULT_LEN, nullptr);
150 break;
151 case Index::TS:
152 sqlite3_result_int64(context_, static_cast<int64_t>(measureObj.TimeStampData()[CurrentRow()]));
153 break;
154 case Index::DUR:
155 if (measureObj.DursData()[CurrentRow()] != INVALID_UINT64) {
156 sqlite3_result_int64(context_, static_cast<int64_t>(measureObj.DursData()[CurrentRow()]));
157 }
158 break;
159 case Index::VALUE:
160 sqlite3_result_int64(context_, static_cast<int64_t>(measureObj.ValuesData()[CurrentRow()]));
161 break;
162 case Index::FILTER_ID:
163 sqlite3_result_int64(context_, static_cast<int32_t>(measureObj.FilterIdData()[CurrentRow()]));
164 break;
165 default:
166 TS_LOGF("Unregistered column : %d", column);
167 break;
168 }
169 return SQLITE_OK;
170 }
171
GetOrbyes(FilterConstraints & measurefc,EstimatedIndexInfo & measureei)172 void MeasureTable::GetOrbyes(FilterConstraints& measurefc, EstimatedIndexInfo& measureei)
173 {
174 auto measureorderbys = measurefc.GetOrderBys();
175 for (auto i = 0; i < measureorderbys.size(); i++) {
176 switch (static_cast<Index>(measureorderbys[i].iColumn)) {
177 case Index::TS:
178 break;
179 default: // other columns can be sorted by SQLite
180 measureei.isOrdered = false;
181 break;
182 }
183 }
184 }
185 } // namespace TraceStreamer
186 } // namespace SysTuning
187