| 1022 | class VectorExecutor : public KernelExecutorImpl<VectorKernel> { |
| 1023 | public: |
| 1024 | Status Execute(const ExecBatch& batch, ExecListener* listener) override { |
| 1025 | // Some vector kernels have a separate code path for handling |
| 1026 | // chunked arrays (VectorKernel::exec_chunked) so we check if we |
| 1027 | // have any chunked arrays. If we do and an exec_chunked function |
| 1028 | // is defined then we call that. |
| 1029 | bool have_chunked_arrays = false; |
| 1030 | for (const Datum& arg : batch.values) { |
| 1031 | if (arg.is_chunked_array()) have_chunked_arrays = true; |
| 1032 | } |
| 1033 | |
| 1034 | output_num_buffers_ = static_cast<int>(output_type_.type->layout().buffers.size()); |
| 1035 | |
| 1036 | // Decide if we need to preallocate memory for this kernel |
| 1037 | validity_preallocated_ = |
| 1038 | (kernel_->null_handling != NullHandling::COMPUTED_NO_PREALLOCATE && |
| 1039 | kernel_->null_handling != NullHandling::OUTPUT_NOT_NULL); |
| 1040 | if (kernel_->mem_allocation == MemAllocation::PREALLOCATE) { |
| 1041 | data_preallocated_.clear(); |
| 1042 | ComputeDataPreallocate(*output_type_.type, &data_preallocated_); |
| 1043 | } |
| 1044 | |
| 1045 | if (kernel_->can_execute_chunkwise) { |
| 1046 | RETURN_NOT_OK(span_iterator_.Init(batch, exec_context()->exec_chunksize())); |
| 1047 | ExecSpan span; |
| 1048 | while (span_iterator_.Next(&span)) { |
| 1049 | RETURN_NOT_OK(Exec(span, listener)); |
| 1050 | } |
| 1051 | } else { |
| 1052 | // Kernel cannot execute chunkwise. If we have any chunked |
| 1053 | // arrays, then VectorKernel::exec_chunked must be defined |
| 1054 | // otherwise we raise an error |
| 1055 | if (have_chunked_arrays) { |
| 1056 | RETURN_NOT_OK(ExecChunked(batch, listener)); |
| 1057 | } else { |
| 1058 | // No chunked arrays. We pack the args into an ExecSpan and |
| 1059 | // call the regular exec code path |
| 1060 | ExecSpan span(batch); |
| 1061 | if (CheckIfAllScalar(batch)) { |
| 1062 | PromoteExecSpanScalars(&span); |
| 1063 | } |
| 1064 | RETURN_NOT_OK(Exec(span, listener)); |
| 1065 | } |
| 1066 | } |
| 1067 | |
| 1068 | if (kernel_->finalize) { |
| 1069 | // Intermediate results require post-processing after the execution is |
| 1070 | // completed (possibly involving some accumulated state) |
| 1071 | RETURN_NOT_OK(kernel_->finalize(kernel_ctx_, &results_)); |
| 1072 | for (const auto& result : results_) { |
| 1073 | RETURN_NOT_OK(listener->OnResult(result)); |
| 1074 | } |
| 1075 | } |
| 1076 | return Status::OK(); |
| 1077 | } |
| 1078 | |
| 1079 | Datum WrapResults(const std::vector<Datum>& inputs, |
| 1080 | const std::vector<Datum>& outputs) override { |
nothing calls this directly
no test coverage detected