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 "instants_table.h" 17#include <cmath> 18 19namespace SysTuning { 20namespace TraceStreamer { 21enum class Index : int32_t { TS = 0, NAME, REF, WAKEUP_FROM, REF_TYPE, VALUE }; 22InstantsTable::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 34InstantsTable::~InstantsTable() {} 35 36std::unique_ptr<TableBase::Cursor> InstantsTable::CreateCursor() 37{ 38 return std::make_unique<Cursor>(dataCache_, this); 39} 40 41InstantsTable::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 47InstantsTable::Cursor::~Cursor() {} 48 49void 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 72void InstantsTable::Cursor::SortOfIndexMap(const FilterConstraints &fc) 73{ 74 auto orderbys = fc.GetOrderBys(); 75 for (auto i = orderbys.size(); i > 0;) { 76 i--; 77 switch (static_cast<Index>(orderbys[i].iColumn)) { 78 case Index::TS: 79 indexMap_->SortBy(orderbys[i].desc); 80 break; 81 default: 82 break; 83 } 84 } 85} 86 87int32_t InstantsTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv) 88{ 89 // reset 90 indexMap_ = std::make_unique<IndexMap>(0, rowCount_); 91 if (rowCount_ <= 0) { 92 return SQLITE_OK; 93 } 94 auto instantsTabCs = fc.GetConstraints(); 95 std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)}; 96 SwapIndexFront(instantsTabCs, sId); 97 for (size_t i = 0; i < instantsTabCs.size(); i++) { 98 const auto &c = instantsTabCs[i]; 99 switch (static_cast<Index>(c.col)) { 100 case Index::TS: 101 FilterTS(c.op, argv[c.idxInaConstraint], InstantsObj_.TimeStampData()); 102 break; 103 case Index::NAME: 104 indexMap_->MixRange(c.op, 105 dataCache_->GetConstDataIndex(std::string( 106 reinterpret_cast<const char *>(sqlite3_value_text(argv[c.idxInaConstraint])))), 107 InstantsObj_.NameIndexsData()); 108 break; 109 case Index::REF: 110 indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[c.idxInaConstraint])), 111 InstantsObj_.InternalTidsData()); 112 break; 113 case Index::WAKEUP_FROM: 114 indexMap_->MixRange(c.op, static_cast<int64_t>(sqlite3_value_int64(argv[c.idxInaConstraint])), 115 InstantsObj_.WakeupFromPidsData()); 116 break; 117 default: 118 break; 119 } 120 } 121 SortOfIndexMap(fc); 122 123 return SQLITE_OK; 124} 125 126int32_t InstantsTable::Cursor::Column(int32_t column) const 127{ 128 size_t stringIdentity = static_cast<size_t>(InstantsObj_.NameIndexsData()[CurrentRow()]); 129 switch (static_cast<Index>(column)) { 130 case Index::TS: 131 sqlite3_result_int64(context_, static_cast<int64_t>(InstantsObj_.TimeStampData()[CurrentRow()])); 132 break; 133 case Index::NAME: { 134 sqlite3_result_text(context_, dataCache_->GetDataFromDict(stringIdentity).c_str(), STR_DEFAULT_LEN, 135 nullptr); 136 break; 137 } 138 case Index::REF: 139 sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.InternalTidsData()[CurrentRow()])); 140 break; 141 case Index::WAKEUP_FROM: 142 sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.WakeupFromPidsData()[CurrentRow()])); 143 break; 144 case Index::REF_TYPE: { 145 sqlite3_result_text(context_, "itid", STR_DEFAULT_LEN, nullptr); 146 break; 147 } 148 case Index::VALUE: { 149 sqlite3_result_double(context_, 0.0); 150 break; 151 } 152 default: 153 TS_LOGF("Unregistered column : %d", column); 154 break; 155 } 156 return SQLITE_OK; 157} 158void InstantsTable::GetOrbyes(FilterConstraints &instantsfc, EstimatedIndexInfo &instantsei) 159{ 160 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each 161 // for loop 162 auto instantsorderbys = instantsfc.GetOrderBys(); 163 for (auto i = 0; i < instantsorderbys.size(); i++) { 164 switch (static_cast<Index>(instantsorderbys[i].iColumn)) { 165 case Index::TS: 166 break; 167 default: // other columns can be sorted by SQLite 168 instantsei.isOrdered = false; 169 break; 170 } 171 } 172} 173} // namespace TraceStreamer 174} // namespace SysTuning 175