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 "irq_table.h"
17fb726d48Sopenharmony_ci
18fb726d48Sopenharmony_cinamespace SysTuning {
19fb726d48Sopenharmony_cinamespace TraceStreamer {
20fb726d48Sopenharmony_cienum class Index : int32_t { ID = 0, TS, DURS, CALL_IDS, CAT, NAME, DEPTH, COOKIE_ID, PARENT_ID, ARGSET, FLAG };
21fb726d48Sopenharmony_ciIrqTable::IrqTable(const TraceDataCache *dataCache) : TableBase(dataCache)
22fb726d48Sopenharmony_ci{
23fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("id", "INTEGER"));
24fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("ts", "INTEGER"));
25fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("dur", "INTEGER"));
26fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("callid", "INTEGER"));
27fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("cat", "TEXT"));
28fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("name", "TEXT"));
29fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("depth", "INTEGER"));
30fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("cookie", "INTEGER"));
31fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("parent_id", "INTEGER"));
32fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("argsetid", "INTEGER"));
33fb726d48Sopenharmony_ci    tableColumn_.emplace_back(TableBase::ColumnInfo("flag", "TEXT"));
34fb726d48Sopenharmony_ci    tablePriKey_.emplace_back("callid");
35fb726d48Sopenharmony_ci    tablePriKey_.emplace_back("ts");
36fb726d48Sopenharmony_ci    tablePriKey_.emplace_back("depth");
37fb726d48Sopenharmony_ci}
38fb726d48Sopenharmony_ci
39fb726d48Sopenharmony_ciIrqTable::~IrqTable() {}
40fb726d48Sopenharmony_ci
41fb726d48Sopenharmony_civoid IrqTable::FilterByConstraint(FilterConstraints &irqfc,
42fb726d48Sopenharmony_ci                                  double &irqfilterCost,
43fb726d48Sopenharmony_ci                                  size_t irqrowCount,
44fb726d48Sopenharmony_ci                                  uint32_t irqcurrenti)
45fb726d48Sopenharmony_ci{
46fb726d48Sopenharmony_ci    // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
47fb726d48Sopenharmony_ci    // for loop
48fb726d48Sopenharmony_ci    const auto &irqc = irqfc.GetConstraints()[irqcurrenti];
49fb726d48Sopenharmony_ci    switch (static_cast<Index>(irqc.col)) {
50fb726d48Sopenharmony_ci        case Index::ID: {
51fb726d48Sopenharmony_ci            if (CanFilterId(irqc.op, irqrowCount)) {
52fb726d48Sopenharmony_ci                irqfc.UpdateConstraint(irqcurrenti, true);
53fb726d48Sopenharmony_ci                irqfilterCost += 1; // id can position by 1 step
54fb726d48Sopenharmony_ci            } else {
55fb726d48Sopenharmony_ci                irqfilterCost += irqrowCount; // scan all rows
56fb726d48Sopenharmony_ci            }
57fb726d48Sopenharmony_ci            break;
58fb726d48Sopenharmony_ci        }
59fb726d48Sopenharmony_ci        default:                          // other column
60fb726d48Sopenharmony_ci            irqfilterCost += irqrowCount; // scan all rows
61fb726d48Sopenharmony_ci            break;
62fb726d48Sopenharmony_ci    }
63fb726d48Sopenharmony_ci}
64fb726d48Sopenharmony_ci
65fb726d48Sopenharmony_cistd::unique_ptr<TableBase::Cursor> IrqTable::CreateCursor()
66fb726d48Sopenharmony_ci{
67fb726d48Sopenharmony_ci    return std::make_unique<Cursor>(dataCache_, this);
68fb726d48Sopenharmony_ci}
69fb726d48Sopenharmony_ci
70fb726d48Sopenharmony_ciIrqTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
71fb726d48Sopenharmony_ci    : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstIrqData().Size())),
72fb726d48Sopenharmony_ci      slicesObj_(dataCache->GetConstIrqData())
73fb726d48Sopenharmony_ci{
74fb726d48Sopenharmony_ci}
75fb726d48Sopenharmony_ci
76fb726d48Sopenharmony_ciIrqTable::Cursor::~Cursor() {}
77fb726d48Sopenharmony_ci
78fb726d48Sopenharmony_ciint32_t IrqTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
79fb726d48Sopenharmony_ci{
80fb726d48Sopenharmony_ci    // reset indexMap_
81fb726d48Sopenharmony_ci    indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
82fb726d48Sopenharmony_ci
83fb726d48Sopenharmony_ci    if (rowCount_ <= 0) {
84fb726d48Sopenharmony_ci        return SQLITE_OK;
85fb726d48Sopenharmony_ci    }
86fb726d48Sopenharmony_ci
87fb726d48Sopenharmony_ci    auto &irqCs = fc.GetConstraints();
88fb726d48Sopenharmony_ci    for (size_t i = 0; i < irqCs.size(); i++) {
89fb726d48Sopenharmony_ci        const auto &c = irqCs[i];
90fb726d48Sopenharmony_ci        switch (static_cast<Index>(c.col)) {
91fb726d48Sopenharmony_ci            case Index::ID:
92fb726d48Sopenharmony_ci                FilterId(c.op, argv[i]);
93fb726d48Sopenharmony_ci                break;
94fb726d48Sopenharmony_ci            default:
95fb726d48Sopenharmony_ci                break;
96fb726d48Sopenharmony_ci        }
97fb726d48Sopenharmony_ci    }
98fb726d48Sopenharmony_ci
99fb726d48Sopenharmony_ci    auto irqTableOrderbys = fc.GetOrderBys();
100fb726d48Sopenharmony_ci    for (auto i = irqTableOrderbys.size(); i > 0;) {
101fb726d48Sopenharmony_ci        i--;
102fb726d48Sopenharmony_ci        switch (static_cast<Index>(irqTableOrderbys[i].iColumn)) {
103fb726d48Sopenharmony_ci            case Index::ID:
104fb726d48Sopenharmony_ci                indexMap_->SortBy(irqTableOrderbys[i].desc);
105fb726d48Sopenharmony_ci                break;
106fb726d48Sopenharmony_ci            default:
107fb726d48Sopenharmony_ci                break;
108fb726d48Sopenharmony_ci        }
109fb726d48Sopenharmony_ci    }
110fb726d48Sopenharmony_ci
111fb726d48Sopenharmony_ci    return SQLITE_OK;
112fb726d48Sopenharmony_ci}
113fb726d48Sopenharmony_ci
114fb726d48Sopenharmony_ciint32_t IrqTable::Cursor::Column(int32_t column) const
115fb726d48Sopenharmony_ci{
116fb726d48Sopenharmony_ci    switch (static_cast<Index>(column)) {
117fb726d48Sopenharmony_ci        case Index::ID:
118fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.IdsData()[CurrentRow()]));
119fb726d48Sopenharmony_ci            break;
120fb726d48Sopenharmony_ci        case Index::TS:
121fb726d48Sopenharmony_ci            SetTypeColumnInt64(slicesObj_.TimeStampData()[CurrentRow()], INVALID_UINT64);
122fb726d48Sopenharmony_ci            break;
123fb726d48Sopenharmony_ci        case Index::DURS:
124fb726d48Sopenharmony_ci            SetTypeColumnInt64(slicesObj_.DursData()[CurrentRow()], INVALID_UINT64);
125fb726d48Sopenharmony_ci            break;
126fb726d48Sopenharmony_ci        case Index::CALL_IDS:
127fb726d48Sopenharmony_ci            SetTypeColumnInt64(slicesObj_.CallIds()[CurrentRow()], INVALID_UINT64);
128fb726d48Sopenharmony_ci            break;
129fb726d48Sopenharmony_ci        case Index::CAT: {
130fb726d48Sopenharmony_ci            SetTypeColumnText(slicesObj_.CatsData()[CurrentRow()], INVALID_UINT64);
131fb726d48Sopenharmony_ci            break;
132fb726d48Sopenharmony_ci        }
133fb726d48Sopenharmony_ci        case Index::NAME: {
134fb726d48Sopenharmony_ci            SetTypeColumnText(slicesObj_.NamesData()[CurrentRow()], INVALID_UINT64);
135fb726d48Sopenharmony_ci            break;
136fb726d48Sopenharmony_ci        }
137fb726d48Sopenharmony_ci        case Index::DEPTH:
138fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.Depths()[CurrentRow()]));
139fb726d48Sopenharmony_ci            break;
140fb726d48Sopenharmony_ci        default:
141fb726d48Sopenharmony_ci            HandleTypeColumns(column);
142fb726d48Sopenharmony_ci    }
143fb726d48Sopenharmony_ci    return SQLITE_OK;
144fb726d48Sopenharmony_ci}
145fb726d48Sopenharmony_civoid IrqTable::Cursor::HandleTypeColumns(int32_t column) const
146fb726d48Sopenharmony_ci{
147fb726d48Sopenharmony_ci    switch (static_cast<Index>(column)) {
148fb726d48Sopenharmony_ci        case Index::COOKIE_ID:
149fb726d48Sopenharmony_ci            SetTypeColumnInt64(slicesObj_.Cookies()[CurrentRow()], INVALID_INT64);
150fb726d48Sopenharmony_ci            break;
151fb726d48Sopenharmony_ci        case Index::PARENT_ID: {
152fb726d48Sopenharmony_ci            if (slicesObj_.ParentIdData()[CurrentRow()].has_value()) {
153fb726d48Sopenharmony_ci                sqlite3_result_int64(context_, static_cast<int64_t>(slicesObj_.ParentIdData()[CurrentRow()].value()));
154fb726d48Sopenharmony_ci            }
155fb726d48Sopenharmony_ci            break;
156fb726d48Sopenharmony_ci        }
157fb726d48Sopenharmony_ci        case Index::ARGSET:
158fb726d48Sopenharmony_ci            SetTypeColumnInt64(slicesObj_.ArgSetIdsData()[CurrentRow()], INVALID_UINT32);
159fb726d48Sopenharmony_ci            break;
160fb726d48Sopenharmony_ci        case Index::FLAG:
161fb726d48Sopenharmony_ci            sqlite3_result_text(context_, slicesObj_.Flags()[CurrentRow()].c_str(), STR_DEFAULT_LEN, nullptr);
162fb726d48Sopenharmony_ci            break;
163fb726d48Sopenharmony_ci        default:
164fb726d48Sopenharmony_ci            TS_LOGF("Unregistered column : %d", column);
165fb726d48Sopenharmony_ci            break;
166fb726d48Sopenharmony_ci    }
167fb726d48Sopenharmony_ci}
168fb726d48Sopenharmony_civoid IrqTable::GetOrbyes(FilterConstraints &irqfc, EstimatedIndexInfo &irqei)
169fb726d48Sopenharmony_ci{
170fb726d48Sopenharmony_ci    auto irqorderbys = irqfc.GetOrderBys();
171fb726d48Sopenharmony_ci    for (auto i = 0; i < irqorderbys.size(); i++) {
172fb726d48Sopenharmony_ci        switch (static_cast<Index>(irqorderbys[i].iColumn)) {
173fb726d48Sopenharmony_ci            case Index::ID:
174fb726d48Sopenharmony_ci                break;
175fb726d48Sopenharmony_ci            default: // other columns can be sorted by SQLite
176fb726d48Sopenharmony_ci                irqei.isOrdered = false;
177fb726d48Sopenharmony_ci                break;
178fb726d48Sopenharmony_ci        }
179fb726d48Sopenharmony_ci    }
180fb726d48Sopenharmony_ci}
181fb726d48Sopenharmony_ci} // namespace TraceStreamer
182fb726d48Sopenharmony_ci} // namespace SysTuning
183