• 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 "instants_table.h"
17 #include <cmath>
18 
19 namespace SysTuning {
20 namespace TraceStreamer {
21 enum class Index : int32_t { TS = 0, NAME, REF, WAKEUP_FROM, REF_TYPE, VALUE };
InstantsTable(const TraceDataCache * dataCache)22 InstantsTable::InstantsTable(const TraceDataCache* dataCache) : TableBase(dataCache)
23 {
24     tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
25     tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT"));
26     tableColumn_.push_back(TableBase::ColumnInfo("ref", "INTEGER"));
27     tableColumn_.push_back(TableBase::ColumnInfo("wakeup_from", "INTEGER"));
28     tableColumn_.push_back(TableBase::ColumnInfo("ref_type", "TEXT"));
29     tableColumn_.push_back(TableBase::ColumnInfo("value", "REAL"));
30     tablePriKey_.push_back("ts");
31     tablePriKey_.push_back("ref");
32 }
33 
~InstantsTable()34 InstantsTable::~InstantsTable() {}
35 
CreateCursor()36 std::unique_ptr<TableBase::Cursor> InstantsTable::CreateCursor()
37 {
38     return std::make_unique<Cursor>(dataCache_, this);
39 }
40 
Cursor(const TraceDataCache * dataCache,TableBase * table)41 InstantsTable::Cursor::Cursor(const TraceDataCache* dataCache, TableBase* table)
42     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstInstantsData().Size())),
43       InstantsObj_(dataCache->GetConstInstantsData())
44 {
45 }
46 
~Cursor()47 InstantsTable::Cursor::~Cursor() {}
48 
FilterByConstraint(FilterConstraints & instantsfc,double & instantsfilterCost,size_t instantsrowCount,uint32_t instantscurrenti)49 void InstantsTable::FilterByConstraint(FilterConstraints& instantsfc,
50                                        double& instantsfilterCost,
51                                        size_t instantsrowCount,
52                                        uint32_t instantscurrenti)
53 {
54     const auto& instantsc = instantsfc.GetConstraints()[instantscurrenti];
55     switch (static_cast<Index>(instantsc.col)) {
56         case Index::TS: {
57             auto instantsoldRowCount = instantsrowCount;
58             if (CanFilterSorted(instantsc.op, instantsrowCount)) {
59                 instantsfc.UpdateConstraint(instantscurrenti, true);
60                 instantsfilterCost += log2(instantsoldRowCount); // binary search
61             } else {
62                 instantsfilterCost += instantsoldRowCount;
63             }
64             break;
65         }
66         default:                                    // other column
67             instantsfilterCost += instantsrowCount; // scan all rows
68             break;
69     }
70 }
71 
CanFilterSorted(const char op,size_t & instantsRowCnt) const72 bool InstantsTable::CanFilterSorted(const char op, size_t& instantsRowCnt) const
73 {
74     switch (op) {
75         case SQLITE_INDEX_CONSTRAINT_EQ:
76             instantsRowCnt = instantsRowCnt / log2(instantsRowCnt);
77             break;
78         case SQLITE_INDEX_CONSTRAINT_GT:
79         case SQLITE_INDEX_CONSTRAINT_GE:
80         case SQLITE_INDEX_CONSTRAINT_LE:
81         case SQLITE_INDEX_CONSTRAINT_LT:
82             instantsRowCnt = (instantsRowCnt >> 1);
83             break;
84         default:
85             return false;
86     }
87     return true;
88 }
89 
SortOfIndexMap(const FilterConstraints & fc)90 void InstantsTable::Cursor::SortOfIndexMap(const FilterConstraints& fc)
91 {
92     auto orderbys = fc.GetOrderBys();
93     for (auto i = orderbys.size(); i > 0;) {
94         i--;
95         switch (static_cast<Index>(orderbys[i].iColumn)) {
96             case Index::TS:
97                 indexMap_->SortBy(orderbys[i].desc);
98                 break;
99             case Index::NAME:
100                 indexMap_->SortBy(orderbys[i].desc);
101                 break;
102             case Index::REF:
103                 indexMap_->SortBy(orderbys[i].desc);
104                 break;
105             case Index::WAKEUP_FROM:
106                 indexMap_->SortBy(orderbys[i].desc);
107                 break;
108             default:
109                 break;
110         }
111     }
112 }
113 
Filter(const FilterConstraints & fc,sqlite3_value ** argv)114 int32_t InstantsTable::Cursor::Filter(const FilterConstraints& fc, sqlite3_value** argv)
115 {
116     // reset
117     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
118     if (rowCount_ <= 0) {
119         return SQLITE_OK;
120     }
121     auto instantsTabCs = fc.GetConstraints();
122     std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
123     SwapIndexFront(instantsTabCs, sId);
124     for (size_t i = 0; i < instantsTabCs.size(); i++) {
125         const auto& c = instantsTabCs[i];
126         switch (static_cast<Index>(c.col)) {
127             case Index::TS:
128                 FilterTS(c.op, argv[i], InstantsObj_.TimeStampData());
129                 break;
130             case Index::NAME:
131                 indexMap_->MixRange(c.op,
132                                     dataCache_->GetConstDataIndex(
133                                         std::string(reinterpret_cast<const char*>(sqlite3_value_text(argv[i])))),
134                                     InstantsObj_.NameIndexsData());
135                 break;
136             case Index::REF:
137                 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[i])),
138                                     InstantsObj_.InternalTidsData());
139                 break;
140             case Index::WAKEUP_FROM:
141                 indexMap_->MixRange(c.op, static_cast<int64_t>(sqlite3_value_int64(argv[i])),
142                                     InstantsObj_.WakeupFromPidsData());
143                 break;
144             default:
145                 break;
146         }
147     }
148     SortOfIndexMap(fc);
149 
150     return SQLITE_OK;
151 }
152 
Column(int32_t column) const153 int32_t InstantsTable::Cursor::Column(int32_t column) const
154 {
155     size_t stringIdentity = static_cast<size_t>(InstantsObj_.NameIndexsData()[CurrentRow()]);
156     switch (static_cast<Index>(column)) {
157         case Index::TS:
158             sqlite3_result_int64(context_, static_cast<int64_t>(InstantsObj_.TimeStampData()[CurrentRow()]));
159             break;
160         case Index::NAME: {
161             sqlite3_result_text(context_, dataCache_->GetDataFromDict(stringIdentity).c_str(), STR_DEFAULT_LEN,
162                                 nullptr);
163             break;
164         }
165         case Index::REF:
166             sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.InternalTidsData()[CurrentRow()]));
167             break;
168         case Index::WAKEUP_FROM:
169             sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.WakeupFromPidsData()[CurrentRow()]));
170             break;
171         case Index::REF_TYPE: {
172             sqlite3_result_text(context_, "itid", STR_DEFAULT_LEN, nullptr);
173             break;
174         }
175         case Index::VALUE: {
176             sqlite3_result_double(context_, 0.0);
177             break;
178         }
179         default:
180             TS_LOGF("Unregistered column : %d", column);
181             break;
182     }
183     return SQLITE_OK;
184 }
GetOrbyes(FilterConstraints & instantsfc,EstimatedIndexInfo & instantsei)185 void InstantsTable::GetOrbyes(FilterConstraints& instantsfc, EstimatedIndexInfo& instantsei)
186 {
187     // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
188     // for loop
189     auto instantsorderbys = instantsfc.GetOrderBys();
190     for (auto i = 0; i < instantsorderbys.size(); i++) {
191         switch (static_cast<Index>(instantsorderbys[i].iColumn)) {
192             case Index::TS:
193                 break;
194             case Index::NAME:
195                 break;
196             case Index::REF:
197                 break;
198             case Index::WAKEUP_FROM:
199                 break;
200             default: // other columns can be sorted by SQLite
201                 instantsei.isOrdered = false;
202                 break;
203         }
204     }
205 }
206 } // namespace TraceStreamer
207 } // namespace SysTuning
208