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 "raw_table.h"
17fb726d48Sopenharmony_cinamespace SysTuning {
18fb726d48Sopenharmony_cinamespace TraceStreamer {
19fb726d48Sopenharmony_cienum class Index : int32_t { ID = 0, TS, NAME, CPU, INTERNAL_TID };
20fb726d48Sopenharmony_cienum RawType { RAW_CPU_IDLE = 1, RAW_SCHED_WAKEUP = 2, RAW_SCHED_WAKING = 3 };
21fb726d48Sopenharmony_ciuint32_t GetNameIndex(const std::string &name)
22fb726d48Sopenharmony_ci{
23fb726d48Sopenharmony_ci    if (name == "cpu_idle") {
24fb726d48Sopenharmony_ci        return RAW_CPU_IDLE;
25fb726d48Sopenharmony_ci    } else if (name == "sched_wakeup") {
26fb726d48Sopenharmony_ci        return RAW_SCHED_WAKEUP;
27fb726d48Sopenharmony_ci    } else if (name == "sched_waking") {
28fb726d48Sopenharmony_ci        return RAW_SCHED_WAKING;
29fb726d48Sopenharmony_ci    } else {
30fb726d48Sopenharmony_ci        return INVALID_UINT32;
31fb726d48Sopenharmony_ci    }
32fb726d48Sopenharmony_ci}
33fb726d48Sopenharmony_ciRawTable::RawTable(const TraceDataCache *dataCache) : TableBase(dataCache)
34fb726d48Sopenharmony_ci{
35fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
36fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
37fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT"));
38fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("cpu", "INTEGER"));
39fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("itid", "INTEGER"));
40fb726d48Sopenharmony_ci    tablePriKey_.push_back("id");
41fb726d48Sopenharmony_ci}
42fb726d48Sopenharmony_ci
43fb726d48Sopenharmony_ciRawTable::~RawTable() {}
44fb726d48Sopenharmony_ci
45fb726d48Sopenharmony_civoid RawTable::FilterByConstraint(FilterConstraints &rawfc,
46fb726d48Sopenharmony_ci                                  double &rawfilterCost,
47fb726d48Sopenharmony_ci                                  size_t rawrowCount,
48fb726d48Sopenharmony_ci                                  uint32_t rawcurrenti)
49fb726d48Sopenharmony_ci{
50fb726d48Sopenharmony_ci    // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
51fb726d48Sopenharmony_ci    // for loop
52fb726d48Sopenharmony_ci    const auto &rawc = rawfc.GetConstraints()[rawcurrenti];
53fb726d48Sopenharmony_ci    switch (static_cast<Index>(rawc.col)) {
54fb726d48Sopenharmony_ci        case Index::ID: {
55fb726d48Sopenharmony_ci            if (CanFilterId(rawc.op, rawrowCount)) {
56fb726d48Sopenharmony_ci                rawfc.UpdateConstraint(rawcurrenti, true);
57fb726d48Sopenharmony_ci                rawfilterCost += 1; // id can position by 1 step
58fb726d48Sopenharmony_ci            } else {
59fb726d48Sopenharmony_ci                rawfilterCost += rawrowCount; // scan all rows
60fb726d48Sopenharmony_ci            }
61fb726d48Sopenharmony_ci            break;
62fb726d48Sopenharmony_ci        }
63fb726d48Sopenharmony_ci        default:                          // other column
64fb726d48Sopenharmony_ci            rawfilterCost += rawrowCount; // scan all rows
65fb726d48Sopenharmony_ci            break;
66fb726d48Sopenharmony_ci    }
67fb726d48Sopenharmony_ci}
68fb726d48Sopenharmony_ci
69fb726d48Sopenharmony_cistd::unique_ptr<TableBase::Cursor> RawTable::CreateCursor()
70fb726d48Sopenharmony_ci{
71fb726d48Sopenharmony_ci    return std::make_unique<Cursor>(dataCache_, this);
72fb726d48Sopenharmony_ci}
73fb726d48Sopenharmony_ci
74fb726d48Sopenharmony_ciRawTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
75fb726d48Sopenharmony_ci    : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstRawTableData().Size())),
76fb726d48Sopenharmony_ci      rawObj_(dataCache->GetConstRawTableData())
77fb726d48Sopenharmony_ci{
78fb726d48Sopenharmony_ci}
79fb726d48Sopenharmony_ci
80fb726d48Sopenharmony_ciRawTable::Cursor::~Cursor() {}
81fb726d48Sopenharmony_ciint32_t RawTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
82fb726d48Sopenharmony_ci{
83fb726d48Sopenharmony_ci    // reset indexMap_
84fb726d48Sopenharmony_ci    indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
85fb726d48Sopenharmony_ci
86fb726d48Sopenharmony_ci    if (rowCount_ <= 0) {
87fb726d48Sopenharmony_ci        return SQLITE_OK;
88fb726d48Sopenharmony_ci    }
89fb726d48Sopenharmony_ci
90fb726d48Sopenharmony_ci    auto RawTableCs = fc.GetConstraints();
91fb726d48Sopenharmony_ci    std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
92fb726d48Sopenharmony_ci    SwapIndexFront(RawTableCs, sId);
93fb726d48Sopenharmony_ci    for (size_t i = 0; i < RawTableCs.size(); i++) {
94fb726d48Sopenharmony_ci        const auto &c = RawTableCs[i];
95fb726d48Sopenharmony_ci        switch (static_cast<Index>(c.col)) {
96fb726d48Sopenharmony_ci            case Index::ID:
97fb726d48Sopenharmony_ci                FilterId(c.op, argv[c.idxInaConstraint]);
98fb726d48Sopenharmony_ci                break;
99fb726d48Sopenharmony_ci            case Index::NAME:
100fb726d48Sopenharmony_ci                indexMap_->MixRange(c.op,
101fb726d48Sopenharmony_ci                                    GetNameIndex(std::string(
102fb726d48Sopenharmony_ci                                        reinterpret_cast<const char *>(sqlite3_value_text(argv[c.idxInaConstraint])))),
103fb726d48Sopenharmony_ci                                    rawObj_.NameData());
104fb726d48Sopenharmony_ci                break;
105fb726d48Sopenharmony_ci            case Index::TS:
106fb726d48Sopenharmony_ci                FilterTS(c.op, argv[c.idxInaConstraint], rawObj_.TimeStampData());
107fb726d48Sopenharmony_ci                break;
108fb726d48Sopenharmony_ci            case Index::INTERNAL_TID:
109fb726d48Sopenharmony_ci                indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[c.idxInaConstraint])),
110fb726d48Sopenharmony_ci                                    rawObj_.InternalTidsData());
111fb726d48Sopenharmony_ci                break;
112fb726d48Sopenharmony_ci            default:
113fb726d48Sopenharmony_ci                break;
114fb726d48Sopenharmony_ci        }
115fb726d48Sopenharmony_ci    }
116fb726d48Sopenharmony_ci
117fb726d48Sopenharmony_ci    auto rawTableOrderbys = fc.GetOrderBys();
118fb726d48Sopenharmony_ci    for (auto i = rawTableOrderbys.size(); i > 0;) {
119fb726d48Sopenharmony_ci        i--;
120fb726d48Sopenharmony_ci        switch (static_cast<Index>(rawTableOrderbys[i].iColumn)) {
121fb726d48Sopenharmony_ci            case Index::ID:
122fb726d48Sopenharmony_ci                indexMap_->SortBy(rawTableOrderbys[i].desc);
123fb726d48Sopenharmony_ci                break;
124fb726d48Sopenharmony_ci            default:
125fb726d48Sopenharmony_ci                break;
126fb726d48Sopenharmony_ci        }
127fb726d48Sopenharmony_ci    }
128fb726d48Sopenharmony_ci
129fb726d48Sopenharmony_ci    return SQLITE_OK;
130fb726d48Sopenharmony_ci}
131fb726d48Sopenharmony_ci
132fb726d48Sopenharmony_ciint32_t RawTable::Cursor::Column(int32_t column) const
133fb726d48Sopenharmony_ci{
134fb726d48Sopenharmony_ci    switch (static_cast<Index>(column)) {
135fb726d48Sopenharmony_ci        case Index::ID:
136fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.IdsData()[CurrentRow()]));
137fb726d48Sopenharmony_ci            break;
138fb726d48Sopenharmony_ci        case Index::TS:
139fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int64_t>(rawObj_.TimeStampData()[CurrentRow()]));
140fb726d48Sopenharmony_ci            break;
141fb726d48Sopenharmony_ci        case Index::NAME: {
142fb726d48Sopenharmony_ci            if (rawObj_.NameData()[CurrentRow()] == RAW_CPU_IDLE) {
143fb726d48Sopenharmony_ci                sqlite3_result_text(context_, "cpu_idle", STR_DEFAULT_LEN, nullptr);
144fb726d48Sopenharmony_ci            } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKEUP) {
145fb726d48Sopenharmony_ci                sqlite3_result_text(context_, "sched_wakeup", STR_DEFAULT_LEN, nullptr);
146fb726d48Sopenharmony_ci            } else if (rawObj_.NameData()[CurrentRow()] == RAW_SCHED_WAKING) {
147fb726d48Sopenharmony_ci                sqlite3_result_text(context_, "sched_waking", STR_DEFAULT_LEN, nullptr);
148fb726d48Sopenharmony_ci            }
149fb726d48Sopenharmony_ci            break;
150fb726d48Sopenharmony_ci        }
151fb726d48Sopenharmony_ci        case Index::CPU:
152fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.CpuData()[CurrentRow()]));
153fb726d48Sopenharmony_ci            break;
154fb726d48Sopenharmony_ci        case Index::INTERNAL_TID:
155fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int32_t>(rawObj_.InternalTidsData()[CurrentRow()]));
156fb726d48Sopenharmony_ci            break;
157fb726d48Sopenharmony_ci        default:
158fb726d48Sopenharmony_ci            TS_LOGF("Unregistered column : %d", column);
159fb726d48Sopenharmony_ci            break;
160fb726d48Sopenharmony_ci    }
161fb726d48Sopenharmony_ci    return SQLITE_OK;
162fb726d48Sopenharmony_ci}
163fb726d48Sopenharmony_civoid RawTable::GetOrbyes(FilterConstraints &rawfc, EstimatedIndexInfo &rawei)
164fb726d48Sopenharmony_ci{
165fb726d48Sopenharmony_ci    auto raworderbys = rawfc.GetOrderBys();
166fb726d48Sopenharmony_ci    for (auto i = 0; i < raworderbys.size(); i++) {
167fb726d48Sopenharmony_ci        switch (static_cast<Index>(raworderbys[i].iColumn)) {
168fb726d48Sopenharmony_ci            case Index::ID:
169fb726d48Sopenharmony_ci                break;
170fb726d48Sopenharmony_ci            default: // other columns can be sorted by SQLite
171fb726d48Sopenharmony_ci                rawei.isOrdered = false;
172fb726d48Sopenharmony_ci                break;
173fb726d48Sopenharmony_ci        }
174fb726d48Sopenharmony_ci    }
175fb726d48Sopenharmony_ci}
176fb726d48Sopenharmony_ci} // namespace TraceStreamer
177fb726d48Sopenharmony_ci} // namespace SysTuning
178