xref: /aosp_15_r20/external/perfetto/src/trace_processor/db/column/range_overlay_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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/range_overlay.h"
18 
19 #include <cstdint>
20 #include <vector>
21 
22 #include "perfetto/trace_processor/basic_types.h"
23 #include "src/trace_processor/containers/bit_vector.h"
24 #include "src/trace_processor/db/column/data_layer.h"
25 #include "src/trace_processor/db/column/fake_storage.h"
26 #include "src/trace_processor/db/column/numeric_storage.h"
27 #include "src/trace_processor/db/column/types.h"
28 #include "src/trace_processor/db/column/utils.h"
29 #include "test/gtest_and_gmock.h"
30 
31 namespace perfetto::trace_processor::column {
32 namespace {
33 
34 using testing::ElementsAre;
35 using testing::IsEmpty;
36 using Range = Range;
37 
38 using Indices = DataLayerChain::Indices;
39 using OrderedIndices = DataLayerChain::OrderedIndices;
40 
TEST(RangeOverlay,SearchSingle)41 TEST(RangeOverlay, SearchSingle) {
42   Range range(3, 8);
43   RangeOverlay storage(&range);
44   auto fake = FakeStorageChain::SearchSubset(
45       8, BitVector{false, false, false, true, false, false, false, false});
46   auto chain = storage.MakeChain(std::move(fake));
47 
48   ASSERT_EQ(chain->SingleSearch(FilterOp::kEq, SqlValue::Long(0u), 0),
49             SingleSearchResult::kMatch);
50   ASSERT_EQ(chain->SingleSearch(FilterOp::kEq, SqlValue::Long(0u), 1),
51             SingleSearchResult::kNoMatch);
52 }
53 
TEST(RangeOverlay,SearchAll)54 TEST(RangeOverlay, SearchAll) {
55   Range range(3, 8);
56   RangeOverlay storage(&range);
57   auto fake = FakeStorageChain::SearchAll(10);
58   auto chain = storage.MakeChain(std::move(fake));
59 
60   auto res = chain->Search(FilterOp::kGe, SqlValue::Long(0u), Range(1, 4));
61   ASSERT_THAT(utils::ToIndexVectorForTests(res), ElementsAre(1u, 2u, 3u));
62 }
63 
TEST(RangeOverlay,SearchNone)64 TEST(RangeOverlay, SearchNone) {
65   Range range(3, 8);
66   RangeOverlay storage(&range);
67   auto fake = FakeStorageChain::SearchNone(10);
68   auto chain = storage.MakeChain(std::move(fake));
69 
70   auto res = chain->Search(FilterOp::kGe, SqlValue::Long(0u), Range(1, 4));
71   ASSERT_THAT(utils::ToIndexVectorForTests(res), IsEmpty());
72 }
73 
TEST(RangeOverlay,SearchLimited)74 TEST(RangeOverlay, SearchLimited) {
75   auto fake = FakeStorageChain::SearchSubset(10, std::vector<uint32_t>{4});
76   Range range(3, 5);
77   RangeOverlay storage(&range);
78   auto chain = storage.MakeChain(std::move(fake));
79 
80   auto res = chain->Search(FilterOp::kGe, SqlValue::Long(0u), Range(0, 2));
81   ASSERT_THAT(utils::ToIndexVectorForTests(res), ElementsAre(1u));
82 }
83 
TEST(RangeOverlay,SearchBitVector)84 TEST(RangeOverlay, SearchBitVector) {
85   auto fake =
86       FakeStorageChain::SearchSubset(8, BitVector({0, 1, 0, 1, 0, 1, 0, 0}));
87   Range range(3, 6);
88   RangeOverlay storage(&range);
89   auto chain = storage.MakeChain(std::move(fake));
90 
91   auto res = chain->Search(FilterOp::kGe, SqlValue::Long(0u), Range(0, 3));
92   ASSERT_THAT(utils::ToIndexVectorForTests(res), ElementsAre(0, 2));
93 }
94 
TEST(RangeOverlay,IndexSearch)95 TEST(RangeOverlay, IndexSearch) {
96   auto fake =
97       FakeStorageChain::SearchSubset(8, BitVector({0, 1, 0, 1, 0, 1, 0, 0}));
98 
99   // {true, false}
100   Range range(3, 5);
101   RangeOverlay storage(&range);
102   auto chain = storage.MakeChain(std::move(fake));
103 
104   // {true, false, true}
105   Indices indices = Indices::CreateWithIndexPayloadForTesting(
106       {0, 1, 0}, Indices::State::kNonmonotonic);
107   chain->IndexSearch(FilterOp::kGe, SqlValue::Long(0u), indices);
108   ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0, 2));
109 }
110 
TEST(RangeOverlay,StableSort)111 TEST(RangeOverlay, StableSort) {
112   std::vector<uint32_t> numeric_data{100, 99, 2, 0, 1};
113   NumericStorage<uint32_t> numeric(&numeric_data, ColumnType::kUint32, false);
114 
115   Range range(2, 4);
116   RangeOverlay storage(&range);
117   auto chain = storage.MakeChain(numeric.MakeChain());
118 
119   std::vector tokens{
120       Token{0, 0},
121       Token{1, 1},
122       Token{2, 2},
123   };
124   chain->StableSort(tokens.data(), tokens.data() + tokens.size(),
125                     SortDirection::kAscending);
126   ASSERT_THAT(utils::ExtractPayloadForTesting(tokens), ElementsAre(1, 2, 0));
127 }
128 
TEST(RangeOverlay,Distinct)129 TEST(RangeOverlay, Distinct) {
130   std::vector<uint32_t> numeric_data{100, 99, 2, 0, 1};
131   NumericStorage<uint32_t> numeric(&numeric_data, ColumnType::kUint32, false);
132 
133   // 99, 2, 0, 1
134   Range range(1, 4);
135   RangeOverlay storage(&range);
136   auto chain = storage.MakeChain(numeric.MakeChain());
137 
138   auto indices = Indices::CreateWithIndexPayloadForTesting(
139       {0, 0, 0}, Indices::State::kNonmonotonic);
140   chain->Distinct(indices);
141   ASSERT_THAT(utils::ExtractPayloadForTesting(indices), ElementsAre(0));
142 }
143 
144 }  // namespace
145 }  // namespace perfetto::trace_processor::column
146