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 "instants_table.h"
17fb726d48Sopenharmony_ci#include <cmath>
18fb726d48Sopenharmony_ci
19fb726d48Sopenharmony_cinamespace SysTuning {
20fb726d48Sopenharmony_cinamespace TraceStreamer {
21fb726d48Sopenharmony_cienum class Index : int32_t { TS = 0, NAME, REF, WAKEUP_FROM, REF_TYPE, VALUE };
22fb726d48Sopenharmony_ciInstantsTable::InstantsTable(const TraceDataCache *dataCache) : TableBase(dataCache)
23fb726d48Sopenharmony_ci{
24fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("ts", "INTEGER"));
25fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("name", "TEXT"));
26fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("ref", "INTEGER"));
27fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("wakeup_from", "INTEGER"));
28fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("ref_type", "TEXT"));
29fb726d48Sopenharmony_ci    tableColumn_.push_back(TableBase::ColumnInfo("value", "REAL"));
30fb726d48Sopenharmony_ci    tablePriKey_.push_back("ts");
31fb726d48Sopenharmony_ci    tablePriKey_.push_back("ref");
32fb726d48Sopenharmony_ci}
33fb726d48Sopenharmony_ci
34fb726d48Sopenharmony_ciInstantsTable::~InstantsTable() {}
35fb726d48Sopenharmony_ci
36fb726d48Sopenharmony_cistd::unique_ptr<TableBase::Cursor> InstantsTable::CreateCursor()
37fb726d48Sopenharmony_ci{
38fb726d48Sopenharmony_ci    return std::make_unique<Cursor>(dataCache_, this);
39fb726d48Sopenharmony_ci}
40fb726d48Sopenharmony_ci
41fb726d48Sopenharmony_ciInstantsTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
42fb726d48Sopenharmony_ci    : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstInstantsData().Size())),
43fb726d48Sopenharmony_ci      InstantsObj_(dataCache->GetConstInstantsData())
44fb726d48Sopenharmony_ci{
45fb726d48Sopenharmony_ci}
46fb726d48Sopenharmony_ci
47fb726d48Sopenharmony_ciInstantsTable::Cursor::~Cursor() {}
48fb726d48Sopenharmony_ci
49fb726d48Sopenharmony_civoid InstantsTable::FilterByConstraint(FilterConstraints &instantsfc,
50fb726d48Sopenharmony_ci                                       double &instantsfilterCost,
51fb726d48Sopenharmony_ci                                       size_t instantsrowCount,
52fb726d48Sopenharmony_ci                                       uint32_t instantscurrenti)
53fb726d48Sopenharmony_ci{
54fb726d48Sopenharmony_ci    const auto &instantsc = instantsfc.GetConstraints()[instantscurrenti];
55fb726d48Sopenharmony_ci    switch (static_cast<Index>(instantsc.col)) {
56fb726d48Sopenharmony_ci        case Index::TS: {
57fb726d48Sopenharmony_ci            auto instantsoldRowCount = instantsrowCount;
58fb726d48Sopenharmony_ci            if (CanFilterSorted(instantsc.op, instantsrowCount)) {
59fb726d48Sopenharmony_ci                instantsfc.UpdateConstraint(instantscurrenti, true);
60fb726d48Sopenharmony_ci                instantsfilterCost += log2(instantsoldRowCount); // binary search
61fb726d48Sopenharmony_ci            } else {
62fb726d48Sopenharmony_ci                instantsfilterCost += instantsoldRowCount;
63fb726d48Sopenharmony_ci            }
64fb726d48Sopenharmony_ci            break;
65fb726d48Sopenharmony_ci        }
66fb726d48Sopenharmony_ci        default:                                    // other column
67fb726d48Sopenharmony_ci            instantsfilterCost += instantsrowCount; // scan all rows
68fb726d48Sopenharmony_ci            break;
69fb726d48Sopenharmony_ci    }
70fb726d48Sopenharmony_ci}
71fb726d48Sopenharmony_ci
72fb726d48Sopenharmony_civoid InstantsTable::Cursor::SortOfIndexMap(const FilterConstraints &fc)
73fb726d48Sopenharmony_ci{
74fb726d48Sopenharmony_ci    auto orderbys = fc.GetOrderBys();
75fb726d48Sopenharmony_ci    for (auto i = orderbys.size(); i > 0;) {
76fb726d48Sopenharmony_ci        i--;
77fb726d48Sopenharmony_ci        switch (static_cast<Index>(orderbys[i].iColumn)) {
78fb726d48Sopenharmony_ci            case Index::TS:
79fb726d48Sopenharmony_ci                indexMap_->SortBy(orderbys[i].desc);
80fb726d48Sopenharmony_ci                break;
81fb726d48Sopenharmony_ci            default:
82fb726d48Sopenharmony_ci                break;
83fb726d48Sopenharmony_ci        }
84fb726d48Sopenharmony_ci    }
85fb726d48Sopenharmony_ci}
86fb726d48Sopenharmony_ci
87fb726d48Sopenharmony_ciint32_t InstantsTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
88fb726d48Sopenharmony_ci{
89fb726d48Sopenharmony_ci    // reset
90fb726d48Sopenharmony_ci    indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
91fb726d48Sopenharmony_ci    if (rowCount_ <= 0) {
92fb726d48Sopenharmony_ci        return SQLITE_OK;
93fb726d48Sopenharmony_ci    }
94fb726d48Sopenharmony_ci    auto instantsTabCs = fc.GetConstraints();
95fb726d48Sopenharmony_ci    std::set<uint32_t> sId = {static_cast<uint32_t>(Index::TS)};
96fb726d48Sopenharmony_ci    SwapIndexFront(instantsTabCs, sId);
97fb726d48Sopenharmony_ci    for (size_t i = 0; i < instantsTabCs.size(); i++) {
98fb726d48Sopenharmony_ci        const auto &c = instantsTabCs[i];
99fb726d48Sopenharmony_ci        switch (static_cast<Index>(c.col)) {
100fb726d48Sopenharmony_ci            case Index::TS:
101fb726d48Sopenharmony_ci                FilterTS(c.op, argv[c.idxInaConstraint], InstantsObj_.TimeStampData());
102fb726d48Sopenharmony_ci                break;
103fb726d48Sopenharmony_ci            case Index::NAME:
104fb726d48Sopenharmony_ci                indexMap_->MixRange(c.op,
105fb726d48Sopenharmony_ci                                    dataCache_->GetConstDataIndex(std::string(
106fb726d48Sopenharmony_ci                                        reinterpret_cast<const char *>(sqlite3_value_text(argv[c.idxInaConstraint])))),
107fb726d48Sopenharmony_ci                                    InstantsObj_.NameIndexsData());
108fb726d48Sopenharmony_ci                break;
109fb726d48Sopenharmony_ci            case Index::REF:
110fb726d48Sopenharmony_ci                indexMap_->MixRange(c.op, static_cast<uint32_t>(sqlite3_value_int(argv[c.idxInaConstraint])),
111fb726d48Sopenharmony_ci                                    InstantsObj_.InternalTidsData());
112fb726d48Sopenharmony_ci                break;
113fb726d48Sopenharmony_ci            case Index::WAKEUP_FROM:
114fb726d48Sopenharmony_ci                indexMap_->MixRange(c.op, static_cast<int64_t>(sqlite3_value_int64(argv[c.idxInaConstraint])),
115fb726d48Sopenharmony_ci                                    InstantsObj_.WakeupFromPidsData());
116fb726d48Sopenharmony_ci                break;
117fb726d48Sopenharmony_ci            default:
118fb726d48Sopenharmony_ci                break;
119fb726d48Sopenharmony_ci        }
120fb726d48Sopenharmony_ci    }
121fb726d48Sopenharmony_ci    SortOfIndexMap(fc);
122fb726d48Sopenharmony_ci
123fb726d48Sopenharmony_ci    return SQLITE_OK;
124fb726d48Sopenharmony_ci}
125fb726d48Sopenharmony_ci
126fb726d48Sopenharmony_ciint32_t InstantsTable::Cursor::Column(int32_t column) const
127fb726d48Sopenharmony_ci{
128fb726d48Sopenharmony_ci    size_t stringIdentity = static_cast<size_t>(InstantsObj_.NameIndexsData()[CurrentRow()]);
129fb726d48Sopenharmony_ci    switch (static_cast<Index>(column)) {
130fb726d48Sopenharmony_ci        case Index::TS:
131fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int64_t>(InstantsObj_.TimeStampData()[CurrentRow()]));
132fb726d48Sopenharmony_ci            break;
133fb726d48Sopenharmony_ci        case Index::NAME: {
134fb726d48Sopenharmony_ci            sqlite3_result_text(context_, dataCache_->GetDataFromDict(stringIdentity).c_str(), STR_DEFAULT_LEN,
135fb726d48Sopenharmony_ci                                nullptr);
136fb726d48Sopenharmony_ci            break;
137fb726d48Sopenharmony_ci        }
138fb726d48Sopenharmony_ci        case Index::REF:
139fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.InternalTidsData()[CurrentRow()]));
140fb726d48Sopenharmony_ci            break;
141fb726d48Sopenharmony_ci        case Index::WAKEUP_FROM:
142fb726d48Sopenharmony_ci            sqlite3_result_int64(context_, static_cast<int32_t>(InstantsObj_.WakeupFromPidsData()[CurrentRow()]));
143fb726d48Sopenharmony_ci            break;
144fb726d48Sopenharmony_ci        case Index::REF_TYPE: {
145fb726d48Sopenharmony_ci            sqlite3_result_text(context_, "itid", STR_DEFAULT_LEN, nullptr);
146fb726d48Sopenharmony_ci            break;
147fb726d48Sopenharmony_ci        }
148fb726d48Sopenharmony_ci        case Index::VALUE: {
149fb726d48Sopenharmony_ci            sqlite3_result_double(context_, 0.0);
150fb726d48Sopenharmony_ci            break;
151fb726d48Sopenharmony_ci        }
152fb726d48Sopenharmony_ci        default:
153fb726d48Sopenharmony_ci            TS_LOGF("Unregistered column : %d", column);
154fb726d48Sopenharmony_ci            break;
155fb726d48Sopenharmony_ci    }
156fb726d48Sopenharmony_ci    return SQLITE_OK;
157fb726d48Sopenharmony_ci}
158fb726d48Sopenharmony_civoid InstantsTable::GetOrbyes(FilterConstraints &instantsfc, EstimatedIndexInfo &instantsei)
159fb726d48Sopenharmony_ci{
160fb726d48Sopenharmony_ci    // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
161fb726d48Sopenharmony_ci    // for loop
162fb726d48Sopenharmony_ci    auto instantsorderbys = instantsfc.GetOrderBys();
163fb726d48Sopenharmony_ci    for (auto i = 0; i < instantsorderbys.size(); i++) {
164fb726d48Sopenharmony_ci        switch (static_cast<Index>(instantsorderbys[i].iColumn)) {
165fb726d48Sopenharmony_ci            case Index::TS:
166fb726d48Sopenharmony_ci                break;
167fb726d48Sopenharmony_ci            default: // other columns can be sorted by SQLite
168fb726d48Sopenharmony_ci                instantsei.isOrdered = false;
169fb726d48Sopenharmony_ci                break;
170fb726d48Sopenharmony_ci        }
171fb726d48Sopenharmony_ci    }
172fb726d48Sopenharmony_ci}
173fb726d48Sopenharmony_ci} // namespace TraceStreamer
174fb726d48Sopenharmony_ci} // namespace SysTuning
175