1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "data_dict_table.h"
17 #include "trace_data_cache.h"
18
19 namespace SysTuning {
20 namespace TraceStreamer {
21 enum class Index : int32_t { ID = 0, STR };
DataDictTable(const TraceDataCache * dataCache)22 DataDictTable::DataDictTable(const TraceDataCache *dataCache) : TableBase(dataCache)
23 {
24 tableColumn_.push_back(TableBase::ColumnInfo("id", "INTEGER"));
25 tableColumn_.push_back(TableBase::ColumnInfo("data", "TEXT"));
26 tablePriKey_.push_back("id");
27 }
28
~DataDictTable()29 DataDictTable::~DataDictTable() {}
30
FilterByConstraint(FilterConstraints & dictfc,double & dictfilterCost,size_t dictrowCount,uint32_t dictcurrenti)31 void DataDictTable::FilterByConstraint(FilterConstraints &dictfc,
32 double &dictfilterCost,
33 size_t dictrowCount,
34 uint32_t dictcurrenti)
35 {
36 // To use the EstimateFilterCost function in the TableBase parent class function to calculate the i-value of each
37 // for loop
38 const auto &dictc = dictfc.GetConstraints()[dictcurrenti];
39 switch (static_cast<Index>(dictc.col)) {
40 case Index::ID: {
41 if (CanFilterId(dictc.op, dictrowCount)) {
42 dictfc.UpdateConstraint(dictcurrenti, true);
43 dictfilterCost += 1; // id can position by 1 step
44 } else {
45 dictfilterCost += dictrowCount; // scan all rows
46 }
47 break;
48 }
49 default: // other column
50 dictfilterCost += dictrowCount; // scan all rows
51 break;
52 }
53 }
54
CreateCursor()55 std::unique_ptr<TableBase::Cursor> DataDictTable::CreateCursor()
56 {
57 return std::make_unique<Cursor>(dataCache_, this);
58 }
59
Cursor(const TraceDataCache * dataCache,TableBase * table)60 DataDictTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
61 : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->DataDictSize()))
62 {
63 }
64
~Cursor()65 DataDictTable::Cursor::~Cursor() {}
66
Filter(const FilterConstraints & fc,sqlite3_value ** argv)67 int32_t DataDictTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
68 {
69 // reset indexMap_
70 indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
71
72 if (rowCount_ <= 0) {
73 return SQLITE_OK;
74 }
75
76 auto &dataDictTabCs = fc.GetConstraints();
77 for (size_t i = 0; i < dataDictTabCs.size(); i++) {
78 const auto &c = dataDictTabCs[i];
79 switch (static_cast<Index>(c.col)) {
80 case Index::ID:
81 FilterId(c.op, argv[i]);
82 break;
83 default:
84 break;
85 }
86 }
87
88 auto dataDictTabOrderbys = fc.GetOrderBys();
89 for (auto i = dataDictTabOrderbys.size(); i > 0;) {
90 i--;
91 switch (static_cast<Index>(dataDictTabOrderbys[i].iColumn)) {
92 case Index::ID:
93 indexMap_->SortBy(dataDictTabOrderbys[i].desc);
94 break;
95 default:
96 break;
97 }
98 }
99
100 return SQLITE_OK;
101 }
102
Column(int32_t col) const103 int32_t DataDictTable::Cursor::Column(int32_t col) const
104 {
105 DataIndex index = static_cast<DataIndex>(CurrentRow());
106 switch (static_cast<Index>(col)) {
107 case Index::ID:
108 sqlite3_result_int64(context_, static_cast<sqlite3_int64>(CurrentRow()));
109 break;
110 case Index::STR:
111 sqlite3_result_text(context_, dataCache_->GetDataFromDict(index).c_str(), STR_DEFAULT_LEN, nullptr);
112 break;
113 default:
114 TS_LOGF("Unknown column %d", col);
115 break;
116 }
117 return SQLITE_OK;
118 }
GetOrbyes(FilterConstraints & dictfc,EstimatedIndexInfo & dictei)119 void DataDictTable::GetOrbyes(FilterConstraints &dictfc, EstimatedIndexInfo &dictei)
120 {
121 auto dictorderbys = dictfc.GetOrderBys();
122 for (auto i = 0; i < dictorderbys.size(); i++) {
123 switch (static_cast<Index>(dictorderbys[i].iColumn)) {
124 case Index::ID:
125 break;
126 default: // other columns can be sorted by SQLite
127 dictei.isOrdered = false;
128 break;
129 }
130 }
131 }
132 } // namespace TraceStreamer
133 } // namespace SysTuning
134