From 0fdf7e08392a451232359813d2262b57b4706f92 Mon Sep 17 00:00:00 2001 From: Jin Shang Date: Tue, 19 Dec 2023 08:00:33 +0800 Subject: [PATCH] move concrete array span to compute internal --- cpp/src/arrow/array/builder_decimal.cc | 1 - cpp/src/arrow/array/data.h | 125 ------------- .../arrow/compute/kernels/codegen_internal.h | 169 ++++++++++++++++++ .../arrow/compute/kernels/scalar_nested.cc | 2 +- cpp/src/arrow/type_fwd.h | 30 +--- cpp/src/arrow/type_traits.h | 29 +-- 6 files changed, 173 insertions(+), 183 deletions(-) diff --git a/cpp/src/arrow/array/builder_decimal.cc b/cpp/src/arrow/array/builder_decimal.cc index 6f39bdc889121..3b1262819df7f 100644 --- a/cpp/src/arrow/array/builder_decimal.cc +++ b/cpp/src/arrow/array/builder_decimal.cc @@ -20,7 +20,6 @@ #include #include -#include "arrow/array/builder_binary.h" #include "arrow/array/data.h" #include "arrow/buffer.h" #include "arrow/buffer_builder.h" diff --git a/cpp/src/arrow/array/data.h b/cpp/src/arrow/array/data.h index 8a4326e95850d..4c2df8381490a 100644 --- a/cpp/src/arrow/array/data.h +++ b/cpp/src/arrow/array/data.h @@ -26,7 +26,6 @@ #include "arrow/buffer.h" #include "arrow/result.h" #include "arrow/type.h" -#include "arrow/type_fwd.h" #include "arrow/util/bit_util.h" #include "arrow/util/macros.h" #include "arrow/util/span.h" @@ -586,128 +585,4 @@ Result> GetArrayView(const std::shared_ptr const std::shared_ptr& type); } // namespace internal - -struct ARROW_EXPORT ConcreteArraySpan { - const ArraySpan* span; - - explicit ConcreteArraySpan(const ArraySpan& span) : span(&span) {} - - bool IsNull(int64_t i) const { return span->IsNull(i); } - bool IsValid(int64_t i) const { return span->IsValid(i); } -}; - -struct ARROW_EXPORT NullArraySpan : public ConcreteArraySpan { - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = NullType; - - // For API compatibility with BinaryArray etc. - bool GetView(int64_t i) const { return false; } - - bool Value(int64_t i) const { return false; } -}; - -struct ARROW_EXPORT BooleanArraySpan : public ConcreteArraySpan { - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = BooleanType; - - bool Value(int64_t i) const { - return bit_util::GetBit(span->buffers[1].data, i + span->offset); - } - - // For API compatibility with BinaryArray etc. - bool GetView(int64_t i) const { return Value(i); } -}; - -template -struct ARROW_EXPORT NumericArraySpan : public ConcreteArraySpan { - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = TYPE; - using value_type = typename TypeClass::c_type; - - // Return the value at the given index - value_type Value(int64_t i) const { return span->GetValues(1)[i]; } - - // For API compatibility with BinaryArray etc. - value_type GetView(int64_t i) const { return Value(i); } -}; - -// variable length binary/string types -template -struct ARROW_EXPORT BaseBinaryArraySpan : public ConcreteArraySpan { - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = TYPE; - using offset_type = typename TypeClass::offset_type; - - /// \brief Get binary value as a string_view - /// Provided for consistency with other arrays. - /// - /// \param i the value index - /// \return the view over the selected value - std::string_view Value(int64_t i) const { return GetView(i); } - - /// \brief Get binary value as a string_view - /// - /// \param i the value index - /// \return the view over the selected value - std::string_view GetView(int64_t i) const { - // Account for base offset - const auto* offsets = span->GetValues(1); - const offset_type pos = offsets[i]; - return std::string_view(reinterpret_cast(span->buffers[2].data + pos), - offsets[i + 1] - pos); - } -}; - -// Fixed size binary and decimal types -template -struct ARROW_EXPORT BaseFixedSizeBinaryArraySpan : public ConcreteArraySpan { - public: - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = TYPE; - - /// \brief Get binary value as a string_view - /// Provided for consistency with other arrays. - /// - /// \param i the value index - /// \return the view over the selected value - std::string_view Value(int64_t i) const { return GetView(i); } - - /// \brief Get binary value as a string_view - /// - /// \param i the value index - /// \return the view over the selected value - std::string_view GetView(int64_t i) const { - const int64_t pos = (i + span->offset) * span->type->byte_width(); - std::string_view view(reinterpret_cast(span->buffers[1].data + pos), - span->type->byte_width()); - return view; - } -}; - -struct ARROW_EXPORT DayTimeIntervalArraySpan : public ConcreteArraySpan { - public: - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = DayTimeIntervalType; - - TypeClass::DayMilliseconds Value(int64_t i) const { - return span->GetValues(1)[i]; - } - - // For API compatibility with BinaryArray etc. - TypeClass::DayMilliseconds GetView(int64_t i) const { return Value(i); } -}; - -struct ARROW_EXPORT MonthDayNanoIntervalArraySpan : public ConcreteArraySpan { - public: - using ConcreteArraySpan::ConcreteArraySpan; - using TypeClass = MonthDayNanoIntervalType; - - TypeClass::MonthDayNanos Value(int64_t i) const { - return span->GetValues(1)[i]; - } - - // For API compatibility with BinaryArray etc. - TypeClass::MonthDayNanos GetView(int64_t i) const { return Value(i); } -}; - } // namespace arrow diff --git a/cpp/src/arrow/compute/kernels/codegen_internal.h b/cpp/src/arrow/compute/kernels/codegen_internal.h index 72b29057b82e0..49f41af16f0d0 100644 --- a/cpp/src/arrow/compute/kernels/codegen_internal.h +++ b/cpp/src/arrow/compute/kernels/codegen_internal.h @@ -1407,6 +1407,175 @@ void PromoteIntegerForDurationArithmetic(std::vector* types); // END of DispatchBest helpers // ---------------------------------------------------------------------- +// ConcreteArraySpan for easy access of ArraySpans in compute kernels +struct ARROW_EXPORT ConcreteArraySpan { + const ArraySpan* span; + + explicit ConcreteArraySpan(const ArraySpan& span) : span(&span) {} + + bool IsNull(int64_t i) const { return span->IsNull(i); } + bool IsValid(int64_t i) const { return span->IsValid(i); } +}; + +struct ARROW_EXPORT NullArraySpan : public ConcreteArraySpan { + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = NullType; + + // For API compatibility with BinaryArray etc. + bool GetView(int64_t i) const { return false; } + + bool Value(int64_t i) const { return false; } +}; + +struct ARROW_EXPORT BooleanArraySpan : public ConcreteArraySpan { + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = BooleanType; + + bool Value(int64_t i) const { + return bit_util::GetBit(span->buffers[1].data, i + span->offset); + } + + // For API compatibility with BinaryArray etc. + bool GetView(int64_t i) const { return Value(i); } +}; + +template +struct ARROW_EXPORT NumericArraySpan : public ConcreteArraySpan { + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = TYPE; + using value_type = typename TypeClass::c_type; + + // Return the value at the given index + value_type Value(int64_t i) const { return span->GetValues(1)[i]; } + + // For API compatibility with BinaryArray etc. + value_type GetView(int64_t i) const { return Value(i); } +}; + +// variable length binary/string types +template +struct ARROW_EXPORT BaseBinaryArraySpan : public ConcreteArraySpan { + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = TYPE; + using offset_type = typename TypeClass::offset_type; + + /// \brief Get binary value as a string_view + /// Provided for consistency with other arrays. + /// + /// \param i the value index + /// \return the view over the selected value + std::string_view Value(int64_t i) const { return GetView(i); } + + /// \brief Get binary value as a string_view + /// + /// \param i the value index + /// \return the view over the selected value + std::string_view GetView(int64_t i) const { + // Account for base offset + const auto* offsets = span->GetValues(1); + const offset_type pos = offsets[i]; + return std::string_view(reinterpret_cast(span->buffers[2].data + pos), + offsets[i + 1] - pos); + } +}; + +// Fixed size binary and decimal types +template +struct ARROW_EXPORT BaseFixedSizeBinaryArraySpan : public ConcreteArraySpan { + public: + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = TYPE; + + /// \brief Get binary value as a string_view + /// Provided for consistency with other arrays. + /// + /// \param i the value index + /// \return the view over the selected value + std::string_view Value(int64_t i) const { return GetView(i); } + + /// \brief Get binary value as a string_view + /// + /// \param i the value index + /// \return the view over the selected value + std::string_view GetView(int64_t i) const { + const int64_t pos = (i + span->offset) * span->type->byte_width(); + std::string_view view(reinterpret_cast(span->buffers[1].data + pos), + span->type->byte_width()); + return view; + } +}; + +struct ARROW_EXPORT DayTimeIntervalArraySpan : public ConcreteArraySpan { + public: + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = DayTimeIntervalType; + + TypeClass::DayMilliseconds Value(int64_t i) const { + return span->GetValues(1)[i]; + } + + // For API compatibility with BinaryArray etc. + TypeClass::DayMilliseconds GetView(int64_t i) const { return Value(i); } +}; + +struct ARROW_EXPORT MonthDayNanoIntervalArraySpan : public ConcreteArraySpan { + public: + using ConcreteArraySpan::ConcreteArraySpan; + using TypeClass = MonthDayNanoIntervalType; + + TypeClass::MonthDayNanos Value(int64_t i) const { + return span->GetValues(1)[i]; + } + + // For API compatibility with BinaryArray etc. + TypeClass::MonthDayNanos GetView(int64_t i) const { return Value(i); } +}; + +template +struct GetArraySpanType; + +template <> +struct GetArraySpanType { + using Type = NullArraySpan; +}; + +template <> +struct GetArraySpanType { + using Type = BooleanArraySpan; +}; + +template +struct GetArraySpanType> { + using Type = NumericArraySpan; +}; + +template +struct GetArraySpanType> { + using Type = BaseBinaryArraySpan; +}; + +template +struct GetArraySpanType> { + using Type = BaseFixedSizeBinaryArraySpan; +}; + +template <> +struct GetArraySpanType { + using Type = DayTimeIntervalArraySpan; +}; + +template <> +struct GetArraySpanType { + using Type = MonthDayNanoIntervalArraySpan; +}; + +template +struct GetArraySpanType> { + using Type = NumericArraySpan; +}; + +// ---------------------------------------------------------------------- + } // namespace internal } // namespace compute } // namespace arrow diff --git a/cpp/src/arrow/compute/kernels/scalar_nested.cc b/cpp/src/arrow/compute/kernels/scalar_nested.cc index 9dc60727f7712..8d2dd6a3501c4 100644 --- a/cpp/src/arrow/compute/kernels/scalar_nested.cc +++ b/cpp/src/arrow/compute/kernels/scalar_nested.cc @@ -946,7 +946,7 @@ struct AdjoinAsListImpl { Status> Visit(const InputType& type, KernelContext* ctx, const ExecSpan& batch, int64_t length, std::shared_ptr* out_values) { - using ArraySpanType = typename TypeTraits::ArraySpanType; + using ArraySpanType = typename GetArraySpanType::Type; using BuilderType = typename TypeTraits::BuilderType; auto builder = std::make_shared(type.GetSharedPtr(), diff --git a/cpp/src/arrow/type_fwd.h b/cpp/src/arrow/type_fwd.h index a480b30b0e06e..63eec10bf723b 100644 --- a/cpp/src/arrow/type_fwd.h +++ b/cpp/src/arrow/type_fwd.h @@ -97,7 +97,6 @@ class NullType; class NullArray; class NullBuilder; struct NullScalar; -struct NullArraySpan; class FixedWidthType; @@ -105,19 +104,11 @@ class BooleanType; class BooleanArray; class BooleanBuilder; struct BooleanScalar; -struct BooleanArraySpan; - -template -struct BaseBinaryArraySpan; - -template -struct BaseFixedSizeBinaryArraySpan; class BinaryType; class BinaryArray; class BinaryBuilder; struct BinaryScalar; -using BinaryArraySpan = BaseBinaryArraySpan; class BinaryViewType; class BinaryViewArray; @@ -128,19 +119,16 @@ class LargeBinaryType; class LargeBinaryArray; class LargeBinaryBuilder; struct LargeBinaryScalar; -using LargeBinaryArraySpan = BaseBinaryArraySpan; class FixedSizeBinaryType; class FixedSizeBinaryArray; class FixedSizeBinaryBuilder; struct FixedSizeBinaryScalar; -using FixedSizeBinaryArraySpan = BaseFixedSizeBinaryArraySpan; class StringType; class StringArray; class StringBuilder; struct StringScalar; -using StringArraySpan = BaseBinaryArraySpan; class StringViewType; class StringViewArray; @@ -151,7 +139,6 @@ class LargeStringType; class LargeStringArray; class LargeStringBuilder; struct LargeStringScalar; -using LargeStringArraySpan = BaseBinaryArraySpan; class ListType; class ListArray; @@ -199,8 +186,6 @@ class Decimal128Builder; class Decimal256Builder; struct Decimal128Scalar; struct Decimal256Scalar; -using Decimal128ArraySpan = BaseFixedSizeBinaryArraySpan; -using Decimal256ArraySpan = BaseFixedSizeBinaryArraySpan; struct UnionMode { enum type { SPARSE, DENSE }; @@ -230,16 +215,12 @@ class NumericBuilder; template class NumericTensor; -template -struct NumericArraySpan; - #define _NUMERIC_TYPE_DECL(KLASS) \ class KLASS##Type; \ using KLASS##Array = NumericArray; \ using KLASS##Builder = NumericBuilder; \ struct KLASS##Scalar; \ - using KLASS##Tensor = NumericTensor; \ - using KLASS##ArraySpan = NumericArraySpan; + using KLASS##Tensor = NumericTensor; _NUMERIC_TYPE_DECL(Int8) _NUMERIC_TYPE_DECL(Int16) @@ -262,13 +243,11 @@ class Date32Type; using Date32Array = NumericArray; using Date32Builder = NumericBuilder; struct Date32Scalar; -using Date32ArraySpan = NumericArraySpan; class Date64Type; using Date64Array = NumericArray; using Date64Builder = NumericBuilder; struct Date64Scalar; -using Date64ArraySpan = NumericArraySpan; struct ARROW_EXPORT TimeUnit { /// The unit for a time or timestamp DataType @@ -283,43 +262,36 @@ class Time32Type; using Time32Array = NumericArray; using Time32Builder = NumericBuilder; struct Time32Scalar; -using Time32ArraySpan = NumericArraySpan; class Time64Type; using Time64Array = NumericArray; using Time64Builder = NumericBuilder; struct Time64Scalar; -using Time64ArraySpan = NumericArraySpan; class TimestampType; using TimestampArray = NumericArray; using TimestampBuilder = NumericBuilder; struct TimestampScalar; -using TimestampArraySpan = NumericArraySpan; class MonthIntervalType; using MonthIntervalArray = NumericArray; using MonthIntervalBuilder = NumericBuilder; struct MonthIntervalScalar; -using MonthIntervalArraySpan = NumericArraySpan; class DayTimeIntervalType; class DayTimeIntervalArray; class DayTimeIntervalBuilder; struct DayTimeIntervalScalar; -struct DayTimeIntervalArraySpan; class MonthDayNanoIntervalType; class MonthDayNanoIntervalArray; class MonthDayNanoIntervalBuilder; struct MonthDayNanoIntervalScalar; -struct MonthDayNanoIntervalArraySpan; class DurationType; using DurationArray = NumericArray; using DurationBuilder = NumericBuilder; struct DurationScalar; -using DurationArraySpan = NumericArraySpan; class ExtensionType; class ExtensionArray; diff --git a/cpp/src/arrow/type_traits.h b/cpp/src/arrow/type_traits.h index 8e2b0057ad14a..ed66c9367dc36 100644 --- a/cpp/src/arrow/type_traits.h +++ b/cpp/src/arrow/type_traits.h @@ -22,9 +22,7 @@ #include #include -#include "arrow/array/data.h" #include "arrow/type.h" -#include "arrow/type_fwd.h" #include "arrow/util/bit_util.h" namespace arrow { @@ -108,7 +106,6 @@ struct TypeTraits { using ArrayType = NullArray; using BuilderType = NullBuilder; using ScalarType = NullScalar; - using ArraySpanType = NullArraySpan; static constexpr int64_t bytes_required(int64_t) { return 0; } constexpr static bool is_parameter_free = true; @@ -120,7 +117,6 @@ struct TypeTraits { using ArrayType = BooleanArray; using BuilderType = BooleanBuilder; using ScalarType = BooleanScalar; - using ArraySpanType = BooleanArraySpan; using CType = bool; static constexpr int64_t bytes_required(int64_t elements) { @@ -138,16 +134,13 @@ struct CTypeTraits : public TypeTraits { }; #define PRIMITIVE_TYPE_TRAITS_DEF_(CType_, ArrowType_, ArrowArrayType, ArrowBuilderType, \ - ArrowScalarType, ArrowTensorType, ArrowArraySpanType, \ - SingletonFn) \ + ArrowScalarType, ArrowTensorType, SingletonFn) \ template <> \ struct TypeTraits { \ using ArrayType = ArrowArrayType; \ using BuilderType = ArrowBuilderType; \ using ScalarType = ArrowScalarType; \ using TensorType = ArrowTensorType; \ - using ArraySpanType = ArrowArraySpanType; \ - \ using CType = ArrowType_::c_type; \ static constexpr int64_t bytes_required(int64_t elements) { \ return elements * static_cast(sizeof(CType)); \ @@ -165,8 +158,7 @@ struct CTypeTraits : public TypeTraits { PRIMITIVE_TYPE_TRAITS_DEF_( \ CType, ARROW_CONCAT(ArrowShort, Type), ARROW_CONCAT(ArrowShort, Array), \ ARROW_CONCAT(ArrowShort, Builder), ARROW_CONCAT(ArrowShort, Scalar), \ - ARROW_CONCAT(ArrowShort, Tensor), ARROW_CONCAT(ArrowShort, ArraySpan), \ - SingletonFn) + ARROW_CONCAT(ArrowShort, Tensor), SingletonFn) PRIMITIVE_TYPE_TRAITS_DEF(uint8_t, UInt8, uint8) PRIMITIVE_TYPE_TRAITS_DEF(int8_t, Int8, int8) @@ -189,7 +181,6 @@ struct TypeTraits { using ArrayType = Date64Array; using BuilderType = Date64Builder; using ScalarType = Date64Scalar; - using ArraySpanType = Date64ArraySpan; using CType = Date64Type::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -204,7 +195,6 @@ struct TypeTraits { using ArrayType = Date32Array; using BuilderType = Date32Builder; using ScalarType = Date32Scalar; - using ArraySpanType = Date32ArraySpan; using CType = Date32Type::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -219,7 +209,6 @@ struct TypeTraits { using ArrayType = TimestampArray; using BuilderType = TimestampBuilder; using ScalarType = TimestampScalar; - using ArraySpanType = TimestampArraySpan; using CType = TimestampType::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -233,7 +222,6 @@ struct TypeTraits { using ArrayType = DurationArray; using BuilderType = DurationBuilder; using ScalarType = DurationScalar; - using ArraySpanType = DurationArraySpan; using CType = DurationType::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -247,7 +235,6 @@ struct TypeTraits { using ArrayType = DayTimeIntervalArray; using BuilderType = DayTimeIntervalBuilder; using ScalarType = DayTimeIntervalScalar; - using ArraySpanType = DayTimeIntervalArraySpan; using CType = DayTimeIntervalType::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -262,7 +249,6 @@ struct TypeTraits { using ArrayType = MonthDayNanoIntervalArray; using BuilderType = MonthDayNanoIntervalBuilder; using ScalarType = MonthDayNanoIntervalScalar; - using ArraySpanType = MonthDayNanoIntervalArraySpan; using CType = MonthDayNanoIntervalType::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -278,7 +264,6 @@ struct TypeTraits { using ArrayType = MonthIntervalArray; using BuilderType = MonthIntervalBuilder; using ScalarType = MonthIntervalScalar; - using ArraySpanType = MonthIntervalArraySpan; using CType = MonthIntervalType::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -293,7 +278,6 @@ struct TypeTraits { using ArrayType = Time32Array; using BuilderType = Time32Builder; using ScalarType = Time32Scalar; - using ArraySpanType = Time32ArraySpan; using CType = Time32Type::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -307,7 +291,6 @@ struct TypeTraits { using ArrayType = Time64Array; using BuilderType = Time64Builder; using ScalarType = Time64Scalar; - using ArraySpanType = Time64ArraySpan; using CType = Time64Type::c_type; static constexpr int64_t bytes_required(int64_t elements) { @@ -322,7 +305,6 @@ struct TypeTraits { using BuilderType = HalfFloatBuilder; using ScalarType = HalfFloatScalar; using TensorType = HalfFloatTensor; - using ArraySpanType = HalfFloatArraySpan; static constexpr int64_t bytes_required(int64_t elements) { return elements * static_cast(sizeof(uint16_t)); @@ -336,7 +318,6 @@ struct TypeTraits { using ArrayType = Decimal128Array; using BuilderType = Decimal128Builder; using ScalarType = Decimal128Scalar; - using ArraySpanType = Decimal128ArraySpan; using CType = Decimal128; constexpr static bool is_parameter_free = false; }; @@ -346,7 +327,6 @@ struct TypeTraits { using ArrayType = Decimal256Array; using BuilderType = Decimal256Builder; using ScalarType = Decimal256Scalar; - using ArraySpanType = Decimal256ArraySpan; using CType = Decimal256; constexpr static bool is_parameter_free = false; }; @@ -356,7 +336,6 @@ struct TypeTraits { using ArrayType = BinaryArray; using BuilderType = BinaryBuilder; using ScalarType = BinaryScalar; - using ArraySpanType = BinaryArraySpan; using OffsetType = Int32Type; constexpr static bool is_parameter_free = true; static inline std::shared_ptr type_singleton() { return binary(); } @@ -377,7 +356,6 @@ struct TypeTraits { using ArrayType = LargeBinaryArray; using BuilderType = LargeBinaryBuilder; using ScalarType = LargeBinaryScalar; - using ArraySpanType = LargeBinaryArraySpan; using OffsetType = Int64Type; constexpr static bool is_parameter_free = true; static inline std::shared_ptr type_singleton() { return large_binary(); } @@ -388,7 +366,6 @@ struct TypeTraits { using ArrayType = FixedSizeBinaryArray; using BuilderType = FixedSizeBinaryBuilder; using ScalarType = FixedSizeBinaryScalar; - using ArraySpanType = FixedSizeBinaryArraySpan; // FixedSizeBinary doesn't have offsets per se, but string length is int32 sized using OffsetType = Int32Type; constexpr static bool is_parameter_free = false; @@ -399,7 +376,6 @@ struct TypeTraits { using ArrayType = StringArray; using BuilderType = StringBuilder; using ScalarType = StringScalar; - using ArraySpanType = StringArraySpan; using OffsetType = Int32Type; constexpr static bool is_parameter_free = true; static inline std::shared_ptr type_singleton() { return utf8(); } @@ -420,7 +396,6 @@ struct TypeTraits { using ArrayType = LargeStringArray; using BuilderType = LargeStringBuilder; using ScalarType = LargeStringScalar; - using ArraySpanType = LargeStringArraySpan; using OffsetType = Int64Type; constexpr static bool is_parameter_free = true; static inline std::shared_ptr type_singleton() { return large_utf8(); }