| 159 | } |
| 160 | |
| 161 | Result<std::shared_ptr<ArrayData>> TransposeDictIndices( |
| 162 | const std::shared_ptr<ArrayData>& data, const std::shared_ptr<DataType>& in_type, |
| 163 | const std::shared_ptr<DataType>& out_type, |
| 164 | const std::shared_ptr<ArrayData>& dictionary, const int32_t* transpose_map, |
| 165 | MemoryPool* pool) { |
| 166 | // Note that in_type may be different from data->type if data is of type ExtensionType |
| 167 | if (in_type->id() != Type::DICTIONARY || out_type->id() != Type::DICTIONARY) { |
| 168 | return Status::TypeError("Expected dictionary type"); |
| 169 | } |
| 170 | const int64_t in_dict_len = data->dictionary->length; |
| 171 | const auto& in_dict_type = checked_cast<const DictionaryType&>(*in_type); |
| 172 | const auto& out_dict_type = checked_cast<const DictionaryType&>(*out_type); |
| 173 | |
| 174 | const auto& in_index_type = *in_dict_type.index_type(); |
| 175 | const auto& out_index_type = |
| 176 | checked_cast<const FixedWidthType&>(*out_dict_type.index_type()); |
| 177 | |
| 178 | if (in_index_type.id() == out_index_type.id() && |
| 179 | IsTrivialTransposition(transpose_map, in_dict_len)) { |
| 180 | // Index type and values will be identical => we can simply reuse |
| 181 | // the existing buffers. |
| 182 | auto out_data = |
| 183 | ArrayData::Make(out_type, data->length, {data->buffers[0], data->buffers[1]}, |
| 184 | data->null_count, data->offset); |
| 185 | out_data->dictionary = dictionary; |
| 186 | return out_data; |
| 187 | } |
| 188 | |
| 189 | // Default path: compute a buffer of transposed indices. |
| 190 | ARROW_ASSIGN_OR_RAISE( |
| 191 | auto out_buffer, |
| 192 | AllocateBuffer(data->length * (out_index_type.bit_width() / CHAR_BIT), pool)); |
| 193 | |
| 194 | // Shift null buffer if the original offset is non-zero |
| 195 | std::shared_ptr<Buffer> null_bitmap; |
| 196 | if (data->offset != 0 && data->null_count != 0) { |
| 197 | ARROW_ASSIGN_OR_RAISE(null_bitmap, CopyBitmap(pool, data->buffers[0]->data(), |
| 198 | data->offset, data->length)); |
| 199 | } else { |
| 200 | null_bitmap = data->buffers[0]; |
| 201 | } |
| 202 | |
| 203 | auto out_data = ArrayData::Make(out_type, data->length, |
| 204 | {null_bitmap, std::move(out_buffer)}, data->null_count); |
| 205 | out_data->dictionary = dictionary; |
| 206 | RETURN_NOT_OK(internal::TransposeInts( |
| 207 | in_index_type, out_index_type, data->GetValues<uint8_t>(1, 0), |
| 208 | out_data->GetMutableValues<uint8_t>(1, 0), data->offset, out_data->offset, |
| 209 | data->length, transpose_map)); |
| 210 | return out_data; |
| 211 | } |
| 212 | |
| 213 | struct CompactTransposeMapVisitor { |
| 214 | const std::shared_ptr<ArrayData>& data; |
no test coverage detected