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