• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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         fprintf(stdout, "%d,", *itor);
48     }
49     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 }
Merge(IndexMap * other)168 void IndexMap::Merge(IndexMap* other)
169 {
170     if (indexType_ == INDEX_TYPE_ID && other->indexType_ == INDEX_TYPE_ID) {
171         if ((other->start_ >= start_ && other->start_ <= end_) || (start_ >= other->start_ && start_ <= other->end_)) {
172             start_ = std::min(start_, other->start_);
173             end_ = std::max(end_, other->end_);
174         } else if (start_ > other->start_) {
175             this->CovertToIndexMap();
176             other->CovertToIndexMap();
177             const std::vector<TableRowId> b = other->rowIndex_;
178             uint32_t bIndex = 0;
179             uint32_t bSize = b.size();
180             while (bIndex != bSize) {
181                 rowIndex_.push_back(b[bIndex]);
182             }
183             start_ = current_ = 0;
184             end_ = rowIndex_.size();
185         } else {
186             this->CovertToIndexMap();
187             other->CovertToIndexMap();
188             std::vector<TableRowId> c = other->rowIndex_;
189             uint32_t aIndex = 0;
190             uint32_t aSize = rowIndex_.size();
191             while (aIndex != aSize) {
192                 c.push_back(rowIndex_[aIndex]);
193             }
194             start_ = current_ = 0;
195             end_ = rowIndex_.size();
196         }
197         return;
198     }
199     this->CovertToIndexMap();
200     other->CovertToIndexMap();
201     const std::vector<TableRowId> b = other->rowIndex_;
202     const std::vector<TableRowId>& a = rowIndex_;
203     std::vector<TableRowId> c;
204     uint32_t aIndex = 0;
205     uint32_t aSize = a.size();
206     uint32_t bIndex = 0;
207     uint32_t bSize = b.size();
208     while (aIndex != aSize || bIndex != bSize) {
209         if (aIndex == aSize) {
210             while (bIndex != bSize) {
211                 c.push_back(b[bIndex]);
212                 bIndex++;
213             }
214             break;
215         }
216         if (bIndex == bSize) {
217             while (aIndex != aSize) {
218                 c.push_back(a[aIndex]);
219                 bIndex++;
220             }
221             break;
222         }
223         if (a[aIndex] < b[bIndex]) {
224             c.push_back(a[aIndex]);
225             aIndex++;
226         } else if (a[aIndex] == b[bIndex]) {
227             c.push_back(a[aIndex]);
228             aIndex++;
229             bIndex++;
230         } else {
231             c.push_back(b[bIndex]);
232             bIndex++;
233         }
234     }
235     rowIndex_ = c;
236     start_ = current_ = 0;
237     end_ = rowIndex_.size();
238 }
239 
Eof() const240 bool IndexMap::Eof() const
241 {
242     if (desc_) {
243         return current_ <= start_ - 1;
244     } else {
245         return current_ >= end_;
246     }
247 }
248 
CurrentRow() const249 TableRowId IndexMap::CurrentRow() const
250 {
251     auto current = current_;
252     if (indexType_ == INDEX_TYPE_ID) {
253         return current;
254     } else {
255         return rowIndex_[current];
256     }
257 }
258 
SortBy(bool desc)259 void IndexMap::SortBy(bool desc)
260 {
261     if (desc) {
262         current_ = end_ - 1;
263     } else {
264         current_ = start_;
265     }
266     desc_ = desc;
267 }
268 } // namespace TraceStreamer
269 } // namespace SysTuning
270