| 44 | |
| 45 | template <typename InType, typename CType = typename TypeTraits<InType>::CType> |
| 46 | Result<std::pair<CType*, int64_t*>> PrepareOutput(int64_t n, KernelContext* ctx, |
| 47 | const DataType& type, ExecResult* out) { |
| 48 | DCHECK_EQ(Type::STRUCT, type.id()); |
| 49 | const auto& out_type = checked_cast<const StructType&>(type); |
| 50 | DCHECK_EQ(2, out_type.num_fields()); |
| 51 | const auto& mode_type = out_type.field(0)->type(); |
| 52 | const auto& count_type = int64(); |
| 53 | |
| 54 | auto mode_data = ArrayData::Make(mode_type, /*length=*/n, /*null_count=*/0); |
| 55 | mode_data->buffers.resize(2, nullptr); |
| 56 | auto count_data = ArrayData::Make(count_type, n, 0); |
| 57 | count_data->buffers.resize(2, nullptr); |
| 58 | |
| 59 | CType* mode_buffer = nullptr; |
| 60 | int64_t* count_buffer = nullptr; |
| 61 | |
| 62 | if (n > 0) { |
| 63 | const auto mode_buffer_size = bit_util::BytesForBits(n * mode_type->bit_width()); |
| 64 | ARROW_ASSIGN_OR_RAISE(mode_data->buffers[1], ctx->Allocate(mode_buffer_size)); |
| 65 | ARROW_ASSIGN_OR_RAISE(count_data->buffers[1], ctx->Allocate(n * sizeof(int64_t))); |
| 66 | mode_buffer = mode_data->template GetMutableValues<CType>(1); |
| 67 | count_buffer = count_data->template GetMutableValues<int64_t>(1); |
| 68 | } |
| 69 | |
| 70 | out->value = |
| 71 | ArrayData::Make(type.GetSharedPtr(), n, {nullptr}, {mode_data, count_data}, 0); |
| 72 | return std::make_pair(mode_buffer, count_buffer); |
| 73 | } |
| 74 | |
| 75 | // find top-n value:count pairs with minimal heap |
| 76 | // suboptimal for tiny or large n, possibly okay as we're not in hot path |
no test coverage detected