Repository: apache/arrow
File: cpp/src/arrow/util/byte_size.cc (C++)

Code before:
    RETURN_NOT_OK(range_offsets->Append(sizeof(offset_type) * offset));
    RETURN_NOT_OK(range_lengths->Append(sizeof(offset_type) * length));

    const offset_type* offsets = input.GetValues<offset_type>(1, offset);
    const Buffer& values = *input.buffers[2];
    offset_type start = offsets[0];
    offset_type end = offsets[length];
    RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(values.data())));
    RETURN_NOT_OK(range_offsets->Append(static_cast<uint64_t>(start)));
    return range_lengths->Append(static_cast<uint64_t>(end - start));
  }

  Status Visit(const BinaryType& type) const { return VisitBaseBinary(type); }

  Status Visit(const LargeBinaryType& type) const { return VisitBaseBinary(type); }

  template <typename BaseViewType>
  Status VisitBaseViewType(const BaseViewType& type) const {
    using c_type = typename BaseViewType::c_type;
    RETURN_NOT_OK(VisitBitmap(input.buffers[0]));
    const Buffer& views = *input.buffers[1];
    RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(views.data())));
    RETURN_NOT_OK(range_offsets->Append(sizeof(c_type) * offset));
    RETURN_NOT_OK(range_lengths->Append(sizeof(c_type) * length));

    // The following calculation is an over/under estimate of the size since views buffer
    // might
    // 1. Not reference all the values in data buffers (the array was filtered without gc)
    // 2. Reference a value multiple times without repeating it in the data buffer
    //
    // Producing exact byte size would require linear scan of all values in view buffer
    for (size_t i = 2; i < input.buffers.size(); i++) {
      const Buffer& buf = *input.buffers[i];
      RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(buf.data())));
      RETURN_NOT_OK(range_offsets->Append(0));
      RETURN_NOT_OK(range_lengths->Append(static_cast<uint64_t>(buf.size())));
    }

    return Status::OK();
  }

  Status Visit(const StringViewType& type) const { return VisitBaseViewType(type); }

  Status Visit(const BinaryViewType& type) const { return VisitBaseViewType(type); }

  template <typename BaseListType>
  Status VisitBaseList(const BaseListType& type) const {
    using offset_type = typename BaseListType::offset_type;
    RETURN_NOT_OK(VisitBitmap(input.buffers[0]));

    const Buffer& offsets_buffer = *input.buffers[1];

Review comment (suggestion):
Can this actually underestimate?
```suggestion
    // The following calculation is an over estimate of the size since views buffer
```

Code after:
    RETURN_NOT_OK(range_offsets->Append(sizeof(offset_type) * offset));
    RETURN_NOT_OK(range_lengths->Append(sizeof(offset_type) * length));

    const offset_type* offsets = input.GetValues<offset_type>(1, offset);
    const Buffer& values = *input.buffers[2];
    offset_type start = offsets[0];
    offset_type end = offsets[length];
    RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(values.data())));
    RETURN_NOT_OK(range_offsets->Append(static_cast<uint64_t>(start)));
    return range_lengths->Append(static_cast<uint64_t>(end - start));
  }

  Status Visit(const BinaryType& type) const { return VisitBaseBinary(type); }

  Status Visit(const LargeBinaryType& type) const { return VisitBaseBinary(type); }

  template <typename BaseViewType>
  Status VisitBaseViewType(const BaseViewType& type) const {
    using c_type = typename BaseViewType::c_type;
    RETURN_NOT_OK(VisitBitmap(input.buffers[0]));
    const Buffer& views = *input.buffers[1];
    RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(views.data())));
    RETURN_NOT_OK(range_offsets->Append(sizeof(c_type) * offset));
    RETURN_NOT_OK(range_lengths->Append(sizeof(c_type) * length));

    // The following calculation is an over estimate of the size since views buffer
    // might
    // 1. Not reference all the values in data buffers (the array was filtered without gc)
    // 2. Reference a value multiple times without repeating it in the data buffer
    //
    // Producing exact byte size would require linear scan of all values in view buffer
    for (size_t i = 2; i < input.buffers.size(); i++) {
      const Buffer& buf = *input.buffers[i];
      RETURN_NOT_OK(range_starts->Append(reinterpret_cast<uint64_t>(buf.data())));
      RETURN_NOT_OK(range_offsets->Append(0));
      RETURN_NOT_OK(range_lengths->Append(static_cast<uint64_t>(buf.size())));
    }

    return Status::OK();
  }

  Status Visit(const StringViewType& type) const { return VisitBaseViewType(type); }

  Status Visit(const BinaryViewType& type) const { return VisitBaseViewType(type); }

  template <typename BaseListType>
  Status VisitBaseList(const BaseListType& type) const {
    using offset_type = typename BaseListType::offset_type;
    RETURN_NOT_OK(VisitBitmap(input.buffers[0]));

    const Buffer& offsets_buffer = *input.buffers[1];