• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef SRC_TRACE_PROCESSOR_DB_STORAGE_VARIANTS_H_
17 #define SRC_TRACE_PROCESSOR_DB_STORAGE_VARIANTS_H_
18 
19 #include <variant>
20 #include "perfetto/ext/base/status_or.h"
21 #include "src/trace_processor/db/column.h"
22 #include "src/trace_processor/db/storage.h"
23 
24 namespace perfetto {
25 namespace trace_processor {
26 namespace column {
27 
28 // All viable numeric values for ColumnTypes.
29 using NumericValue = std::variant<uint32_t, int32_t, int64_t, double_t>;
30 
31 // Using the fact that binary operators in std are operators() of classes, we
32 // can wrap those classes in variants and use them for std::visit in
33 // SerialComparators. This helps prevent excess templating and switches.
34 template <typename T>
35 using FilterOpVariant = std::variant<std::greater<T>,
36                                      std::greater_equal<T>,
37                                      std::less<T>,
38                                      std::less_equal<T>,
39                                      std::equal_to<T>,
40                                      std::not_equal_to<T>>;
41 
42 // Based on SqlValue and ColumnType, casts SqlValue to proper type, returns
43 // std::nullopt if SqlValue can't be cast and should be considered invalid for
44 // comparison.
GetNumericTypeVariant(ColumnType type,SqlValue val)45 inline std::optional<NumericValue> GetNumericTypeVariant(ColumnType type,
46                                                          SqlValue val) {
47   if (val.is_null())
48     return std::nullopt;
49 
50   switch (type) {
51     case ColumnType::kDouble:
52       return val.AsDouble();
53     case ColumnType::kInt64:
54       return val.AsLong();
55     case ColumnType::kInt32:
56       if (val.AsLong() > std::numeric_limits<int32_t>::max() ||
57           val.AsLong() < std::numeric_limits<int32_t>::min())
58         return std::nullopt;
59       return static_cast<int32_t>(val.AsLong());
60     case ColumnType::kUint32:
61       if (val.AsLong() > std::numeric_limits<uint32_t>::max() ||
62           val.AsLong() < std::numeric_limits<uint32_t>::min())
63         return std::nullopt;
64       return static_cast<uint32_t>(val.AsLong());
65     case ColumnType::kString:
66     case ColumnType::kDummy:
67     case ColumnType::kId:
68       return std::nullopt;
69   }
70   PERFETTO_FATAL("For GCC");
71 }
72 
73 // Based on SqlValue and ColumnType, casts SqlValue to proper type, returns
74 // std::nullopt if SqlValue can't be cast and should be considered invalid for
75 // comparison.
GetNumericTypeVariant(ColumnType type)76 inline std::optional<NumericValue> GetNumericTypeVariant(ColumnType type) {
77   return GetNumericTypeVariant(type, SqlValue::Long(0));
78 }
79 
80 // Fetch std binary comparator class based on FilterOp. Can be used in
81 // std::visit for comparison.
82 template <typename T>
GetFilterOpVariant(FilterOp op)83 inline FilterOpVariant<T> GetFilterOpVariant(FilterOp op) {
84   switch (op) {
85     case FilterOp::kEq:
86       return FilterOpVariant<T>(std::equal_to<T>());
87     case FilterOp::kNe:
88       return FilterOpVariant<T>(std::not_equal_to<T>());
89     case FilterOp::kGe:
90       return FilterOpVariant<T>(std::greater_equal<T>());
91     case FilterOp::kGt:
92       return FilterOpVariant<T>(std::greater<T>());
93     case FilterOp::kLe:
94       return FilterOpVariant<T>(std::less_equal<T>());
95     case FilterOp::kLt:
96       return FilterOpVariant<T>(std::less<T>());
97     case FilterOp::kGlob:
98     case FilterOp::kIsNotNull:
99     case FilterOp::kIsNull:
100       PERFETTO_FATAL("Not a valid operation on numeric type.");
101   }
102   PERFETTO_FATAL("For GCC");
103 }
104 
105 }  // namespace column
106 }  // namespace trace_processor
107 }  // namespace perfetto
108 #endif  // SRC_TRACE_PROCESSOR_DB_STORAGE_VARIANTS_H_
109