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