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 "dma_fence_table.h"
17 
18 namespace SysTuning {
19 namespace TraceStreamer {
20 enum class Index : int32_t { ID = 0, TS, DURS, CAT, DRIVER, TIMELINE, CONTEXT, SEQNO };
DmaFenceTable(const TraceDataCache *dataCache)21 DmaFenceTable::DmaFenceTable(const TraceDataCache *dataCache) : TableBase(dataCache)
22 {
23     tableColumn_.emplace_back(TableBase::ColumnInfo("id", "INTEGER"));
24     tableColumn_.emplace_back(TableBase::ColumnInfo("ts", "INTEGER"));
25     tableColumn_.emplace_back(TableBase::ColumnInfo("dur", "INTEGER"));
26     tableColumn_.emplace_back(TableBase::ColumnInfo("cat", "TEXT"));
27     tableColumn_.emplace_back(TableBase::ColumnInfo("driver", "TEXT"));
28     tableColumn_.emplace_back(TableBase::ColumnInfo("timeline", "TEXT"));
29     tableColumn_.emplace_back(TableBase::ColumnInfo("context", "INTEGER"));
30     tableColumn_.emplace_back(TableBase::ColumnInfo("seqno", "INTEGER"));
31     tablePriKey_.push_back("id");
32 }
33 
~DmaFenceTable()34 DmaFenceTable::~DmaFenceTable() {}
35 
FilterByConstraint(FilterConstraints &dmaFencefc, double &dmaFencefilterCost, size_t dmaFencerowCount, uint32_t dmaFencecurrenti)36 void DmaFenceTable::FilterByConstraint(FilterConstraints &dmaFencefc,
37                                        double &dmaFencefilterCost,
38                                        size_t dmaFencerowCount,
39                                        uint32_t dmaFencecurrenti)
40 {
41     const auto &dmaFencec = dmaFencefc.GetConstraints()[dmaFencecurrenti];
42     switch (static_cast<Index>(dmaFencec.col)) {
43         case Index::ID: {
44             if (CanFilterId(dmaFencec.op, dmaFencerowCount)) {
45                 dmaFencefc.UpdateConstraint(dmaFencecurrenti, true);
46                 dmaFencefilterCost += 1; // id can position by 1 step
47             } else {
48                 dmaFencefilterCost += dmaFencerowCount; // scan all rows
49             }
50             break;
51         }
52         default:                                    // other column
53             dmaFencefilterCost += dmaFencerowCount; // scan all rows
54             break;
55     }
56 }
57 
CreateCursor()58 std::unique_ptr<TableBase::Cursor> DmaFenceTable::CreateCursor()
59 {
60     return std::make_unique<Cursor>(dataCache_, this);
61 }
62 
Cursor(const TraceDataCache *dataCache, TableBase *table)63 DmaFenceTable::Cursor::Cursor(const TraceDataCache *dataCache, TableBase *table)
64     : TableBase::Cursor(dataCache, table, static_cast<uint32_t>(dataCache->GetConstDmaFenceData().Size())),
65       dmaFenceObj_(dataCache->GetConstDmaFenceData())
66 {
67 }
68 
~Cursor()69 DmaFenceTable::Cursor::~Cursor() {}
70 
Filter(const FilterConstraints &fc, sqlite3_value **argv)71 int32_t DmaFenceTable::Cursor::Filter(const FilterConstraints &fc, sqlite3_value **argv)
72 {
73     // reset indexMap_
74     indexMap_ = std::make_unique<IndexMap>(0, rowCount_);
75 
76     if (rowCount_ <= 0) {
77         return SQLITE_OK;
78     }
79 
80     auto DmaFenceTabCs = fc.GetConstraints();
81     for (size_t i = 0; i < DmaFenceTabCs.size(); i++) {
82         const auto &c = DmaFenceTabCs[i];
83         switch (static_cast<Index>(c.col)) {
84             case Index::ID:
85                 FilterId(c.op, argv[i]);
86                 break;
87             case Index::TS:
88                 FilterTS(c.op, argv[i], dmaFenceObj_.TimelinesData());
89                 break;
90             default:
91                 break;
92         }
93     }
94 
95     auto DmaFenceTabOrderbys = fc.GetOrderBys();
96     for (auto i = DmaFenceTabOrderbys.size(); i > 0;) {
97         i--;
98         switch (static_cast<Index>(DmaFenceTabOrderbys[i].iColumn)) {
99             case Index::ID:
100                 indexMap_->SortBy(DmaFenceTabOrderbys[i].desc);
101                 break;
102             default:
103                 break;
104         }
105     }
106 
107     return SQLITE_OK;
108 }
109 
Column(int32_t column) const110 int32_t DmaFenceTable::Cursor::Column(int32_t column) const
111 {
112     switch (static_cast<Index>(column)) {
113         case Index::ID:
114             sqlite3_result_int64(context_, CurrentRow());
115             break;
116         case Index::TS:
117             SetTypeColumnInt64(dmaFenceObj_.TimeStampData()[CurrentRow()], INVALID_UINT64);
118             break;
119         case Index::DURS:
120             SetTypeColumnInt64(dmaFenceObj_.DursData()[CurrentRow()], INVALID_UINT64);
121             break;
122         case Index::CAT: {
123             SetTypeColumnText(dmaFenceObj_.CatsData()[CurrentRow()], INVALID_UINT64);
124             break;
125         }
126         case Index::DRIVER: {
127             SetTypeColumnText(dmaFenceObj_.DriversData()[CurrentRow()], INVALID_UINT64);
128             break;
129         }
130         case Index::TIMELINE: {
131             SetTypeColumnText(dmaFenceObj_.TimelinesData()[CurrentRow()], INVALID_UINT64);
132             break;
133         }
134         case Index::CONTEXT: {
135             SetTypeColumnInt32(dmaFenceObj_.ContextsData()[CurrentRow()], INVALID_UINT32);
136             break;
137         }
138         case Index::SEQNO: {
139             SetTypeColumnInt32(dmaFenceObj_.SeqnosData()[CurrentRow()], INVALID_UINT32);
140             break;
141         }
142         default:
143             break;
144     }
145     return SQLITE_OK;
146 }
147 
GetOrbyes(FilterConstraints &dmaFencefc, EstimatedIndexInfo &dmaFenceei)148 void DmaFenceTable::GetOrbyes(FilterConstraints &dmaFencefc, EstimatedIndexInfo &dmaFenceei)
149 {
150     auto dmaFenceorderbys = dmaFencefc.GetOrderBys();
151     for (auto i = 0; i < dmaFenceorderbys.size(); i++) {
152         switch (static_cast<Index>(dmaFenceorderbys[i].iColumn)) {
153             case Index::ID:
154                 break;
155             default: // other columns can be sorted by SQLite
156                 dmaFenceei.isOrdered = false;
157                 break;
158         }
159     }
160 }
161 } // namespace TraceStreamer
162 } // namespace SysTuning