MCPcopy Create free account
hub / github.com/apache/arrow / CheckDecoderClobber

Function CheckDecoderClobber

cpp/src/arrow/util/rle_bitmap_test.cc:146–201  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

144/// @see CheckDecoderValuesChunked
145template <typename Decoder>
146void CheckDecoderClobber(const typename Decoder::RunType& run,
147 const std::vector<bool>& expected, rle_size_t chunk_size = 1,
148 rle_size_t expected_skip = 0) {
149 ARROW_SCOPED_TRACE("chunk_size = ", chunk_size, ", expected_skip = ", expected_skip);
150
151 const auto n_vals = static_cast<rle_size_t>(expected.size());
152 ASSERT_LE(expected_skip, n_vals);
153
154 Decoder decoder(run);
155 const auto advanced = decoder.Advance(expected_skip);
156 ASSERT_EQ(advanced, expected_skip);
157 const auto n_vals_to_decode = n_vals - expected_skip;
158
159 // Output buffer with enough capacity to store a full chunk plus extra bytes as
160 // clobbers/guard to check for out of bounds write.
161 const auto n_bytes = static_cast<size_t>(bit_util::BytesForBits(chunk_size) +
162 bit_util::CeilDiv(n_vals, chunk_size) + 2);
163 // This seed is arbitrary and of little importance. We are simply trying to avoid an
164 // unlikely case where guards have the same pattern in all invocations.
165 const auto out_pattern =
166 MakeRandomBytes(n_bytes, /* seed= */ (chunk_size << 16) ^ expected_skip);
167 auto out = out_pattern;
168
169 rle_size_t n_val_read = 0;
170 rle_size_t out_bit_start = 0;
171 while (n_val_read < n_vals_to_decode) {
172 // Clean output buffer
173 out = out_pattern;
174 const auto want = std::min(chunk_size, n_vals_to_decode - n_val_read);
175 const auto got = decoder.GetBatch(BitmapSpanMut(out.data(), out_bit_start), want);
176 ASSERT_GT(got, 0) << "at pos " << n_val_read; // break on failure
177 EXPECT_EQ(got, want) << "at pos " << n_val_read;
178 // Check that the leading bits have not been modified
179 CheckBitsEqual({.actual = out, .expected = out_pattern, .count = out_bit_start});
180 // Check that the trailing bits have not been modified
181 CheckBitsEqual({
182 .actual = out,
183 .expected = out_pattern,
184 .count = static_cast<rle_size_t>(8 * n_bytes) - (out_bit_start + want),
185 .actual_start_bit = out_bit_start + want,
186 .expected_start_bit = out_bit_start + want,
187 });
188 // Check decoded bits are also correct
189 CheckDecodedBits({
190 .actual = out,
191 .expected = expected,
192 .count = want,
193 .actual_start_bit = out_bit_start,
194 .expected_start_idx = expected_skip + n_val_read,
195 });
196
197 n_val_read += got;
198 ++out_bit_start;
199 EXPECT_EQ(decoder.remaining(), n_vals_to_decode - n_val_read);
200 }
201}
202
203/// All the checks shared by both decoder types.

Callers

nothing calls this directly

Calls 10

BytesForBitsFunction · 0.85
CeilDivFunction · 0.85
MakeRandomBytesFunction · 0.85
CheckBitsEqualFunction · 0.85
CheckDecodedBitsFunction · 0.85
sizeMethod · 0.45
AdvanceMethod · 0.45
GetBatchMethod · 0.45
dataMethod · 0.45
remainingMethod · 0.45

Tested by

no test coverage detected