1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 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 #ifndef TABLE_H 17 #define TABLE_H 18 19 #include <memory> 20 #include <set> 21 #include <string> 22 #include <vector> 23 24 #include "filter_constraints.h" 25 #include "index_map.h" 26 #include "sqlite3.h" 27 #include "trace_data_cache.h" 28 namespace SysTuning { 29 namespace TraceStreamer { 30 class TableBase; 31 using TabTemplate = std::unique_ptr<TableBase> (*)(const TraceDataCache* dataCache); 32 class TableBase : public sqlite3_vtab { 33 public: 34 virtual ~TableBase(); 35 TableBase(const TableBase&) = delete; 36 TableBase& operator=(const TableBase&) = delete; 37 38 template <typename T> TableDeclare(sqlite3 & db,TraceDataCache * dataCache,const std::string & tableName)39 static void TableDeclare(sqlite3& db, TraceDataCache* dataCache, const std::string& tableName) 40 { 41 TableRegister(db, dataCache, tableName, [](const TraceDataCache* cache) { 42 return std::unique_ptr<TableBase>(std::make_unique<T>(cache)); 43 }); 44 dataCache->AppendNewTable(tableName); 45 } 46 std::string CreateTableSql() const; 47 virtual bool CanFilterId(const char op, size_t& rowCount); 48 49 class Cursor : public sqlite3_vtab_cursor { 50 public: 51 Cursor(const TraceDataCache* dataCache, TableBase* table, uint32_t rowCount); 52 virtual ~Cursor(); Reset()53 virtual void Reset() 54 { 55 indexMap_ = std::make_unique<IndexMap>(0, rowCount_); 56 } 57 58 virtual int32_t Next(); 59 60 virtual int32_t Eof(); 61 62 virtual uint32_t CurrentRow() const; 63 virtual void FilterTS(unsigned char op, sqlite3_value* argv, const std::deque<InternalTime>& times); 64 65 virtual int32_t RowId(sqlite3_int64* id); Filter(const FilterConstraints & fc,sqlite3_value ** argv)66 virtual int32_t Filter(const FilterConstraints& fc, sqlite3_value** argv) 67 { 68 Unused(fc); 69 Unused(argv); 70 return 0; 71 } 72 virtual int32_t Column(int32_t n) const = 0; 73 template <typename T1, typename T2> SetTypeColumnInt64(const T1 & data,const T2 & invalidValue)74 void SetTypeColumnInt64(const T1& data, const T2& invalidValue) const 75 { 76 if (data != invalidValue) { 77 sqlite3_result_int64(context_, static_cast<int64_t>(data)); 78 } 79 } 80 template <typename T1, typename T2> SetTypeColumnInt32(const T1 & data,const T2 & invalidValue)81 void SetTypeColumnInt32(const T1& data, const T2& invalidValue) const 82 { 83 if (data != invalidValue) { 84 sqlite3_result_int(context_, static_cast<int32_t>(data)); 85 } 86 } 87 template <typename T> SetTypeColumnInt64NotZero(const T & data)88 void SetTypeColumnInt64NotZero(const T& data) const 89 { 90 if (data) { 91 sqlite3_result_int64(context_, static_cast<int64_t>(data)); 92 } 93 } 94 template <typename T1, typename T2> SetTypeColumnText(const T1 & data,const T2 & invalidValue)95 void SetTypeColumnText(const T1& data, const T2& invalidValue) const 96 { 97 if (data != invalidValue) { 98 sqlite3_result_text(context_, dataCache_->GetDataFromDict(data).c_str(), STR_DEFAULT_LEN, nullptr); 99 } 100 } 101 template <typename T1, typename T2, typename T3> SetTypeColumn(const T1 & data,const T2 & invalidValue,const T3 invalidTypeId)102 void SetTypeColumn(const T1& data, const T2& invalidValue, const T3 invalidTypeId) const 103 { 104 if (data != invalidValue) { 105 sqlite3_result_int64(context_, static_cast<int64_t>(data)); 106 } else { 107 sqlite3_result_int64(context_, static_cast<int64_t>(invalidTypeId)); 108 } 109 } 110 template <typename T1, typename T2> SetTypeColumnTextNotEmpty(const T1 & data,const T2 & dataToString)111 void SetTypeColumnTextNotEmpty(const T1& data, const T2& dataToString) const 112 { 113 if (!data) { 114 sqlite3_result_text(context_, dataToString, STR_DEFAULT_LEN, nullptr); 115 } 116 } 117 virtual void FilterId(unsigned char op, sqlite3_value* argv); 118 virtual void FilterEnd(); SwapIndexFront(std::vector<FilterConstraints::Constraint> & cs,const std::set<uint32_t> & sId)119 void SwapIndexFront(std::vector<FilterConstraints::Constraint>& cs, const std::set<uint32_t>& sId) 120 { 121 uint32_t index = 0; 122 for (size_t i = 0; i < cs.size(); i++) { 123 const auto& c = cs[i]; 124 if (sId.count(c.col)) { 125 std::swap(cs[index], cs[i]); 126 index++; 127 break; 128 } 129 } 130 } 131 132 public: 133 sqlite3_context* context_; 134 TableBase* table_ = nullptr; 135 136 protected: 137 const TraceDataCache* dataCache_; 138 std::unique_ptr<IndexMap> indexMap_; 139 uint32_t rowCount_; 140 }; 141 142 struct ColumnInfo { ColumnInfoColumnInfo143 ColumnInfo(const std::string& name, const std::string& type) : name_(name), type_(type) {} 144 std::string name_; 145 std::string type_; 146 }; 147 148 protected: TableBase(const TraceDataCache * dataCache)149 explicit TableBase(const TraceDataCache* dataCache) : dataCache_(dataCache), cursor_(nullptr) {} 150 151 struct EstimatedIndexInfo { 152 int64_t estimatedRows = 0; 153 double estimatedCost = 0.0; 154 bool isOrdered = false; 155 }; 156 157 static void TableRegister(sqlite3& db, TraceDataCache* cache, const std::string& tableName, TabTemplate tmplate); 158 static void SetModuleCallbacks(sqlite3_module& module, const std::string& tableName); Update(int32_t argc,sqlite3_value ** argv,sqlite3_int64 * pRowid)159 virtual int32_t Update(int32_t argc, sqlite3_value** argv, sqlite3_int64* pRowid) 160 { 161 return SQLITE_READONLY; 162 } 163 164 int32_t BestIndex(sqlite3_index_info* idxInfo); 165 // needs to correspond to Cursor::Filter() FilterByConstraint(FilterConstraints & fc,double & filterCost,size_t rowCount,uint32_t currenti)166 virtual void FilterByConstraint(FilterConstraints& fc, double& filterCost, size_t rowCount, uint32_t currenti) 167 { 168 Unused(fc); 169 Unused(filterCost); 170 Unused(rowCount); 171 Unused(currenti); 172 } 173 GetSize()174 virtual int64_t GetSize() 175 { 176 return -1; 177 } 178 GetOrbyes(FilterConstraints & fc,EstimatedIndexInfo & ei)179 virtual void GetOrbyes(FilterConstraints& fc, EstimatedIndexInfo& ei) 180 { 181 Unused(fc); 182 Unused(ei); 183 } 184 // needs to correspond to Cursor::Filter() 185 virtual void EstimateFilterCost(FilterConstraints& fc, EstimatedIndexInfo& ei); 186 187 virtual std::unique_ptr<Cursor> CreateCursor() = 0; 188 int32_t Open(sqlite3_vtab_cursor** ppCursor); Init(int32_t,const char * const *)189 virtual void Init(int32_t, const char* const*) 190 { 191 return; 192 }; 193 194 public: 195 std::string name_; 196 197 protected: 198 std::vector<ColumnInfo> tableColumn_ = {}; 199 std::vector<std::string> tablePriKey_ = {}; 200 const TraceDataCache* dataCache_; 201 TraceDataCache* wdataCache_ = nullptr; 202 std::unique_ptr<Cursor> cursor_; 203 204 private: 205 uint16_t bestIndexNum_ = 0; 206 int32_t cacheIdxNum_ = 0; 207 FilterConstraints cacheConstraint_; 208 }; 209 } // namespace TraceStreamer 210 } // namespace SysTuning 211 212 #endif // TABLE_H 213