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