You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2021/06/29 14:53:42 UTC

[GitHub] [arrow] bkietz commented on a change in pull request #10579: ARROW-11932: [C++] Implement ArrayBuilder::AppendScalar

bkietz commented on a change in pull request #10579:
URL: https://github.com/apache/arrow/pull/10579#discussion_r660698340



##########
File path: cpp/src/arrow/array/builder_base.cc
##########
@@ -92,6 +95,139 @@ Status ArrayBuilder::Advance(int64_t elements) {
   return null_bitmap_builder_.Advance(elements);
 }
 
+namespace {
+struct AppendScalarImpl {
+  template <typename T, typename AppendScalar,
+            typename BuilderType = typename TypeTraits<T>::BuilderType,
+            typename ScalarType = typename TypeTraits<T>::ScalarType>
+  Status UseBuilder(const AppendScalar& append) {
+    for (int64_t i = 0; i < n_repeats_; i++) {
+      for (const std::shared_ptr<Scalar>* scalar = scalars_begin_; scalar != scalars_end_;
+           scalar++) {
+        if ((*scalar)->is_valid) {
+          RETURN_NOT_OK(append(internal::checked_cast<const ScalarType&>(**scalar),
+                               static_cast<BuilderType*>(builder_)));
+        } else {
+          RETURN_NOT_OK(builder_->AppendNull());
+        }
+      }
+    }
+    return Status::OK();
+  }
+
+  struct AppendValue {
+    template <typename BuilderType, typename ScalarType>
+    Status operator()(const ScalarType& s, BuilderType* builder) const {
+      return builder->Append(s.value);
+    }
+  };
+
+  struct AppendBuffer {
+    template <typename BuilderType, typename ScalarType>
+    Status operator()(const ScalarType& s, BuilderType* builder) const {
+      const Buffer& buffer = *s.value;
+      return builder->Append(util::string_view{buffer});
+    }
+  };
+
+  struct AppendList {
+    template <typename BuilderType, typename ScalarType>
+    Status operator()(const ScalarType& s, BuilderType* builder) const {
+      RETURN_NOT_OK(builder->Append());
+      const Array& list = *s.value;
+      for (int64_t i = 0; i < list.length(); i++) {
+        ARROW_ASSIGN_OR_RAISE(auto scalar, list.GetScalar(i));
+        RETURN_NOT_OK(builder->value_builder()->AppendScalar(*scalar));
+      }
+      return Status::OK();
+    }
+  };
+
+  template <typename T>
+  enable_if_has_c_type<T, Status> Visit(const T&) {
+    return UseBuilder<T>(AppendValue{});
+  }
+
+  template <typename T>
+  enable_if_has_string_view<T, Status> Visit(const T&) {
+    return UseBuilder<T>(AppendBuffer{});
+  }
+
+  template <typename T>
+  enable_if_decimal<T, Status> Visit(const T&) {
+    return UseBuilder<T>(AppendValue{});
+  }
+

Review comment:
       +1 for reserving AOT for simple types
   
   ```suggestion
     template <typename T>
     enable_if_fixed_width<T, Status> Visit(const T&) {
       auto builder = checked_cast<typename TypeTraits<T>::BuilderType*>(builder_);
       RETURN_NOT_OK(builder->Reserve(n_repeats_ * (scalar_end_ - scalar_begin_)));
   
       for (int64_t i = 0; i < n_repeats_; i++) {
         for (const std::shared_ptr<Scalar>* raw = scalars_begin_; raw != scalars_end_;
              raw++) {
           auto scalar = checked_cast<const typename TypeTraits<T>::ScalarType*>(raw->get());
           if (scalar->is_valid) {
             builder->UnsafeAppend(scalar->value);
           } else {
             builder->UnsafeAppendNull();
           }
         }
       }
       return Status::OK();
     }
   
     template <typename T>
     enable_if_base_binary<T, Status> Visit(const T&) {
       int64_t data_size = 0;
       for (const std::shared_ptr<Scalar>* raw = scalars_begin_; raw != scalars_end_;
              raw++) {
         auto scalar = checked_cast<const typename TypeTraits<T>::ScalarType*>(raw->get());
         if (scalar->is_valid) {
           data_size += scalar->value->size();
         }
       }
   
       auto builder = checked_cast<typename TypeTraits<T>::BuilderType*>(builder_);
       RETURN_NOT_OK(builder->Reserve(n_repeats_ * (scalar_end_ - scalar_begin_)));
       RETURN_NOT_OK(builder->ReserveData(n_repeats_ * data_size));
   
       for (int64_t i = 0; i < n_repeats_; i++) {
         for (const std::shared_ptr<Scalar>* raw = scalars_begin_; raw != scalars_end_;
              raw++) {
           auto scalar = checked_cast<const typename TypeTraits<T>::ScalarType*>(raw->get());
           if (scalar->is_valid) {
             builder->UnsafeAppend(util::string_view{*scalar->value});
           } else {
             builder->UnsafeAppendNull();
           }
         }
       }
       return Status::OK();
     }
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@arrow.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org