• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "index_map.h"
17 
18 #include <algorithm>
19 
20 #include "log.h"
21 
22 namespace SysTuning {
23 namespace TraceStreamer {
IndexMap(TableRowId start,TableRowId end)24 IndexMap::IndexMap(TableRowId start, TableRowId end) : end_(end), current_(start), start_(start) {}
25 
CovertToIndexMap()26 void IndexMap::CovertToIndexMap()
27 {
28     if (converted_) {
29         indexType_ = INDEX_TYPE_OUTER_INDEX;
30         return;
31     }
32     converted_ = true;
33     if (indexType_ == INDEX_TYPE_ID && HasData()) {
34         for (auto i = start_; i < end_; i++) {
35             rowIndex_.push_back(i);
36         }
37         current_ = start_ = 0;
38         end_ = rowIndex_.size();
39     }
40     indexType_ = INDEX_TYPE_OUTER_INDEX;
41     empty_ = false;
42 }
43 
Print()44 void IndexMap::Print()
45 {
46     for (auto itor = rowIndex_.begin(); itor != rowIndex_.end(); itor++) {
47         (void)fprintf(stdout, "%d,", *itor);
48     }
49     (void)fflush(stdout);
50 }
Sort()51 void IndexMap::Sort() {}
52 
Init()53 void IndexMap::Init()
54 {
55     intersectEable_ = HasData();
56 }
HasData() const57 bool IndexMap::HasData() const
58 {
59     return !empty_;
60 }
Intersect(TableRowId start,TableRowId end)61 void IndexMap::Intersect(TableRowId start, TableRowId end)
62 {
63     if (indexType_ == INDEX_TYPE_OUTER_INDEX) {
64         bool changed = false;
65         rowIndexBak_.clear();
66         for (auto i = rowIndex_.begin(); i != rowIndex_.end(); i++) {
67             if (*i >= start && *i < end) {
68                 changed = true;
69                 rowIndexBak_.push_back(*i);
70             }
71         }
72         if (changed) {
73             rowIndex_ = rowIndexBak_;
74         }
75         start_ = current_ = 0;
76         end_ = rowIndex_.size();
77     } else {
78         start_ = std::max(start_, start);
79         end_ = std::min(end_, end);
80         current_ = start_;
81     }
82     empty_ = false;
83 }
84 
Size() const85 size_t IndexMap::Size() const
86 {
87     return end_ - start_;
88 }
89 
Next()90 void IndexMap::Next()
91 {
92     if (desc_) {
93         if (current_ > start_ - 1) {
94             current_--;
95         }
96     } else {
97         if (current_ < end_) {
98             current_++;
99         }
100     }
101 }
FilterId(unsigned char op,sqlite3_value * argv)102 void IndexMap::FilterId(unsigned char op, sqlite3_value *argv)
103 {
104     auto type = sqlite3_value_type(argv);
105     if (type != SQLITE_INTEGER) {
106         // other type consider it NULL
107         Intersect(0, 0);
108         return;
109     }
110     if (HasData()) {
111         CovertToIndexMap();
112     }
113 
114     auto v = static_cast<TableRowId>(sqlite3_value_int64(argv));
115     switch (op) {
116         case SQLITE_INDEX_CONSTRAINT_EQ:
117             Intersect(v, v + 1);
118             break;
119         case SQLITE_INDEX_CONSTRAINT_GE:
120             Intersect(v, end_);
121             break;
122         case SQLITE_INDEX_CONSTRAINT_GT:
123             v++;
124             Intersect(v, end_);
125             break;
126         case SQLITE_INDEX_CONSTRAINT_LE:
127             v++;
128             Intersect(0, v);
129             break;
130         case SQLITE_INDEX_CONSTRAINT_LT:
131             Intersect(0, v);
132             break;
133         default:
134             // can't filter, all rows
135             break;
136     }
137 }
138 
FilterTS(unsigned char op,sqlite3_value * argv,const std::deque<InternalTime> & times)139 void IndexMap::FilterTS(unsigned char op, sqlite3_value *argv, const std::deque<InternalTime> &times)
140 {
141     auto v = static_cast<uint64_t>(sqlite3_value_int64(argv));
142     auto getValue = [](const uint64_t &row) { return row; };
143     switch (op) {
144         case SQLITE_INDEX_CONSTRAINT_EQ:
145             IntersectabcEqual(times, v, getValue);
146             break;
147         case SQLITE_INDEX_CONSTRAINT_GT:
148             v++;
149             [[fallthrough]];
150         case SQLITE_INDEX_CONSTRAINT_GE: {
151             IntersectGreaterEqual(times, v, getValue);
152             break;
153         }
154         case SQLITE_INDEX_CONSTRAINT_LE:
155             v++;
156             [[fallthrough]];
157         case SQLITE_INDEX_CONSTRAINT_LT:
158             IntersectLessEqual(times, v, getValue);
159             break;
160         case SQLITE_INDEX_CONSTRAINT_ISNOTNULL: {
161             RemoveNullElements(times, v);
162             break;
163         }
164         default:
165             break;
166     } // end of switch (op)
167 }
MergeIndexTypeId(IndexMap * other)168 bool IndexMap::MergeIndexTypeId(IndexMap *other)
169 {
170     if (indexType_ != INDEX_TYPE_ID && other->indexType_ != INDEX_TYPE_ID) {
171         return false;
172     }
173     if ((other->start_ >= start_ && other->start_ <= end_) || (start_ >= other->start_ && start_ <= other->end_)) {
174         start_ = std::min(start_, other->start_);
175         end_ = std::max(end_, other->end_);
176     } else if (start_ > other->start_) {
177         this->CovertToIndexMap();
178         other->CovertToIndexMap();
179         const std::vector<TableRowId> b = other->rowIndex_;
180         uint32_t bIndex = 0;
181         uint32_t bSize = b.size();
182         while (bIndex != bSize) {
183             rowIndex_.push_back(b[bIndex]);
184         }
185         start_ = current_ = 0;
186         end_ = rowIndex_.size();
187     } else {
188         this->CovertToIndexMap();
189         other->CovertToIndexMap();
190         std::vector<TableRowId> c = other->rowIndex_;
191         uint32_t aIndex = 0;
192         uint32_t aSize = rowIndex_.size();
193         while (aIndex != aSize) {
194             c.push_back(rowIndex_[aIndex]);
195         }
196         start_ = current_ = 0;
197         end_ = rowIndex_.size();
198     }
199     return true;
200 }
Merge(IndexMap * other)201 bool IndexMap::Merge(IndexMap *other)
202 {
203     TS_CHECK_TRUE_RET(MergeIndexTypeId(other) == false, true);
204     this->CovertToIndexMap();
205     other->CovertToIndexMap();
206     const std::vector<TableRowId> b = other->rowIndex_;
207     const std::vector<TableRowId> &a = rowIndex_;
208     std::vector<TableRowId> c;
209     uint32_t aIndex = 0;
210     uint32_t aSize = a.size();
211     uint32_t bIndex = 0;
212     uint32_t bSize = b.size();
213     while (aIndex != aSize || bIndex != bSize) {
214         if (aIndex == aSize) {
215             while (bIndex != bSize) {
216                 c.push_back(b[bIndex]);
217                 bIndex++;
218             }
219             break;
220         }
221         if (bIndex == bSize) {
222             while (aIndex != aSize) {
223                 c.push_back(a[aIndex]);
224                 bIndex++;
225             }
226             break;
227         }
228         if (a[aIndex] < b[bIndex]) {
229             c.push_back(a[aIndex]);
230             aIndex++;
231         } else if (a[aIndex] == b[bIndex]) {
232             c.push_back(a[aIndex]);
233             aIndex++;
234             bIndex++;
235         } else {
236             c.push_back(b[bIndex]);
237             bIndex++;
238         }
239     }
240     rowIndex_ = c;
241     start_ = current_ = 0;
242     end_ = rowIndex_.size();
243     return true;
244 }
245 
Eof() const246 bool IndexMap::Eof() const
247 {
248     if (desc_) {
249         return current_ <= start_ - 1;
250     } else {
251         return current_ >= end_;
252     }
253 }
254 
CurrentRow() const255 TableRowId IndexMap::CurrentRow() const
256 {
257     auto current = current_;
258     if (indexType_ == INDEX_TYPE_ID) {
259         return current;
260     } else {
261         return rowIndex_[current];
262     }
263 }
264 
SortBy(bool desc)265 void IndexMap::SortBy(bool desc)
266 {
267     if (desc) {
268         current_ = end_ - 1;
269     } else {
270         current_ = start_;
271     }
272     desc_ = desc;
273 }
274 } // namespace TraceStreamer
275 } // namespace SysTuning
276