1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
18 #include "gandiva/selection_vector.h"
24 #include <gtest/gtest.h>
26 #include "arrow/testing/gtest_util.h"
30 class TestSelectionVector
: public ::testing::Test
{
32 virtual void SetUp() { pool_
= arrow::default_memory_pool(); }
34 arrow::MemoryPool
* pool_
;
37 static inline uint32_t RoundUpNumi64(uint32_t value
) { return (value
+ 63) >> 6; }
39 TEST_F(TestSelectionVector
, TestInt16Make
) {
42 // Test with pool allocation
43 std::shared_ptr
<SelectionVector
> selection
;
44 auto status
= SelectionVector::MakeInt16(max_slots
, pool_
, &selection
);
45 EXPECT_EQ(status
.ok(), true) << status
.message();
46 EXPECT_EQ(selection
->GetMaxSlots(), max_slots
);
47 EXPECT_EQ(selection
->GetNumSlots(), 0);
49 // Test with pre-alloced buffer
50 std::shared_ptr
<SelectionVector
> selection2
;
51 auto buffer_len
= max_slots
* sizeof(int16_t);
52 ASSERT_OK_AND_ASSIGN(auto buffer
, arrow::AllocateBuffer(buffer_len
, pool_
));
54 status
= SelectionVector::MakeInt16(max_slots
, std::move(buffer
), &selection2
);
55 EXPECT_EQ(status
.ok(), true) << status
.message();
56 EXPECT_EQ(selection2
->GetMaxSlots(), max_slots
);
57 EXPECT_EQ(selection2
->GetNumSlots(), 0);
60 TEST_F(TestSelectionVector
, TestInt16MakeNegative
) {
63 std::shared_ptr
<SelectionVector
> selection
;
64 auto buffer_len
= max_slots
* sizeof(int16_t);
66 // alloc a buffer that's insufficient.
67 ASSERT_OK_AND_ASSIGN(auto buffer
, arrow::AllocateBuffer(buffer_len
- 16, pool_
));
69 auto status
= SelectionVector::MakeInt16(max_slots
, std::move(buffer
), &selection
);
70 EXPECT_EQ(status
.IsInvalid(), true);
73 TEST_F(TestSelectionVector
, TestInt16Set
) {
76 std::shared_ptr
<SelectionVector
> selection
;
77 auto status
= SelectionVector::MakeInt16(max_slots
, pool_
, &selection
);
78 EXPECT_EQ(status
.ok(), true) << status
.message();
80 selection
->SetIndex(0, 100);
81 EXPECT_EQ(selection
->GetIndex(0), 100);
83 selection
->SetIndex(1, 200);
84 EXPECT_EQ(selection
->GetIndex(1), 200);
86 selection
->SetNumSlots(2);
87 EXPECT_EQ(selection
->GetNumSlots(), 2);
89 // TopArray() should return an array with 100,200
90 auto array_raw
= selection
->ToArray();
91 const auto& array
= dynamic_cast<const arrow::UInt16Array
&>(*array_raw
);
92 EXPECT_EQ(array
.length(), 2) << array_raw
->ToString();
93 EXPECT_EQ(array
.Value(0), 100) << array_raw
->ToString();
94 EXPECT_EQ(array
.Value(1), 200) << array_raw
->ToString();
97 TEST_F(TestSelectionVector
, TestInt16PopulateFromBitMap
) {
100 std::shared_ptr
<SelectionVector
> selection
;
101 auto status
= SelectionVector::MakeInt16(max_slots
, pool_
, &selection
);
102 EXPECT_EQ(status
.ok(), true) << status
.message();
104 int bitmap_size
= RoundUpNumi64(max_slots
) * 8;
105 std::vector
<uint8_t> bitmap(bitmap_size
);
107 arrow::BitUtil::SetBit(&bitmap
[0], 0);
108 arrow::BitUtil::SetBit(&bitmap
[0], 5);
109 arrow::BitUtil::SetBit(&bitmap
[0], 121);
110 arrow::BitUtil::SetBit(&bitmap
[0], 220);
112 status
= selection
->PopulateFromBitMap(&bitmap
[0], bitmap_size
, max_slots
- 1);
113 EXPECT_EQ(status
.ok(), true) << status
.message();
115 EXPECT_EQ(selection
->GetNumSlots(), 3);
116 EXPECT_EQ(selection
->GetIndex(0), 0);
117 EXPECT_EQ(selection
->GetIndex(1), 5);
118 EXPECT_EQ(selection
->GetIndex(2), 121);
121 TEST_F(TestSelectionVector
, TestInt16PopulateFromBitMapNegative
) {
124 std::shared_ptr
<SelectionVector
> selection
;
125 auto status
= SelectionVector::MakeInt16(max_slots
, pool_
, &selection
);
126 EXPECT_EQ(status
.ok(), true) << status
.message();
128 int bitmap_size
= 16;
129 std::vector
<uint8_t> bitmap(bitmap_size
);
131 arrow::BitUtil::SetBit(&bitmap
[0], 0);
132 arrow::BitUtil::SetBit(&bitmap
[0], 1);
133 arrow::BitUtil::SetBit(&bitmap
[0], 2);
135 // The bitmap has three set bits, whereas the selection vector has capacity for only 2.
136 status
= selection
->PopulateFromBitMap(&bitmap
[0], bitmap_size
, 2);
137 EXPECT_EQ(status
.IsInvalid(), true);
140 TEST_F(TestSelectionVector
, TestInt32Set
) {
143 std::shared_ptr
<SelectionVector
> selection
;
144 auto status
= SelectionVector::MakeInt32(max_slots
, pool_
, &selection
);
145 EXPECT_EQ(status
.ok(), true) << status
.message();
147 selection
->SetIndex(0, 100);
148 EXPECT_EQ(selection
->GetIndex(0), 100);
150 selection
->SetIndex(1, 200);
151 EXPECT_EQ(selection
->GetIndex(1), 200);
153 selection
->SetIndex(2, 100000);
154 EXPECT_EQ(selection
->GetIndex(2), 100000);
156 selection
->SetNumSlots(3);
157 EXPECT_EQ(selection
->GetNumSlots(), 3);
159 // TopArray() should return an array with 100,200,100000
160 auto array_raw
= selection
->ToArray();
161 const auto& array
= dynamic_cast<const arrow::UInt32Array
&>(*array_raw
);
162 EXPECT_EQ(array
.length(), 3) << array_raw
->ToString();
163 EXPECT_EQ(array
.Value(0), 100) << array_raw
->ToString();
164 EXPECT_EQ(array
.Value(1), 200) << array_raw
->ToString();
165 EXPECT_EQ(array
.Value(2), 100000) << array_raw
->ToString();
168 TEST_F(TestSelectionVector
, TestInt32PopulateFromBitMap
) {
171 std::shared_ptr
<SelectionVector
> selection
;
172 auto status
= SelectionVector::MakeInt32(max_slots
, pool_
, &selection
);
173 EXPECT_EQ(status
.ok(), true) << status
.message();
175 int bitmap_size
= RoundUpNumi64(max_slots
) * 8;
176 std::vector
<uint8_t> bitmap(bitmap_size
);
178 arrow::BitUtil::SetBit(&bitmap
[0], 0);
179 arrow::BitUtil::SetBit(&bitmap
[0], 5);
180 arrow::BitUtil::SetBit(&bitmap
[0], 121);
181 arrow::BitUtil::SetBit(&bitmap
[0], 220);
183 status
= selection
->PopulateFromBitMap(&bitmap
[0], bitmap_size
, max_slots
- 1);
184 EXPECT_EQ(status
.ok(), true) << status
.message();
186 EXPECT_EQ(selection
->GetNumSlots(), 3);
187 EXPECT_EQ(selection
->GetIndex(0), 0);
188 EXPECT_EQ(selection
->GetIndex(1), 5);
189 EXPECT_EQ(selection
->GetIndex(2), 121);
192 TEST_F(TestSelectionVector
, TestInt32MakeNegative
) {
195 std::shared_ptr
<SelectionVector
> selection
;
196 auto buffer_len
= max_slots
* sizeof(int32_t);
198 // alloc a buffer that's insufficient.
199 ASSERT_OK_AND_ASSIGN(auto buffer
, arrow::AllocateBuffer(buffer_len
- 1, pool_
));
201 auto status
= SelectionVector::MakeInt32(max_slots
, std::move(buffer
), &selection
);
202 EXPECT_EQ(status
.IsInvalid(), true);
205 TEST_F(TestSelectionVector
, TestInt64Set
) {
208 std::shared_ptr
<SelectionVector
> selection
;
209 auto status
= SelectionVector::MakeInt64(max_slots
, pool_
, &selection
);
210 EXPECT_EQ(status
.ok(), true) << status
.message();
212 selection
->SetIndex(0, 100);
213 EXPECT_EQ(selection
->GetIndex(0), 100);
215 selection
->SetIndex(1, 200);
216 EXPECT_EQ(selection
->GetIndex(1), 200);
218 selection
->SetIndex(2, 100000);
219 EXPECT_EQ(selection
->GetIndex(2), 100000);
221 selection
->SetNumSlots(3);
222 EXPECT_EQ(selection
->GetNumSlots(), 3);
224 // TopArray() should return an array with 100,200,100000
225 auto array_raw
= selection
->ToArray();
226 const auto& array
= dynamic_cast<const arrow::UInt64Array
&>(*array_raw
);
227 EXPECT_EQ(array
.length(), 3) << array_raw
->ToString();
228 EXPECT_EQ(array
.Value(0), 100) << array_raw
->ToString();
229 EXPECT_EQ(array
.Value(1), 200) << array_raw
->ToString();
230 EXPECT_EQ(array
.Value(2), 100000) << array_raw
->ToString();
233 TEST_F(TestSelectionVector
, TestInt64PopulateFromBitMap
) {
236 std::shared_ptr
<SelectionVector
> selection
;
237 auto status
= SelectionVector::MakeInt64(max_slots
, pool_
, &selection
);
238 EXPECT_EQ(status
.ok(), true) << status
.message();
240 int bitmap_size
= RoundUpNumi64(max_slots
) * 8;
241 std::vector
<uint8_t> bitmap(bitmap_size
);
243 arrow::BitUtil::SetBit(&bitmap
[0], 0);
244 arrow::BitUtil::SetBit(&bitmap
[0], 5);
245 arrow::BitUtil::SetBit(&bitmap
[0], 121);
246 arrow::BitUtil::SetBit(&bitmap
[0], 220);
248 status
= selection
->PopulateFromBitMap(&bitmap
[0], bitmap_size
, max_slots
- 1);
249 EXPECT_EQ(status
.ok(), true) << status
.message();
251 EXPECT_EQ(selection
->GetNumSlots(), 3);
252 EXPECT_EQ(selection
->GetIndex(0), 0);
253 EXPECT_EQ(selection
->GetIndex(1), 5);
254 EXPECT_EQ(selection
->GetIndex(2), 121);
257 TEST_F(TestSelectionVector
, TestInt64MakeNegative
) {
260 std::shared_ptr
<SelectionVector
> selection
;
261 auto buffer_len
= max_slots
* sizeof(int64_t);
263 // alloc a buffer that's insufficient.
264 ASSERT_OK_AND_ASSIGN(auto buffer
, arrow::AllocateBuffer(buffer_len
- 1, pool_
));
266 auto status
= SelectionVector::MakeInt64(max_slots
, std::move(buffer
), &selection
);
267 EXPECT_EQ(status
.IsInvalid(), true);
270 } // namespace gandiva