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