| 569 | |
| 570 | public: |
| 571 | explicit Converter_Dictionary(const std::shared_ptr<ChunkedArray>& chunked_array) |
| 572 | : Converter(chunked_array), |
| 573 | need_unification_(DictionaryChunkArrayNeedUnification(chunked_array)) { |
| 574 | if (need_unification_) { |
| 575 | const auto& arr_type = checked_cast<const DictionaryType&>(*chunked_array->type()); |
| 576 | unifier_ = ValueOrStop(DictionaryUnifier::Make(arr_type.value_type())); |
| 577 | |
| 578 | int n_arrays = chunked_array->num_chunks(); |
| 579 | arrays_transpose_.resize(n_arrays); |
| 580 | |
| 581 | for (int i = 0; i < n_arrays; i++) { |
| 582 | const auto& dict_i = |
| 583 | *checked_cast<const DictionaryArray&>(*chunked_array->chunk(i)).dictionary(); |
| 584 | StopIfNotOk(unifier_->Unify(dict_i, &arrays_transpose_[i])); |
| 585 | } |
| 586 | |
| 587 | StopIfNotOk(unifier_->GetResult(&out_type_, &dictionary_)); |
| 588 | } else { |
| 589 | const auto& dict_type = checked_cast<const DictionaryType&>(*chunked_array->type()); |
| 590 | |
| 591 | const auto& indices_type = *dict_type.index_type(); |
| 592 | switch (indices_type.id()) { |
| 593 | case Type::UINT8: |
| 594 | case Type::INT8: |
| 595 | case Type::UINT16: |
| 596 | case Type::INT16: |
| 597 | case Type::INT32: |
| 598 | case Type::UINT32: |
| 599 | case Type::INT64: |
| 600 | case Type::UINT64: |
| 601 | break; |
| 602 | default: |
| 603 | cpp11::stop("Cannot convert Dictionary Array of type `%s` to R", |
| 604 | dict_type.ToString().c_str()); |
| 605 | } |
| 606 | |
| 607 | if (chunked_array->num_chunks() > 0) { |
| 608 | // DictionaryChunkArrayNeedUnification() returned false so we can safely assume |
| 609 | // the dictionary of the first chunk applies everywhere |
| 610 | const auto& dict_array = |
| 611 | checked_cast<const DictionaryArray&>(*chunked_array->chunk(0)); |
| 612 | dictionary_ = dict_array.dictionary(); |
| 613 | } else { |
| 614 | dictionary_ = CreateEmptyArray(dict_type.value_type()); |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | // R factors store their codes in 32-bit integers, so dictionary arrays with |
| 619 | // more levels than that cannot be represented safely. |
| 620 | if (dictionary_->length() > std::numeric_limits<int>::max()) { |
| 621 | const auto& dict_type = checked_cast<const DictionaryType&>(*chunked_array->type()); |
| 622 | cpp11::stop( |
| 623 | "Cannot convert Dictionary Array of type `%s` to R: dictionary has " |
| 624 | "more levels than an R factor can represent", |
| 625 | dict_type.ToString().c_str()); |
| 626 | } |
| 627 | } |
| 628 |
nothing calls this directly
no test coverage detected