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#ifndef TABLE_INDEX_MAP_H 17fb726d48Sopenharmony_ci#define TABLE_INDEX_MAP_H 18fb726d48Sopenharmony_ci 19fb726d48Sopenharmony_ci#include <cstdint> 20fb726d48Sopenharmony_ci#include <deque> 21fb726d48Sopenharmony_ci#include <functional> 22fb726d48Sopenharmony_ci#include <vector> 23fb726d48Sopenharmony_ci#include "sqlite3.h" 24fb726d48Sopenharmony_ci#include "ts_common.h" 25fb726d48Sopenharmony_ci 26fb726d48Sopenharmony_cinamespace SysTuning { 27fb726d48Sopenharmony_cinamespace TraceStreamer { 28fb726d48Sopenharmony_ciclass IndexMap { 29fb726d48Sopenharmony_cipublic: 30fb726d48Sopenharmony_ci IndexMap() {} 31fb726d48Sopenharmony_ci ~IndexMap() {} 32fb726d48Sopenharmony_ci 33fb726d48Sopenharmony_ci IndexMap(TableRowId start, TableRowId end); 34fb726d48Sopenharmony_ci void ConvertToIndexMap(); 35fb726d48Sopenharmony_ci static void Sort(); 36fb726d48Sopenharmony_ci void Print(); 37fb726d48Sopenharmony_ci void Init(); 38fb726d48Sopenharmony_ci bool Merge(IndexMap *other); 39fb726d48Sopenharmony_ci void FilterId(unsigned char op, sqlite3_value *argv); 40fb726d48Sopenharmony_ci void FilterTS(unsigned char op, sqlite3_value *argv, const std::deque<InternalTime> ×); 41fb726d48Sopenharmony_ci template <class T> 42fb726d48Sopenharmony_ci void ProcessData(const std::deque<T> &dataQueue, 43fb726d48Sopenharmony_ci bool remove, 44fb726d48Sopenharmony_ci std::function<bool(TableRowId)> firstCheck, 45fb726d48Sopenharmony_ci std::function<bool(TableRowId)> scondCheck) 46fb726d48Sopenharmony_ci { 47fb726d48Sopenharmony_ci if (remove) { 48fb726d48Sopenharmony_ci bool changed = false; 49fb726d48Sopenharmony_ci for (const auto &val : rowIndex_) { 50fb726d48Sopenharmony_ci if (!firstCheck(val)) { 51fb726d48Sopenharmony_ci changed = true; 52fb726d48Sopenharmony_ci rowIndexBak_.push_back(val); 53fb726d48Sopenharmony_ci } 54fb726d48Sopenharmony_ci } 55fb726d48Sopenharmony_ci if (changed) { 56fb726d48Sopenharmony_ci rowIndex_ = rowIndexBak_; 57fb726d48Sopenharmony_ci } 58fb726d48Sopenharmony_ci } else { 59fb726d48Sopenharmony_ci for (auto i = 0; i < dataQueue.size(); i++) { 60fb726d48Sopenharmony_ci if (scondCheck(i)) { 61fb726d48Sopenharmony_ci rowIndex_.push_back(i); 62fb726d48Sopenharmony_ci } 63fb726d48Sopenharmony_ci } 64fb726d48Sopenharmony_ci } 65fb726d48Sopenharmony_ci indexType_ = INDEX_TYPE_OUTER_INDEX; 66fb726d48Sopenharmony_ci FixSize(); 67fb726d48Sopenharmony_ci } 68fb726d48Sopenharmony_ci void PrepMixRange(bool &remove) 69fb726d48Sopenharmony_ci { 70fb726d48Sopenharmony_ci filters_++; 71fb726d48Sopenharmony_ci if (HasData()) { 72fb726d48Sopenharmony_ci ConvertToIndexMap(); 73fb726d48Sopenharmony_ci remove = true; 74fb726d48Sopenharmony_ci } 75fb726d48Sopenharmony_ci rowIndexBak_.clear(); 76fb726d48Sopenharmony_ci } 77fb726d48Sopenharmony_ci template <class T> 78fb726d48Sopenharmony_ci void MixRange(unsigned char op, T value, const std::deque<T> &dataQueue) 79fb726d48Sopenharmony_ci { 80fb726d48Sopenharmony_ci auto invalidValue = std::numeric_limits<T>::max(); 81fb726d48Sopenharmony_ci bool remove = false; 82fb726d48Sopenharmony_ci PrepMixRange(remove); 83fb726d48Sopenharmony_ci switch (op) { 84fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_EQ: 85fb726d48Sopenharmony_ci ProcessData( 86fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] != value; }, 87fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] == value; }); 88fb726d48Sopenharmony_ci break; 89fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_NE: 90fb726d48Sopenharmony_ci ProcessData( 91fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] == value; }, 92fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] != value; }); 93fb726d48Sopenharmony_ci break; 94fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_ISNULL: 95fb726d48Sopenharmony_ci ProcessData( 96fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] != invalidValue; }, 97fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] == invalidValue; }); 98fb726d48Sopenharmony_ci break; 99fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: 100fb726d48Sopenharmony_ci ProcessData( 101fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] == invalidValue; }, 102fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] != invalidValue; }); 103fb726d48Sopenharmony_ci break; 104fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GT: 105fb726d48Sopenharmony_ci ProcessData( 106fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] <= value; }, 107fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] > value; }); 108fb726d48Sopenharmony_ci break; 109fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_GE: 110fb726d48Sopenharmony_ci ProcessData( 111fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] < value; }, 112fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] >= value; }); 113fb726d48Sopenharmony_ci break; 114fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LE: 115fb726d48Sopenharmony_ci ProcessData( 116fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] > value; }, 117fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] <= value; }); 118fb726d48Sopenharmony_ci break; 119fb726d48Sopenharmony_ci case SQLITE_INDEX_CONSTRAINT_LT: 120fb726d48Sopenharmony_ci ProcessData( 121fb726d48Sopenharmony_ci dataQueue, remove, [&](TableRowId id) -> bool { return dataQueue[id] >= value; }, 122fb726d48Sopenharmony_ci [&](TableRowId id) -> bool { return dataQueue[id] < value; }); 123fb726d48Sopenharmony_ci break; 124fb726d48Sopenharmony_ci default: 125fb726d48Sopenharmony_ci break; 126fb726d48Sopenharmony_ci } // end of switch (op) 127fb726d48Sopenharmony_ci empty_ = false; 128fb726d48Sopenharmony_ci } 129fb726d48Sopenharmony_ci void FixSize() 130fb726d48Sopenharmony_ci { 131fb726d48Sopenharmony_ci if (indexType_ == INDEX_TYPE_OUTER_INDEX) { 132fb726d48Sopenharmony_ci end_ = rowIndex_.size(); 133fb726d48Sopenharmony_ci current_ = 0; 134fb726d48Sopenharmony_ci } 135fb726d48Sopenharmony_ci } 136fb726d48Sopenharmony_ci void Remove(TableRowId row) 137fb726d48Sopenharmony_ci { 138fb726d48Sopenharmony_ci (void)std::remove(rowIndex_.begin(), rowIndex_.end(), row); 139fb726d48Sopenharmony_ci } 140fb726d48Sopenharmony_ci void Set(TableRowId start, TableRowId end) 141fb726d48Sopenharmony_ci { 142fb726d48Sopenharmony_ci if (indexType_ == INDEX_TYPE_ID) { 143fb726d48Sopenharmony_ci end_ = std::min(end_, end); 144fb726d48Sopenharmony_ci current_ = start_ = std::max(start_, start); 145fb726d48Sopenharmony_ci } 146fb726d48Sopenharmony_ci } 147fb726d48Sopenharmony_ci 148fb726d48Sopenharmony_ci size_t Size() const; 149fb726d48Sopenharmony_ci 150fb726d48Sopenharmony_ci void Next(); 151fb726d48Sopenharmony_ci 152fb726d48Sopenharmony_ci bool Eof() const; 153fb726d48Sopenharmony_ci 154fb726d48Sopenharmony_ci TableRowId CurrentRow() const; 155fb726d48Sopenharmony_ci 156fb726d48Sopenharmony_ci void SortBy(bool desc); 157fb726d48Sopenharmony_ci void Intersect(TableRowId start, TableRowId end); 158fb726d48Sopenharmony_ci 159fb726d48Sopenharmony_ci // the follow functions require that thecolData is sotred 160fb726d48Sopenharmony_ci template <typename Row, typename Val, typename GetV = const Val &(const Row &)> 161fb726d48Sopenharmony_ci void IntersectabcEqual(const std::deque<Row> &rows, Val v, GetV getValue) 162fb726d48Sopenharmony_ci { 163fb726d48Sopenharmony_ci auto start = std::lower_bound(rows.begin() + start_, rows.begin() + end_, v); 164fb726d48Sopenharmony_ci auto end = std::upper_bound(start, rows.begin() + end_, v); 165fb726d48Sopenharmony_ci auto newStart = std::distance(rows.begin(), start); 166fb726d48Sopenharmony_ci auto newEnd = std::distance(rows.begin(), end); 167fb726d48Sopenharmony_ci Intersect(newStart, newEnd); 168fb726d48Sopenharmony_ci return; 169fb726d48Sopenharmony_ci } 170fb726d48Sopenharmony_ci 171fb726d48Sopenharmony_ci template <typename Row, typename Val, typename GetV = const Val &(const Row &)> 172fb726d48Sopenharmony_ci void IntersectGreaterEqual(const std::deque<Row> &rows, Val v, GetV getValue) 173fb726d48Sopenharmony_ci { 174fb726d48Sopenharmony_ci auto start = std::lower_bound(rows.begin() + start_, rows.begin() + end_, v, 175fb726d48Sopenharmony_ci [&](const Row &row, const Val &v) { return v > getValue(row); }); 176fb726d48Sopenharmony_ci auto newStart = std::distance(rows.begin(), start); 177fb726d48Sopenharmony_ci Intersect(newStart, INVALID_INT32); 178fb726d48Sopenharmony_ci return; 179fb726d48Sopenharmony_ci } 180fb726d48Sopenharmony_ci 181fb726d48Sopenharmony_ci template <typename Row, typename Val, typename GetV = const Val &(const Row &)> 182fb726d48Sopenharmony_ci void IntersectLessEqual(const std::deque<Row> &rows, Val v, GetV getValue) 183fb726d48Sopenharmony_ci { 184fb726d48Sopenharmony_ci auto end = std::upper_bound(rows.begin() + start_, rows.begin() + end_, v, 185fb726d48Sopenharmony_ci [&](const Row &row, const Val &v) { return v > getValue(row); }); 186fb726d48Sopenharmony_ci auto newEnd = std::distance(rows.begin(), end); 187fb726d48Sopenharmony_ci Intersect(0, newEnd); 188fb726d48Sopenharmony_ci return; 189fb726d48Sopenharmony_ci } 190fb726d48Sopenharmony_ci template <typename T> 191fb726d48Sopenharmony_ci void RemoveNullElements(const std::deque<T> &rows, T v) 192fb726d48Sopenharmony_ci { 193fb726d48Sopenharmony_ci auto invalidValue = std::numeric_limits<T>::max(); 194fb726d48Sopenharmony_ci bool remove = false; 195fb726d48Sopenharmony_ci if (HasData()) { 196fb726d48Sopenharmony_ci ConvertToIndexMap(); 197fb726d48Sopenharmony_ci remove = true; 198fb726d48Sopenharmony_ci } 199fb726d48Sopenharmony_ci 200fb726d48Sopenharmony_ci if (remove) { 201fb726d48Sopenharmony_ci for (auto i = rowIndex_.begin(); i != rowIndex_.end();) { 202fb726d48Sopenharmony_ci if (rows[*i] == invalidValue) { 203fb726d48Sopenharmony_ci i = rowIndex_.erase(i); 204fb726d48Sopenharmony_ci } else { 205fb726d48Sopenharmony_ci i++; 206fb726d48Sopenharmony_ci } 207fb726d48Sopenharmony_ci } 208fb726d48Sopenharmony_ci } else { 209fb726d48Sopenharmony_ci auto size = rows.size(); 210fb726d48Sopenharmony_ci for (size_t i = 0; i < size; i++) { 211fb726d48Sopenharmony_ci if (rows[i] != invalidValue) { 212fb726d48Sopenharmony_ci rowIndex_.push_back(i); 213fb726d48Sopenharmony_ci } 214fb726d48Sopenharmony_ci } 215fb726d48Sopenharmony_ci empty_ = false; 216fb726d48Sopenharmony_ci } 217fb726d48Sopenharmony_ci indexType_ = INDEX_TYPE_OUTER_INDEX; 218fb726d48Sopenharmony_ci FixSize(); 219fb726d48Sopenharmony_ci return; 220fb726d48Sopenharmony_ci } 221fb726d48Sopenharmony_ci bool HasData() const; 222fb726d48Sopenharmony_ci std::vector<TableRowId> rowIndex_ = {}; 223fb726d48Sopenharmony_ci std::vector<TableRowId> rowIndexBak_ = {}; 224fb726d48Sopenharmony_ci 225fb726d48Sopenharmony_ciprivate: 226fb726d48Sopenharmony_ci bool MergeIndexTypeId(IndexMap *other); 227fb726d48Sopenharmony_ci 228fb726d48Sopenharmony_ciprivate: 229fb726d48Sopenharmony_ci TableRowId end_ = INVALID_INT32; 230fb726d48Sopenharmony_ci TableRowId current_ = 0; 231fb726d48Sopenharmony_ci TableRowId start_ = 0; 232fb726d48Sopenharmony_ci enum FindIndexType { 233fb726d48Sopenharmony_ci INDEX_TYPE_ID, 234fb726d48Sopenharmony_ci INDEX_TYPE_OUTER_INDEX, 235fb726d48Sopenharmony_ci }; 236fb726d48Sopenharmony_ci FindIndexType indexType_ = INDEX_TYPE_ID; 237fb726d48Sopenharmony_ci 238fb726d48Sopenharmony_ci enum IndexType { COMPACT, SPARSE }; 239fb726d48Sopenharmony_ci bool empty_ = true; 240fb726d48Sopenharmony_ci bool desc_ = false; 241fb726d48Sopenharmony_ci bool converted_ = false; 242fb726d48Sopenharmony_ci uint8_t filters_ = 0; 243fb726d48Sopenharmony_ci bool intersectEable_ = false; 244fb726d48Sopenharmony_ci}; 245fb726d48Sopenharmony_ci} // namespace TraceStreamer 246fb726d48Sopenharmony_ci} // namespace SysTuning 247fb726d48Sopenharmony_ci 248fb726d48Sopenharmony_ci#endif // TABLE_INDEX_MAP_H 249