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 "raw_table.h" 17namespace SysTuning { 18namespace TraceStreamer { 19enum class Index : int32_t { ID = 0, TS, NAME, CPU, INTERNAL_TID }; 20enum RawType { RAW_CPU_IDLE = 1, RAW_SCHED_WAKEUP = 2, RAW_SCHED_WAKING = 3 }; 21uint32_t GetNameIndex(const std::string &name) 22{ 23 if (name == "cpu_idle") { 24 return RAW_CPU_IDLE; 25 } else if (name == "sched_wakeup") { 26 return RAW_SCHED_WAKEUP; 27 } else if (name == "sched_waking") { 28 return RAW_SCHED_WAKING; 29 } else { 30 return INVALID_UINT32; 31 } 32} 33RawTable::RawTable(const TraceDataCache *dataCache) : TableBase(dataCache) 34{ 35 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER")); 36 tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER")); 37 tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT")); 38 tableColumn_.push_back(TableBase::ColumnInfo("cpu", "INTEGER")); 39 tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER")); 40 tablePriKey_.push_back("id"); 41} 42 43RawTable::~RawTable() {} 44 45void RawTable::FilterByConstraint(FilterConstraints &rawfc, 46 double &rawfilterCost, 47 size_t rawrowCount, 48 uint32_t rawcurrenti) 49{ 50 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each 51 // for loop 52 const auto &rawc = rawfc.GetConstraints()[rawcurrenti]; 53 switch (static_cast<Index>(rawc.col)) { 54 case Index::ID: { 55 if (CanFilterId(rawc.op, rawrowCount)) { 56 rawfc.UpdateConstraint(rawcurrenti, true); 57 rawfilterCost += 1; // id can position by 1 step 58 } else { 59 rawfilterCost += rawrowCount; // scan all rows 60 } 61 break; 62 } 63 default: // other column 64 rawfilterCost += rawrowCount; // scan all rows 65 break; 66 } 67} 68 69std::unique_ptr<TableBase::Cursor> RawTable::CreateCursor() 70{ 71 return std::make_unique<Cursor>(dataCache_, this); 72} 73 74RawTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table) 75 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstRawTableData().Size())), 76 rawObj_(dataCache->GetConstRawTableData()) 77{ 78} 79 80RawTable::Cursor::~Cursor() {} 81int32_t RawTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv) 82{ 83 // reset indexMap_ 84 indexMap_ = std::make_unique<IndexMap>(0, rowCount_); 85 86 if (rowCount_ <= 0) { 87 return SQLITE_OK; 88 } 89 90 auto RawTableCs = fc.GetConstraints(); 91 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)}; 92 SwapIndexFront(RawTableCs, sId); 93 for (size_t i = 0; i < RawTableCs.size(); i++) { 94 const auto &c = RawTableCs[i]; 95 switch (static_cast<Index>(c.col)) { 96 case Index::ID: 97 FilterId(c.op, argv[c.idxInaConstraint]); 98 break; 99 case Index::NAME: 100 indexMap_->MixRange(c.op, 101 GetNameIndex(std::string( 102 reinterpret_cast<const char *>(sqlite3_value_text(argv[c.idxInaConstraint])))), 103 rawObj_.NameData()); 104 break; 105 case Index::TS: 106 FilterTS(c.op, argv[c.idxInaConstraint], rawObj_.TimeStampData()); 107 break; 108 case Index::INTERNAL_TID: 109 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[c.idxInaConstraint])), 110 rawObj_.InternalTidsData()); 111 break; 112 default: 113 break; 114 } 115 } 116 117 auto rawTableOrderbys = fc.GetOrderBys(); 118 for (auto i = rawTableOrderbys.size(); i > 0;) { 119 i--; 120 switch (static_cast<Index>(rawTableOrderbys[i].iColumn)) { 121 case Index::ID: 122 indexMap_->SortBy(rawTableOrderbys[i].desc); 123 break; 124 default: 125 break; 126 } 127 } 128 129 return SQLITE_OK; 130} 131 132int32_t RawTable::Cursor::Column(int32_t column) const 133{ 134 switch (static_cast<Index>(column)) { 135 case Index::ID: 136 sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.IdsData()[CurrentRow()])); 137 break; 138 case Index::TS: 139 sqlite3_result_int64(context_, static_cast<int64_t>(rawObj_.TimeStampData()[CurrentRow()])); 140 break; 141 case Index::NAME: { 142 if (rawObj_.NameData()[CurrentRow()] == RAW_CPU_IDLE) { 143 sqlite3_result_text(context_, "cpu_idle", STR_DEFAULT_LEN, nullptr); 144 } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKEUP) { 145 sqlite3_result_text(context_, "sched_wakeup", STR_DEFAULT_LEN, nullptr); 146 } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKING) { 147 sqlite3_result_text(context_, "sched_waking", STR_DEFAULT_LEN, nullptr); 148 } 149 break; 150 } 151 case Index::CPU: 152 sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.CpuData()[CurrentRow()])); 153 break; 154 case Index::INTERNAL_TID: 155 sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.InternalTidsData()[CurrentRow()])); 156 break; 157 default: 158 TS_LOGF("Unregistered column : %d", column); 159 break; 160 } 161 return SQLITE_OK; 162} 163void RawTable::GetOrbyes(FilterConstraints &rawfc, EstimatedIndexInfo &rawei) 164{ 165 auto raworderbys = rawfc.GetOrderBys(); 166 for (auto i = 0; i < raworderbys.size(); i++) { 167 switch (static_cast<Index>(raworderbys[i].iColumn)) { 168 case Index::ID: 169 break; 170 default: // other columns can be sorted by SQLite 171 rawei.isOrdered = false; 172 break; 173 } 174 } 175} 176} // namespace TraceStreamer 177} // namespace SysTuning 178