Skip to content

Commit 98529d6

Browse files
committed
apply review suggestions, factor element-to-byte checks into helper
1 parent f4ee35d commit 98529d6

3 files changed

Lines changed: 31 additions & 47 deletions

File tree

cpp/src/arrow/buffer_builder.h

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
#include "arrow/buffer.h"
2828
#include "arrow/status.h"
2929
#include "arrow/util/bit_util.h"
30-
#include "arrow/util/int_util_overflow.h"
3130
#include "arrow/util/bitmap_generate.h"
3231
#include "arrow/util/bitmap_ops.h"
32+
#include "arrow/util/int_util_overflow.h"
3333
#include "arrow/util/macros.h"
3434
#include "arrow/util/ubsan.h"
3535
#include "arrow/util/visibility.h"
@@ -114,8 +114,8 @@ class ARROW_EXPORT BufferBuilder {
114114
// jemalloc, but significantly better performance when using the system
115115
// allocator. See ARROW-6450 for further discussion
116116
int64_t doubled;
117-
if (ARROW_PREDICT_FALSE(internal::AddWithOverflow(current_capacity, current_capacity,
118-
&doubled))) {
117+
if (ARROW_PREDICT_FALSE(
118+
internal::AddWithOverflow(current_capacity, current_capacity, &doubled))) {
119119
return new_capacity;
120120
}
121121
return std::max(new_capacity, doubled);
@@ -274,21 +274,12 @@ class TypedBufferBuilder<
274274
}
275275

276276
Status Append(const T* values, int64_t num_elements) {
277-
if (ARROW_PREDICT_FALSE(num_elements < 0)) {
278-
return Status::Invalid("Append: negative number of elements");
279-
}
280277
int64_t num_bytes;
281-
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
282-
num_elements, static_cast<int64_t>(sizeof(T)), &num_bytes))) {
283-
return Status::CapacityError("Append: size overflow");
284-
}
278+
ARROW_RETURN_NOT_OK(ElementsToBytes("Append", num_elements, &num_bytes));
285279
return bytes_builder_.Append(reinterpret_cast<const uint8_t*>(values), num_bytes);
286280
}
287281

288282
Status Append(const int64_t num_copies, T value) {
289-
if (ARROW_PREDICT_FALSE(num_copies < 0)) {
290-
return Status::Invalid("Append: negative number of copies");
291-
}
292283
ARROW_RETURN_NOT_OK(Reserve(num_copies));
293284
UnsafeAppend(num_copies, value);
294285
return Status::OK();
@@ -318,38 +309,20 @@ class TypedBufferBuilder<
318309
}
319310

320311
Status Resize(const int64_t new_capacity, bool shrink_to_fit = true) {
321-
if (ARROW_PREDICT_FALSE(new_capacity < 0)) {
322-
return Status::Invalid("Resize: negative capacity");
323-
}
324312
int64_t num_bytes;
325-
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
326-
new_capacity, static_cast<int64_t>(sizeof(T)), &num_bytes))) {
327-
return Status::CapacityError("Resize: capacity overflow");
328-
}
313+
ARROW_RETURN_NOT_OK(ElementsToBytes("Resize", new_capacity, &num_bytes));
329314
return bytes_builder_.Resize(num_bytes, shrink_to_fit);
330315
}
331316

332317
Status Reserve(const int64_t additional_elements) {
333-
if (ARROW_PREDICT_FALSE(additional_elements < 0)) {
334-
return Status::Invalid("Reserve: negative additional_elements");
335-
}
336318
int64_t num_bytes;
337-
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
338-
additional_elements, static_cast<int64_t>(sizeof(T)), &num_bytes))) {
339-
return Status::CapacityError("Reserve: size overflow");
340-
}
319+
ARROW_RETURN_NOT_OK(ElementsToBytes("Reserve", additional_elements, &num_bytes));
341320
return bytes_builder_.Reserve(num_bytes);
342321
}
343322

344323
Status Advance(const int64_t length) {
345-
if (ARROW_PREDICT_FALSE(length < 0)) {
346-
return Status::Invalid("Advance: negative length");
347-
}
348324
int64_t num_bytes;
349-
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
350-
length, static_cast<int64_t>(sizeof(T)), &num_bytes))) {
351-
return Status::CapacityError("Advance: size overflow");
352-
}
325+
ARROW_RETURN_NOT_OK(ElementsToBytes("Advance", length, &num_bytes));
353326
return bytes_builder_.Advance(num_bytes);
354327
}
355328

@@ -374,14 +347,8 @@ class TypedBufferBuilder<
374347
/// only for memory allocation).
375348
Result<std::shared_ptr<Buffer>> FinishWithLength(int64_t final_length,
376349
bool shrink_to_fit = true) {
377-
if (ARROW_PREDICT_FALSE(final_length < 0)) {
378-
return Status::Invalid("FinishWithLength: negative final length");
379-
}
380350
int64_t num_bytes;
381-
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
382-
final_length, static_cast<int64_t>(sizeof(T)), &num_bytes))) {
383-
return Status::CapacityError("FinishWithLength: final length overflow");
384-
}
351+
ARROW_RETURN_NOT_OK(ElementsToBytes("FinishWithLength", final_length, &num_bytes));
385352
return bytes_builder_.FinishWithLength(num_bytes, shrink_to_fit);
386353
}
387354

@@ -393,6 +360,20 @@ class TypedBufferBuilder<
393360
T* mutable_data() { return reinterpret_cast<T*>(bytes_builder_.mutable_data()); }
394361

395362
private:
363+
// Convert a number of elements to a number of bytes, erroring out on
364+
// negative element counts and byte size overflow.
365+
static Status ElementsToBytes(const char* operation, int64_t num_elements,
366+
int64_t* num_bytes) {
367+
if (ARROW_PREDICT_FALSE(num_elements < 0)) {
368+
return Status::Invalid(operation, ": negative number of elements");
369+
}
370+
if (ARROW_PREDICT_FALSE(internal::MultiplyWithOverflow(
371+
num_elements, static_cast<int64_t>(sizeof(T)), num_bytes))) {
372+
return Status::CapacityError(operation, ": byte size overflow");
373+
}
374+
return Status::OK();
375+
}
376+
396377
BufferBuilder bytes_builder_;
397378
};
398379

@@ -503,7 +484,7 @@ class TypedBufferBuilder<bool> {
503484
internal::AddWithOverflow(bit_length_, additional_elements, &min_length))) {
504485
return Status::CapacityError("Reserve: capacity overflow");
505486
}
506-
return Resize(min_length, false);
487+
return Resize(BufferBuilder::GrowByFactor(bit_length_, min_length), false);
507488
}
508489

509490
Status Advance(const int64_t length) {
@@ -534,6 +515,9 @@ class TypedBufferBuilder<bool> {
534515
/// only for memory allocation).
535516
Result<std::shared_ptr<Buffer>> FinishWithLength(int64_t final_length,
536517
bool shrink_to_fit = true) {
518+
if (ARROW_PREDICT_FALSE(final_length < 0)) {
519+
return Status::Invalid("FinishWithLength: negative final length");
520+
}
537521
const auto final_byte_length = bit_util::BytesForBits(final_length);
538522
bytes_builder_.UnsafeAdvance(final_byte_length - bytes_builder_.length());
539523
bit_length_ = false_count_ = 0;

cpp/src/arrow/buffer_test.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ TEST(TestBufferBuilder, InvalidReserveAndAppendLengths) {
736736
ASSERT_RAISES(Invalid, builder.Advance(-1));
737737

738738
const int64_t overflow_add = std::numeric_limits<int64_t>::max() - 8;
739-
ASSERT_RAISES(CapacityError, builder.Reserve(overflow_add));
739+
ASSERT_RAISES(OutOfMemory, builder.Reserve(overflow_add));
740740
}
741741

742742
TEST(TestBufferBuilder, Alignment) {
@@ -880,7 +880,8 @@ TYPED_TEST(TypedTestBufferBuilder, NegativeAndOverflowAppend) {
880880

881881
ASSERT_RAISES(Invalid, builder.Append(-1, static_cast<TypeParam>(0)));
882882

883-
const int64_t max_num_elements = std::numeric_limits<int64_t>::max() / sizeof(TypeParam) + 1;
883+
const int64_t max_num_elements =
884+
std::numeric_limits<int64_t>::max() / sizeof(TypeParam) + 1;
884885
ASSERT_RAISES(CapacityError,
885886
builder.Append(max_num_elements, static_cast<TypeParam>(0)));
886887
}

cpp/src/arrow/memory_pool.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ constexpr int64_t kMaxBufferCapacity = std::numeric_limits<int64_t>::max() - 63;
7373

7474
Status ValidateBufferCapacity(int64_t capacity, const char* operation) {
7575
if (ARROW_PREDICT_FALSE(capacity < 0)) {
76-
return Status::Invalid(operation, ": negative capacity");
76+
return Status::Invalid(operation, ": negative capacity: ", capacity);
7777
}
7878
if (ARROW_PREDICT_FALSE(capacity > kMaxBufferCapacity)) {
79-
return Status::CapacityError(operation, ": capacity overflow");
79+
return Status::OutOfMemory(operation, ": capacity too large: ", capacity);
8080
}
8181
return Status::OK();
8282
}
@@ -1031,7 +1031,6 @@ Result<std::unique_ptr<ResizableBuffer>> AllocateResizableBuffer(const int64_t s
10311031
Result<std::unique_ptr<ResizableBuffer>> AllocateResizableBuffer(const int64_t size,
10321032
const int64_t alignment,
10331033
MemoryPool* pool) {
1034-
RETURN_NOT_OK(ValidateBufferCapacity(size, "AllocateResizableBuffer"));
10351034
return ResizePoolBuffer<std::unique_ptr<ResizableBuffer>>(
10361035
PoolBuffer::MakeUnique(pool, alignment), size);
10371036
}

0 commit comments

Comments
 (0)