1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ci#include "callstack_table.h" 17fb726d48Sopenharmony_ci 18fb726d48Sopenharmony_cinamespace SysTuning { 19fb726d48Sopenharmony_cinamespace TraceStreamer { 20fb726d48Sopenharmony_cienum class Index : int32_t { 21fb726d48Sopenharmony_ci ID = 0, 22fb726d48Sopenharmony_ci TS, 23fb726d48Sopenharmony_ci DURS, 24fb726d48Sopenharmony_ci CALL_IDS, 25fb726d48Sopenharmony_ci CATS, 26fb726d48Sopenharmony_ci NAME, 27fb726d48Sopenharmony_ci DEPTHS, 28fb726d48Sopenharmony_ci COOKIES_ID, 29fb726d48Sopenharmony_ci#if IS_WASM 30fb726d48Sopenharmony_ci COLORINDEX, 31fb726d48Sopenharmony_ci#endif 32fb726d48Sopenharmony_ci PARENT_ID, 33fb726d48Sopenharmony_ci ARGSET, 34fb726d48Sopenharmony_ci CHAIN_IDS, 35fb726d48Sopenharmony_ci SPAN_IDS, 36fb726d48Sopenharmony_ci PARENT_SPAN_IDS, 37fb726d48Sopenharmony_ci FLAGS 38fb726d48Sopenharmony_ci}; 39fb726d48Sopenharmony_ciCallStackTable::CallStackTable(const TraceDataCache *dataCache) : TableBase(dataCache) 40fb726d48Sopenharmony_ci{ 41fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER")); 42fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER")); 43fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("dur", "INTEGER")); 44fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("callid", "INTEGER")); 45fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("cat", "TEXT")); 46fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT")); 47fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("depth", "INTEGER")); 48fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("cookie", "INTEGER")); 49fb726d48Sopenharmony_ci#if IS_WASM 50fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("colorIndex", "INTEGER")); 51fb726d48Sopenharmony_ci#endif 52fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("parent_id", "INTEGER")); 53fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("argsetid", "INTEGER")); 54fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("chainId", "TEXT")); 55fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("spanId", "TEXT")); 56fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("parentSpanId", "TEXT")); 57fb726d48Sopenharmony_ci tableColumn_.push_back(TableBase::ColumnInfo("flag", "TEXT")); 58fb726d48Sopenharmony_ci tablePriKey_.push_back("callid"); 59fb726d48Sopenharmony_ci tablePriKey_.push_back("ts"); 60fb726d48Sopenharmony_ci tablePriKey_.push_back("depth"); 61fb726d48Sopenharmony_ci} 62fb726d48Sopenharmony_ci 63fb726d48Sopenharmony_ciCallStackTable::~CallStackTable() {} 64fb726d48Sopenharmony_ci 65fb726d48Sopenharmony_civoid CallStackTable::FilterByConstraint(FilterConstraints &callfc, 66fb726d48Sopenharmony_ci double &callfilterCost, 67fb726d48Sopenharmony_ci size_t callrowCount, 68fb726d48Sopenharmony_ci uint32_t callCurrenti) 69fb726d48Sopenharmony_ci{ 70fb726d48Sopenharmony_ci // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each 71fb726d48Sopenharmony_ci // for loop 72fb726d48Sopenharmony_ci const auto &callc = callfc.GetConstraints()[callCurrenti]; 73fb726d48Sopenharmony_ci switch (static_cast<Index>(callc.col)) { 74fb726d48Sopenharmony_ci case Index::ID: { 75fb726d48Sopenharmony_ci if (CanFilterId(callc.op, callrowCount)) { 76fb726d48Sopenharmony_ci callfc.UpdateConstraint(callCurrenti, true); 77fb726d48Sopenharmony_ci callfilterCost += 1; // id can position by 1 step 78fb726d48Sopenharmony_ci } else { 79fb726d48Sopenharmony_ci callfilterCost += callrowCount; // scan all rows 80fb726d48Sopenharmony_ci } 81fb726d48Sopenharmony_ci break; 82fb726d48Sopenharmony_ci } 83fb726d48Sopenharmony_ci default: // other column 84fb726d48Sopenharmony_ci callfilterCost += callrowCount; // scan all rows 85fb726d48Sopenharmony_ci break; 86fb726d48Sopenharmony_ci } 87fb726d48Sopenharmony_ci} 88fb726d48Sopenharmony_ci 89fb726d48Sopenharmony_cistd::unique_ptr<TableBase::Cursor> CallStackTable::CreateCursor() 90fb726d48Sopenharmony_ci{ 91fb726d48Sopenharmony_ci return std::make_unique<Cursor>(dataCache_, this); 92fb726d48Sopenharmony_ci} 93fb726d48Sopenharmony_ci 94fb726d48Sopenharmony_ciCallStackTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table) 95fb726d48Sopenharmony_ci : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstInternalSlicesData().Size())), 96fb726d48Sopenharmony_ci slicesObj_(dataCache->GetConstInternalSlicesData()) 97fb726d48Sopenharmony_ci{ 98fb726d48Sopenharmony_ci} 99fb726d48Sopenharmony_ci 100fb726d48Sopenharmony_ciCallStackTable::Cursor::~Cursor() {} 101fb726d48Sopenharmony_ci 102fb726d48Sopenharmony_ciint32_t CallStackTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv) 103fb726d48Sopenharmony_ci{ 104fb726d48Sopenharmony_ci // reset indexMap_ 105fb726d48Sopenharmony_ci indexMap_ = std::make_unique<IndexMap>(0, rowCount_); 106fb726d48Sopenharmony_ci 107fb726d48Sopenharmony_ci if (rowCount_ <= 0) { 108fb726d48Sopenharmony_ci return SQLITE_OK; 109fb726d48Sopenharmony_ci } 110fb726d48Sopenharmony_ci 111fb726d48Sopenharmony_ci auto callStackTabCs = fc.GetConstraints(); 112fb726d48Sopenharmony_ci std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)}; 113fb726d48Sopenharmony_ci SwapIndexFront(callStackTabCs, sId); 114fb726d48Sopenharmony_ci for (size_t i = 0; i < callStackTabCs.size(); i++) { 115fb726d48Sopenharmony_ci const auto &c = callStackTabCs[i]; 116fb726d48Sopenharmony_ci switch (static_cast<Index>(c.col)) { 117fb726d48Sopenharmony_ci case Index::ID: 118fb726d48Sopenharmony_ci FilterId(c.op, argv[c.idxInaConstraint]); 119fb726d48Sopenharmony_ci break; 120fb726d48Sopenharmony_ci case Index::TS: 121fb726d48Sopenharmony_ci FilterTS(c.op, argv[c.idxInaConstraint], slicesObj_.TimeStampData()); 122fb726d48Sopenharmony_ci break; 123fb726d48Sopenharmony_ci case Index::CALL_IDS: 124fb726d48Sopenharmony_ci indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[c.idxInaConstraint])), 125fb726d48Sopenharmony_ci slicesObj_.CallIds()); 126fb726d48Sopenharmony_ci break; 127fb726d48Sopenharmony_ci case Index::COOKIES_ID: 128fb726d48Sopenharmony_ci indexMap_->MixRange(c.op, static_cast<int64_t>(sqlite3_value_int64(argv[c.idxInaConstraint])), 129fb726d48Sopenharmony_ci slicesObj_.Cookies()); 130fb726d48Sopenharmony_ci break; 131fb726d48Sopenharmony_ci default: 132fb726d48Sopenharmony_ci break; 133fb726d48Sopenharmony_ci } 134fb726d48Sopenharmony_ci } 135fb726d48Sopenharmony_ci 136fb726d48Sopenharmony_ci auto callStackTableOrderbys = fc.GetOrderBys(); 137fb726d48Sopenharmony_ci for (auto i = callStackTableOrderbys.size(); i > 0;) { 138fb726d48Sopenharmony_ci i--; 139fb726d48Sopenharmony_ci switch (static_cast<Index>(callStackTableOrderbys[i].iColumn)) { 140fb726d48Sopenharmony_ci case Index::ID: 141fb726d48Sopenharmony_ci indexMap_->SortBy(callStackTableOrderbys[i].desc); 142fb726d48Sopenharmony_ci break; 143fb726d48Sopenharmony_ci default: 144fb726d48Sopenharmony_ci break; 145fb726d48Sopenharmony_ci } 146fb726d48Sopenharmony_ci } 147fb726d48Sopenharmony_ci 148fb726d48Sopenharmony_ci return SQLITE_OK; 149fb726d48Sopenharmony_ci} 150fb726d48Sopenharmony_ci 151fb726d48Sopenharmony_ciint32_t CallStackTable::Cursor::Column(int32_t col) const 152fb726d48Sopenharmony_ci{ 153fb726d48Sopenharmony_ci switch (static_cast<Index>(col)) { 154fb726d48Sopenharmony_ci case Index::ID: 155fb726d48Sopenharmony_ci sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.IdsData()[CurrentRow()])); 156fb726d48Sopenharmony_ci break; 157fb726d48Sopenharmony_ci case Index::TS: 158fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.TimeStampData()[CurrentRow()], INVALID_UINT64); 159fb726d48Sopenharmony_ci break; 160fb726d48Sopenharmony_ci case Index::DURS: 161fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.DursData()[CurrentRow()], INVALID_UINT64); 162fb726d48Sopenharmony_ci break; 163fb726d48Sopenharmony_ci case Index::CALL_IDS: 164fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.CallIds()[CurrentRow()], INVALID_UINT64); 165fb726d48Sopenharmony_ci break; 166fb726d48Sopenharmony_ci#if IS_WASM 167fb726d48Sopenharmony_ci case Index::COLORINDEX: 168fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.ColorIndexs()[CurrentRow()], INVALID_UINT64); 169fb726d48Sopenharmony_ci break; 170fb726d48Sopenharmony_ci#endif 171fb726d48Sopenharmony_ci case Index::CATS: { 172fb726d48Sopenharmony_ci SetTypeColumnText(slicesObj_.CatsData()[CurrentRow()], INVALID_UINT64); 173fb726d48Sopenharmony_ci break; 174fb726d48Sopenharmony_ci } 175fb726d48Sopenharmony_ci case Index::NAME: { 176fb726d48Sopenharmony_ci SetTypeColumnText(slicesObj_.NamesData()[CurrentRow()], INVALID_UINT64); 177fb726d48Sopenharmony_ci break; 178fb726d48Sopenharmony_ci default: 179fb726d48Sopenharmony_ci HandleTypeColumns(col); 180fb726d48Sopenharmony_ci } 181fb726d48Sopenharmony_ci } 182fb726d48Sopenharmony_ci return SQLITE_OK; 183fb726d48Sopenharmony_ci} 184fb726d48Sopenharmony_civoid CallStackTable::Cursor::HandleTypeColumns(int32_t col) const 185fb726d48Sopenharmony_ci{ 186fb726d48Sopenharmony_ci switch (static_cast<Index>(col)) { 187fb726d48Sopenharmony_ci case Index::DEPTHS: 188fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.Depths()[CurrentRow()], INVALID_UINT64); 189fb726d48Sopenharmony_ci break; 190fb726d48Sopenharmony_ci case Index::COOKIES_ID: 191fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.Cookies()[CurrentRow()], INVALID_INT64); 192fb726d48Sopenharmony_ci break; 193fb726d48Sopenharmony_ci case Index::PARENT_ID: { 194fb726d48Sopenharmony_ci if (slicesObj_.ParentIdData()[CurrentRow()].has_value()) { 195fb726d48Sopenharmony_ci sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.ParentIdData()[CurrentRow()].value())); 196fb726d48Sopenharmony_ci } 197fb726d48Sopenharmony_ci break; 198fb726d48Sopenharmony_ci } 199fb726d48Sopenharmony_ci case Index::ARGSET: 200fb726d48Sopenharmony_ci SetTypeColumnInt64(slicesObj_.ArgSetIdsData()[CurrentRow()], INVALID_UINT32); 201fb726d48Sopenharmony_ci break; 202fb726d48Sopenharmony_ci case Index::CHAIN_IDS: 203fb726d48Sopenharmony_ci SetTypeColumnTextNotEmpty(slicesObj_.ChainIds()[CurrentRow()].empty(), 204fb726d48Sopenharmony_ci slicesObj_.ChainIds()[CurrentRow()].c_str()); 205fb726d48Sopenharmony_ci break; 206fb726d48Sopenharmony_ci case Index::SPAN_IDS: 207fb726d48Sopenharmony_ci SetTypeColumnTextNotEmpty(slicesObj_.SpanIds()[CurrentRow()].empty(), 208fb726d48Sopenharmony_ci slicesObj_.SpanIds()[CurrentRow()].c_str()); 209fb726d48Sopenharmony_ci break; 210fb726d48Sopenharmony_ci case Index::PARENT_SPAN_IDS: 211fb726d48Sopenharmony_ci SetTypeColumnTextNotEmpty(slicesObj_.ParentSpanIds()[CurrentRow()].empty(), 212fb726d48Sopenharmony_ci slicesObj_.ParentSpanIds()[CurrentRow()].c_str()); 213fb726d48Sopenharmony_ci break; 214fb726d48Sopenharmony_ci case Index::FLAGS: 215fb726d48Sopenharmony_ci SetTypeColumnTextNotEmpty(slicesObj_.Flags()[CurrentRow()].empty(), 216fb726d48Sopenharmony_ci slicesObj_.Flags()[CurrentRow()].c_str()); 217fb726d48Sopenharmony_ci break; 218fb726d48Sopenharmony_ci default: 219fb726d48Sopenharmony_ci TS_LOGF("Unregistered column : %d", col); 220fb726d48Sopenharmony_ci break; 221fb726d48Sopenharmony_ci } 222fb726d48Sopenharmony_ci} 223fb726d48Sopenharmony_civoid CallStackTable::GetOrbyes(FilterConstraints &callfc, EstimatedIndexInfo &callei) 224fb726d48Sopenharmony_ci{ 225fb726d48Sopenharmony_ci auto orderbys = callfc.GetOrderBys(); 226fb726d48Sopenharmony_ci for (auto i = 0; i < orderbys.size(); i++) { 227fb726d48Sopenharmony_ci switch (static_cast<Index>(orderbys[i].iColumn)) { 228fb726d48Sopenharmony_ci case Index::ID: 229fb726d48Sopenharmony_ci break; 230fb726d48Sopenharmony_ci default: // other columns can be sorted by SQLite 231fb726d48Sopenharmony_ci callei.isOrdered = false; 232fb726d48Sopenharmony_ci break; 233fb726d48Sopenharmony_ci } 234fb726d48Sopenharmony_ci } 235fb726d48Sopenharmony_ci} 236fb726d48Sopenharmony_ci} // namespace TraceStreamer 237fb726d48Sopenharmony_ci} // namespace SysTuning 238