diff --git a/r/src/altrep.cpp b/r/src/altrep.cpp index bb91ca03c40..aec487f420d 100644 --- a/r/src/altrep.cpp +++ b/r/src/altrep.cpp @@ -149,15 +149,12 @@ struct AltrepVectorBase { // What gets printed on .Internal(inspect()) static Rboolean Inspect(SEXP alt, int pre, int deep, int pvec, void (*inspect_subtree)(SEXP, int, int, int)) { - SEXP data_class_sym = CAR(ATTRIB(ALTREP_CLASS(alt))); - const char* class_name = CHAR(PRINTNAME(data_class_sym)); - if (IsMaterialized(alt)) { - Rprintf("materialized %s len=%ld\n", class_name, + Rprintf("materialized %s len=%ld\n", Impl::class_name, static_cast(Rf_xlength(Representation(alt)))); // NOLINT: runtime/int } else { const auto& chunked_array = GetChunkedArray(alt); - Rprintf("%s<%p, %s, %d chunks, %ld nulls> len=%ld\n", class_name, + Rprintf("%s<%p, %s, %d chunks, %ld nulls> len=%ld\n", Impl::class_name, reinterpret_cast(chunked_array.get()), chunked_array->type()->ToString().c_str(), chunked_array->num_chunks(), static_cast(chunked_array->null_count()), // NOLINT: runtime/int @@ -197,6 +194,7 @@ struct AltrepVectorPrimitive : public AltrepVectorBase::type; using Base::IsMaterialized; @@ -437,10 +435,13 @@ struct AltrepVectorPrimitive : public AltrepVectorBase R_altrep_class_t AltrepVectorPrimitive::class_t; +template +const char* AltrepVectorPrimitive::class_name; struct AltrepFactor : public AltrepVectorBase { // singleton altrep class description static R_altrep_class_t class_t; + static const char* class_name; using Base = AltrepVectorBase; using Base::IsMaterialized; @@ -574,11 +575,10 @@ struct AltrepFactor : public AltrepVectorBase { // the representation integer vector SEXP dup = PROTECT(Rf_shallow_duplicate(Materialize(alt))); - // additional attributes from the altrep - SEXP atts = PROTECT(Rf_duplicate(ATTRIB(alt))); - SET_ATTRIB(dup, atts); + // copy attributes from the altrep object + DUPLICATE_ATTRIB(dup, alt); - UNPROTECT(2); + UNPROTECT(1); return dup; } @@ -765,6 +765,7 @@ struct AltrepFactor : public AltrepVectorBase { static SEXP Sum(SEXP alt, Rboolean narm) { return nullptr; } }; R_altrep_class_t AltrepFactor::class_t; +const char* AltrepFactor::class_name; // Implementation for string arrays template @@ -772,6 +773,7 @@ struct AltrepVectorString : public AltrepVectorBase> { using Base = AltrepVectorBase>; static R_altrep_class_t class_t; + static const char* class_name; using StringArrayType = typename TypeTraits::ArrayType; using Base::Representation; @@ -969,6 +971,8 @@ struct AltrepVectorString : public AltrepVectorBase> { template R_altrep_class_t AltrepVectorString::class_t; +template +const char* AltrepVectorString::class_name; // initialize altrep, altvec, altreal, and altinteger methods template @@ -1016,6 +1020,7 @@ void InitAltIntegerMethods(R_altrep_class_t class_t, DllInfo* dll) { template void InitAltRealClass(DllInfo* dll, const char* name) { AltrepClass::class_t = R_make_altreal_class(name, "arrow", dll); + AltrepClass::class_name = name; InitAltrepMethods(AltrepClass::class_t, dll); InitAltvecMethods(AltrepClass::class_t, dll); InitAltRealMethods(AltrepClass::class_t, dll); @@ -1024,6 +1029,7 @@ void InitAltRealClass(DllInfo* dll, const char* name) { template void InitAltIntegerClass(DllInfo* dll, const char* name) { AltrepClass::class_t = R_make_altinteger_class(name, "arrow", dll); + AltrepClass::class_name = name; InitAltrepMethods(AltrepClass::class_t, dll); InitAltvecMethods(AltrepClass::class_t, dll); InitAltIntegerMethods(AltrepClass::class_t, dll); @@ -1032,6 +1038,7 @@ void InitAltIntegerClass(DllInfo* dll, const char* name) { template void InitAltStringClass(DllInfo* dll, const char* name) { AltrepClass::class_t = R_make_altstring_class(name, "arrow", dll); + AltrepClass::class_name = name; R_set_altrep_Length_method(AltrepClass::class_t, AltrepClass::Length); R_set_altrep_Inspect_method(AltrepClass::class_t, AltrepClass::Inspect); R_set_altrep_Duplicate_method(AltrepClass::class_t, AltrepClass::Duplicate); @@ -1094,10 +1101,11 @@ SEXP MakeAltrepVector(const std::shared_ptr& chunked_array) { bool is_arrow_altrep(SEXP x) { if (ALTREP(x)) { - SEXP info = ALTREP_CLASS_SERIALIZED_CLASS(ALTREP_CLASS(x)); - SEXP pkg = ALTREP_SERIALIZED_CLASS_PKGSYM(info); - - if (pkg == symbols::arrow) return true; + return R_altrep_inherits(x, AltrepVectorPrimitive::class_t) || + R_altrep_inherits(x, AltrepVectorPrimitive::class_t) || + R_altrep_inherits(x, AltrepFactor::class_t) || + R_altrep_inherits(x, AltrepVectorString::class_t) || + R_altrep_inherits(x, AltrepVectorString::class_t); } return false; @@ -1160,20 +1168,21 @@ sexp test_arrow_altrep_is_materialized(sexp x) { return Rf_ScalarLogical(NA_LOGICAL); } - sexp data_class_sym = CAR(ATTRIB(ALTREP_CLASS(x))); - std::string class_name(CHAR(PRINTNAME(data_class_sym))); - int result = NA_LOGICAL; - if (class_name == "arrow::array_dbl_vector") { + if (R_altrep_inherits(x, arrow::r::altrep::AltrepVectorPrimitive::class_t)) { result = arrow::r::altrep::AltrepVectorPrimitive::IsMaterialized(x); - } else if (class_name == "arrow::array_int_vector") { + } else if (R_altrep_inherits( + x, arrow::r::altrep::AltrepVectorPrimitive::class_t)) { result = arrow::r::altrep::AltrepVectorPrimitive::IsMaterialized(x); - } else if (class_name == "arrow::array_string_vector") { + } else if (R_altrep_inherits( + x, arrow::r::altrep::AltrepVectorString::class_t)) { result = arrow::r::altrep::AltrepVectorString::IsMaterialized(x); - } else if (class_name == "arrow::array_large_string_vector") { + } else if (R_altrep_inherits( + x, + arrow::r::altrep::AltrepVectorString::class_t)) { result = arrow::r::altrep::AltrepVectorString::IsMaterialized(x); - } else if (class_name == "arrow::array_factor") { + } else if (R_altrep_inherits(x, arrow::r::altrep::AltrepFactor::class_t)) { result = arrow::r::altrep::AltrepFactor::IsMaterialized(x); } @@ -1191,18 +1200,19 @@ bool test_arrow_altrep_force_materialize(sexp x) { stop("x is already materialized"); } - sexp data_class_sym = CAR(ATTRIB(ALTREP_CLASS(x))); - std::string class_name(CHAR(PRINTNAME(data_class_sym))); - - if (class_name == "arrow::array_dbl_vector") { + if (R_altrep_inherits(x, arrow::r::altrep::AltrepVectorPrimitive::class_t)) { arrow::r::altrep::AltrepVectorPrimitive::Materialize(x); - } else if (class_name == "arrow::array_int_vector") { + } else if (R_altrep_inherits( + x, arrow::r::altrep::AltrepVectorPrimitive::class_t)) { arrow::r::altrep::AltrepVectorPrimitive::Materialize(x); - } else if (class_name == "arrow::array_string_vector") { + } else if (R_altrep_inherits( + x, arrow::r::altrep::AltrepVectorString::class_t)) { arrow::r::altrep::AltrepVectorString::Materialize(x); - } else if (class_name == "arrow::array_large_string_vector") { + } else if (R_altrep_inherits( + x, + arrow::r::altrep::AltrepVectorString::class_t)) { arrow::r::altrep::AltrepVectorString::Materialize(x); - } else if (class_name == "arrow::array_factor") { + } else if (R_altrep_inherits(x, arrow::r::altrep::AltrepFactor::class_t)) { arrow::r::altrep::AltrepFactor::Materialize(x); } else { return false; diff --git a/r/src/arrow_cpp11.h b/r/src/arrow_cpp11.h index c4483ce531f..700dccb928e 100644 --- a/r/src/arrow_cpp11.h +++ b/r/src/arrow_cpp11.h @@ -39,11 +39,6 @@ #define ARROW_R_DCHECK(EXPR) #endif -// For context, see: -// https://github.com/r-devel/r-svn/blob/6418faeb6f5d87d3d9b92b8978773bc3856b4b6f/src/main/altrep.c#L37 -#define ALTREP_CLASS_SERIALIZED_CLASS(x) ATTRIB(x) -#define ALTREP_SERIALIZED_CLASS_PKGSYM(x) CADR(x) - #if (R_VERSION < R_Version(3, 5, 0)) #define LOGICAL_RO(x) ((const int*)LOGICAL(x)) #define INTEGER_RO(x) ((const int*)INTEGER(x))