| 1532 | |
| 1533 | template <typename ArrayType> |
| 1534 | void PutBinaryArray(const ArrayType& array) { |
| 1535 | auto previous_len = static_cast<uint32_t>(last_value_.length()); |
| 1536 | std::string_view last_value_view = last_value_; |
| 1537 | |
| 1538 | PARQUET_THROW_NOT_OK(::arrow::VisitArraySpanInline<typename ArrayType::TypeClass>( |
| 1539 | *array.data(), |
| 1540 | [&](::std::string_view view) { |
| 1541 | if (ARROW_PREDICT_FALSE(view.size() >= kMaxByteArraySize)) { |
| 1542 | return Status::Invalid( |
| 1543 | "Parquet cannot store strings with size 2GB or more, got: ", view.size()); |
| 1544 | } |
| 1545 | const ByteArray src{view}; |
| 1546 | |
| 1547 | uint32_t common_prefix_length = 0; |
| 1548 | const uint32_t len = src.len; |
| 1549 | const uint32_t maximum_common_prefix_length = std::min(previous_len, len); |
| 1550 | while (common_prefix_length < maximum_common_prefix_length) { |
| 1551 | if (last_value_view[common_prefix_length] != view[common_prefix_length]) { |
| 1552 | break; |
| 1553 | } |
| 1554 | common_prefix_length++; |
| 1555 | } |
| 1556 | previous_len = len; |
| 1557 | prefix_length_encoder_.Put({static_cast<int32_t>(common_prefix_length)}, 1); |
| 1558 | |
| 1559 | last_value_view = view; |
| 1560 | const auto suffix_length = static_cast<uint32_t>(len - common_prefix_length); |
| 1561 | if (suffix_length == 0) { |
| 1562 | suffix_encoder_.Put(&empty_, 1); |
| 1563 | return Status::OK(); |
| 1564 | } |
| 1565 | const uint8_t* suffix_ptr = src.ptr + common_prefix_length; |
| 1566 | // Convert to ByteArray, so it can be passed to the suffix_encoder_. |
| 1567 | const ByteArray suffix(suffix_length, suffix_ptr); |
| 1568 | suffix_encoder_.Put(&suffix, 1); |
| 1569 | |
| 1570 | unencoded_byte_array_data_bytes_ += len; |
| 1571 | return Status::OK(); |
| 1572 | }, |
| 1573 | []() { return Status::OK(); })); |
| 1574 | last_value_ = last_value_view; |
| 1575 | } |
| 1576 | |
| 1577 | ::arrow::BufferBuilder sink_; |
| 1578 | DeltaBitPackEncoder<Int32Type> prefix_length_encoder_; |