• 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 
17 #include "src/trace_processor/db/column/utils.h"
18 
19 #include <cmath>
20 #include <cstdint>
21 #include <functional>
22 #include <optional>
23 #include <utility>
24 #include <vector>
25 
26 #include "perfetto/base/logging.h"
27 #include "perfetto/trace_processor/basic_types.h"
28 #include "src/trace_processor/containers/row_map.h"
29 #include "src/trace_processor/db/column/data_layer.h"
30 #include "src/trace_processor/db/column/types.h"
31 
32 namespace perfetto::trace_processor::column::utils {
33 
CompareIntColumnWithDouble(FilterOp op,SqlValue * sql_val)34 SearchValidationResult CompareIntColumnWithDouble(FilterOp op,
35                                                   SqlValue* sql_val) {
36   double double_val = sql_val->AsDouble();
37   if (std::equal_to<>()(
38           double_val, static_cast<double>(static_cast<uint32_t>(double_val)))) {
39     // If double is the same as uint32_t, we should just "cast" the |sql_val|
40     // to be treated as long.
41     *sql_val = SqlValue::Long(static_cast<int64_t>(double_val));
42     return SearchValidationResult::kOk;
43   }
44   // Logic for when the value is a real double.
45   switch (op) {
46     case FilterOp::kEq:
47       return SearchValidationResult::kNoData;
48     case FilterOp::kNe:
49       return SearchValidationResult::kAllData;
50 
51     case FilterOp::kLe:
52     case FilterOp::kGt:
53       *sql_val = SqlValue::Long(static_cast<int64_t>(std::floor(double_val)));
54       return SearchValidationResult::kOk;
55 
56     case FilterOp::kLt:
57     case FilterOp::kGe:
58       *sql_val = SqlValue::Long(static_cast<int64_t>(std::ceil(double_val)));
59       return SearchValidationResult::kOk;
60 
61     case FilterOp::kIsNotNull:
62     case FilterOp::kIsNull:
63     case FilterOp::kGlob:
64     case FilterOp::kRegex:
65       PERFETTO_FATAL("Invalid filter operation");
66   }
67   PERFETTO_FATAL("For GCC");
68 }
69 
ToIndexVectorForTests(RangeOrBitVector & r_or_bv)70 std::vector<uint32_t> ToIndexVectorForTests(RangeOrBitVector& r_or_bv) {
71   RowMap rm;
72   if (r_or_bv.IsBitVector()) {
73     rm = RowMap(std::move(r_or_bv).TakeIfBitVector());
74   } else {
75     Range range = std::move(r_or_bv).TakeIfRange();
76     rm = RowMap(range.start, range.end);
77   }
78   return rm.GetAllIndices();
79 }
80 
ExtractPayloadForTesting(const DataLayerChain::Indices & indices)81 std::vector<uint32_t> ExtractPayloadForTesting(
82     const DataLayerChain::Indices& indices) {
83   std::vector<uint32_t> payload;
84   payload.reserve(indices.tokens.size());
85   for (const auto& token : indices.tokens) {
86     payload.push_back(token.payload);
87   }
88   return payload;
89 }
90 
ExtractPayloadForTesting(std::vector<column::DataLayerChain::SortToken> & tokens)91 std::vector<uint32_t> ExtractPayloadForTesting(
92     std::vector<column::DataLayerChain::SortToken>& tokens) {
93   std::vector<uint32_t> payload;
94   payload.reserve(tokens.size());
95   for (const auto& token : tokens) {
96     payload.push_back(token.payload);
97   }
98   return payload;
99 }
100 
CanReturnEarly(SearchValidationResult res,Range range)101 std::optional<Range> CanReturnEarly(SearchValidationResult res, Range range) {
102   switch (res) {
103     case SearchValidationResult::kOk:
104       return std::nullopt;
105     case SearchValidationResult::kAllData:
106       return range;
107     case SearchValidationResult::kNoData:
108       return Range();
109   }
110   PERFETTO_FATAL("For GCC");
111 }
112 
CanReturnEarly(SearchValidationResult res,uint32_t indices_size)113 std::optional<Range> CanReturnEarly(SearchValidationResult res,
114                                     uint32_t indices_size) {
115   switch (res) {
116     case SearchValidationResult::kOk:
117       return std::nullopt;
118     case SearchValidationResult::kAllData:
119       return Range(0, indices_size);
120     case SearchValidationResult::kNoData:
121       return Range();
122   }
123   PERFETTO_FATAL("For GCC");
124 }
125 
CanReturnEarly(SearchValidationResult res,DataLayerChain::Indices & indices)126 bool CanReturnEarly(SearchValidationResult res,
127                     DataLayerChain::Indices& indices) {
128   switch (res) {
129     case SearchValidationResult::kOk:
130       return false;
131     case SearchValidationResult::kAllData:
132       return true;
133     case SearchValidationResult::kNoData:
134       indices.tokens.clear();
135       return true;
136   }
137   PERFETTO_FATAL("For GCC");
138 }
139 
140 }  // namespace perfetto::trace_processor::column::utils
141