| 450 | } |
| 451 | |
| 452 | static SEXP Make(const std::shared_ptr<ChunkedArray>& chunked_array) { |
| 453 | // only dealing with dictionaries of strings |
| 454 | if (internal::checked_cast<const DictionaryArray&>(*chunked_array->chunk(0)) |
| 455 | .dictionary() |
| 456 | ->type_id() != Type::STRING) { |
| 457 | return R_NilValue; |
| 458 | } |
| 459 | |
| 460 | bool need_unification = DictionaryChunkArrayNeedUnification(chunked_array); |
| 461 | |
| 462 | std::shared_ptr<Array> dictionary; |
| 463 | SEXP pointer_arrays_transpose; |
| 464 | |
| 465 | if (need_unification) { |
| 466 | const auto& arr_type = |
| 467 | internal::checked_cast<const DictionaryType&>(*chunked_array->type()); |
| 468 | std::unique_ptr<arrow::DictionaryUnifier> unifier_ = |
| 469 | ValueOrStop(DictionaryUnifier::Make(arr_type.value_type())); |
| 470 | |
| 471 | int n_arrays = chunked_array->num_chunks(); |
| 472 | BufferVector arrays_transpose(n_arrays); |
| 473 | |
| 474 | for (int i = 0; i < n_arrays; i++) { |
| 475 | const auto& dict_i = |
| 476 | *internal::checked_cast<const DictionaryArray&>(*chunked_array->chunk(i)) |
| 477 | .dictionary(); |
| 478 | StopIfNotOk(unifier_->Unify(dict_i, &arrays_transpose[i])); |
| 479 | } |
| 480 | |
| 481 | std::shared_ptr<DataType> out_type; |
| 482 | StopIfNotOk(unifier_->GetResult(&out_type, &dictionary)); |
| 483 | |
| 484 | Pointer<BufferVector> ptr( |
| 485 | new std::shared_ptr<BufferVector>(new BufferVector(arrays_transpose))); |
| 486 | pointer_arrays_transpose = PROTECT(ptr); |
| 487 | } else { |
| 488 | // just use the first one |
| 489 | const auto& dict_array = |
| 490 | internal::checked_cast<const DictionaryArray&>(*chunked_array->chunk(0)); |
| 491 | dictionary = dict_array.dictionary(); |
| 492 | |
| 493 | pointer_arrays_transpose = PROTECT(R_NilValue); |
| 494 | } |
| 495 | |
| 496 | // the chunked array as data1 |
| 497 | SEXP data1 = |
| 498 | PROTECT(external_pointer<ArrowAltrepData>(new ArrowAltrepData(chunked_array))); |
| 499 | |
| 500 | // a pairlist with the representation in the first node |
| 501 | SEXP data2 = PROTECT(Rf_list2(R_NilValue, // representation, empty at first |
| 502 | pointer_arrays_transpose)); |
| 503 | |
| 504 | SEXP alt = PROTECT(R_new_altrep(class_t, data1, data2)); |
| 505 | MARK_NOT_MUTABLE(alt); |
| 506 | |
| 507 | // set factor attributes |
| 508 | Rf_setAttrib(alt, R_LevelsSymbol, Array__as_vector(dictionary)); |
| 509 |
nothing calls this directly
no test coverage detected