Skip to content

Commit 5fc5bf0

Browse files
committed
Add test for RleBitPackedDecoder::CountUpTo
1 parent 9dd5b89 commit 5fc5bf0

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

cpp/src/arrow/util/rle_encoding_test.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
// From Apache Impala (incubating) as of 2016-01-29
1919

20+
#include <algorithm>
2021
#include <bit>
2122
#include <cstdint>
2223
#include <cstring>
@@ -1196,6 +1197,58 @@ void CheckAdvance(const Array& data, int bit_width) {
11961197
// literal group to a multiple of 8 with zeros, leaving up to 7 extra values.
11971198
}
11981199

1200+
/// Check RleBitPackedDecoder::CountUpTo, which spans multiple runs through the
1201+
/// parser (unlike the per-run decoder CountUpTo).
1202+
///
1203+
/// Nulls are treated as regular data (i.e. their raw value is encoded and
1204+
/// decoded). The counts returned over successive batches are compared against a
1205+
/// naive count over the original data.
1206+
template <typename Type>
1207+
void CheckCountUpTo(const Array& data, int bit_width, typename Type::c_type value) {
1208+
using ArrayType = typename TypeTraits<Type>::ArrayType;
1209+
using value_type = typename Type::c_type;
1210+
1211+
const auto data_size = static_cast<rle_size_t>(data.length());
1212+
const value_type* data_values = static_cast<const ArrayType&>(data).raw_values();
1213+
1214+
ARROW_SCOPED_TRACE("bit_width = ", bit_width, ", data_size = ", data_size,
1215+
", value = ", value);
1216+
1217+
// Encode all values into `buffer`.
1218+
const auto buffer = EncodeTestArray<Type>(data, bit_width);
1219+
1220+
RleBitPackedDecoder<value_type> decoder(buffer.data(), static_cast<int>(buffer.size()),
1221+
bit_width);
1222+
1223+
// Count in a `step` small relative to the data size, so we span many
1224+
// iterations and repeatedly cross run boundaries.
1225+
const rle_size_t step = std::max<rle_size_t>(data_size / 16, 1);
1226+
rle_size_t pos = 0;
1227+
rle_size_t total_matching = 0;
1228+
while (pos < data_size) {
1229+
const auto to_process = std::min(step, data_size - pos);
1230+
const auto res = decoder.CountUpTo(value, to_process);
1231+
ASSERT_EQ(res.processed_count, to_process);
1232+
1233+
// The matching count of this batch must equal a naive count over the data.
1234+
const auto expected =
1235+
std::count(data_values + pos, data_values + pos + to_process, value);
1236+
EXPECT_EQ(res.matching_count, static_cast<rle_size_t>(expected))
1237+
<< "at position " << pos;
1238+
1239+
pos += res.processed_count;
1240+
total_matching += res.matching_count;
1241+
}
1242+
EXPECT_EQ(pos, data_size) << "Total number of values processed is off";
1243+
const auto total_expected = std::count(data_values, data_values + data_size, value);
1244+
EXPECT_EQ(total_matching, static_cast<rle_size_t>(total_expected));
1245+
1246+
// The decoder is exhausted of the values we requested: counting further only
1247+
// yields the padding values the encoder appended to the last literal group.
1248+
const auto res = decoder.CountUpTo(value, data_size);
1249+
EXPECT_LT(res.processed_count, 8);
1250+
}
1251+
11991252
template <typename T>
12001253
struct DataTestRleBitPackedRandomPart {
12011254
using value_type = T;
@@ -1355,6 +1408,15 @@ void DoTestGetBatchSpacedRoundtrip() {
13551408
CheckAdvance<ArrowType>(*array, case_.bit_width);
13561409
CheckAdvance<ArrowType>(*array->Slice(1), case_.bit_width);
13571410

1411+
// Tests for CountUpTo, counting a value present in the data (the first one)
1412+
// and a value that may not be (the max encodable one).
1413+
const auto first = static_cast<T>(
1414+
static_cast<const typename TypeTraits<ArrowType>::ArrayType&>(*array).Value(0));
1415+
const auto max_value = static_cast<T>((T{1} << (case_.bit_width - 1)) - 1);
1416+
CheckCountUpTo<ArrowType>(*array, case_.bit_width, first);
1417+
CheckCountUpTo<ArrowType>(*array, case_.bit_width, max_value);
1418+
CheckCountUpTo<ArrowType>(*array->Slice(1), case_.bit_width, first);
1419+
13581420
// Tests for GetBatchSpaced
13591421
CheckRoundTrip<ArrowType>(*array, case_.bit_width, /* spaced= */ true,
13601422
/* parts= */ 1);

0 commit comments

Comments
 (0)