diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc index 35dc496bddb00..7f4d789c105e2 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.cc @@ -23,7 +23,7 @@ namespace arrow::matlab::array::proxy { - Array::Array() { + Array::Array(std::shared_ptr array) : array{std::move(array)} { // Register Proxy methods. REGISTER_METHOD(Array, toString); diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/array.h b/matlab/src/cpp/arrow/matlab/array/proxy/array.h index 94fad759759ca..c36f1900712e1 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/array.h @@ -25,7 +25,7 @@ namespace arrow::matlab::array::proxy { class Array : public libmexclass::proxy::Proxy { public: - Array(); + Array(std::shared_ptr array); virtual ~Array() {} diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc index 9a3b7ed4e22e9..bcbe49f04bb6d 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.cc @@ -23,6 +23,9 @@ namespace arrow::matlab::array::proxy { + BooleanArray::BooleanArray(std::shared_ptr array) + : arrow::matlab::array::proxy::Array{std::move(array)} {} + libmexclass::proxy::MakeResult BooleanArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { ::matlab::data::StructArray opts = constructor_arguments[0]; @@ -40,7 +43,8 @@ namespace arrow::matlab::array::proxy { const auto array_length = logical_mda.getNumberOfElements(); auto array_data = arrow::ArrayData::Make(data_type, array_length, {validity_bitmap_buffer, data_buffer}); - return std::make_shared(arrow::MakeArray(array_data)); + auto arrow_array = std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(arrow_array)); } void BooleanArray::toMATLAB(libmexclass::proxy::method::Context& context) { diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h index 6966d1090ee56..b3117d852a7d8 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/boolean_array.h @@ -20,15 +20,13 @@ #include "arrow/matlab/array/proxy/array.h" #include "libmexclass/proxy/Proxy.h" +#include "arrow/type_fwd.h" namespace arrow::matlab::array::proxy { class BooleanArray : public arrow::matlab::array::proxy::Array { public: - BooleanArray(const std::shared_ptr logical_array) - : arrow::matlab::array::proxy::Array() { - array = logical_array; - } + BooleanArray(std::shared_ptr array); static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h index 24d2565f306c9..d3930c77ca036 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/numeric_array.h @@ -27,6 +27,7 @@ #include "arrow/matlab/error/error.h" #include "arrow/matlab/bit/pack.h" #include "arrow/matlab/bit/unpack.h" +#include "arrow/matlab/buffer/matlab_buffer.h" #include "libmexclass/proxy/Proxy.h" @@ -35,14 +36,15 @@ namespace arrow::matlab::array::proxy { template class NumericArray : public arrow::matlab::array::proxy::Array { public: - NumericArray(const std::shared_ptr numeric_array) - : arrow::matlab::array::proxy::Array() { - array = numeric_array; - } + using ArrowType = typename arrow::CTypeTraits::ArrowType; - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - using ArrowType = typename arrow::CTypeTraits::ArrowType; - using BuilderType = typename arrow::CTypeTraits::BuilderType; + NumericArray(const std::shared_ptr> numeric_array) + : arrow::matlab::array::proxy::Array{std::move(numeric_array)} {} + + static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + using NumericArray = arrow::NumericArray; + using NumericArrayProxy = typename arrow::matlab::array::proxy::NumericArray; ::matlab::data::StructArray opts = constructor_arguments[0]; @@ -50,20 +52,16 @@ class NumericArray : public arrow::matlab::array::proxy::Array { const ::matlab::data::TypedArray numeric_mda = opts[0]["MatlabArray"]; const ::matlab::data::TypedArray valid_mda = opts[0]["Valid"]; - // Get raw pointer of mxArray - auto it(numeric_mda.cbegin()); - auto dt = it.operator->(); + auto data_buffer = std::make_shared(numeric_mda); const auto data_type = arrow::CTypeTraits::type_singleton(); const auto length = static_cast(numeric_mda.getNumberOfElements()); // cast size_t to int64_t - // Do not make a copy when creating arrow::Buffer - auto data_buffer = std::make_shared(reinterpret_cast(dt), - sizeof(CType) * numeric_mda.getNumberOfElements()); // Pack the validity bitmap values. MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, bit::packValid(valid_mda), error::BITPACK_VALIDITY_BITMAP_ERROR_ID); auto array_data = arrow::ArrayData::Make(data_type, length, {packed_validity_bitmap, data_buffer}); - return std::make_shared>(arrow::MakeArray(array_data)); + auto numeric_array = std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(numeric_array)); } protected: diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc index 51f39d72fca6c..2a11323a212bb 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.cc @@ -26,6 +26,9 @@ namespace arrow::matlab::array::proxy { + StringArray::StringArray(const std::shared_ptr string_array) + : arrow::matlab::array::proxy::Array(std::move(string_array)) {} + libmexclass::proxy::MakeResult StringArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { namespace mda = ::matlab::data; @@ -53,8 +56,8 @@ namespace arrow::matlab::array::proxy { arrow::StringBuilder builder; MATLAB_ERROR_IF_NOT_OK(builder.AppendValues(strings, unpacked_validity_bitmap_ptr), error::STRING_BUILDER_APPEND_FAILED); MATLAB_ASSIGN_OR_ERROR(auto array, builder.Finish(), error::STRING_BUILDER_FINISH_FAILED); - - return std::make_shared(array); + auto typed_array = std::static_pointer_cast(array); + return std::make_shared(std::move(typed_array)); } void StringArray::toMATLAB(libmexclass::proxy::method::Context& context) { diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h index de0c4625928e4..bdcfedd7cdda3 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/string_array.h @@ -21,15 +21,14 @@ #include "libmexclass/proxy/Proxy.h" +#include "arrow/type_fwd.h" + namespace arrow::matlab::array::proxy { class StringArray : public arrow::matlab::array::proxy::Array { public: - StringArray(const std::shared_ptr string_array) - : arrow::matlab::array::proxy::Array() { - array = string_array; - } - + StringArray(const std::shared_ptr string_array); + static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); protected: diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc index 3b19daec58576..17a86e848a868 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc +++ b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc @@ -20,24 +20,22 @@ #include "arrow/matlab/error/error.h" #include "arrow/matlab/bit/pack.h" #include "arrow/matlab/bit/unpack.h" +#include "arrow/matlab/buffer/matlab_buffer.h" #include "arrow/matlab/type/time_unit.h" #include "arrow/util/utf8.h" #include "arrow/type.h" -#include "arrow/builder.h" - namespace arrow::matlab::array::proxy { - namespace { - const uint8_t* getUnpackedValidityBitmap(const ::matlab::data::TypedArray& valid_elements) { - const auto valid_elements_iterator(valid_elements.cbegin()); - return reinterpret_cast(valid_elements_iterator.operator->()); - } - } // anonymous namespace + TimestampArray::TimestampArray(std::shared_ptr array) + : arrow::matlab::array::proxy::Array{std::move(array)} {} libmexclass::proxy::MakeResult TimestampArray::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { namespace mda = ::matlab::data; + using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer; + using TimestampArray = arrow::TimestampArray; + using TimestampArrayProxy = arrow::matlab::array::proxy::TimestampArray; mda::StructArray opts = constructor_arguments[0]; @@ -49,32 +47,31 @@ namespace arrow::matlab::array::proxy { const mda::TypedArray units_mda = opts[0]["TimeUnit"]; // extract the time zone string - const std::u16string& utf16_timezone = timezone_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto timezone, arrow::util::UTF16StringToUTF8(utf16_timezone), + const std::u16string& u16_timezone = timezone_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto timezone, + arrow::util::UTF16StringToUTF8(u16_timezone), error::UNICODE_CONVERSION_ERROR_ID); // extract the time unit - const std::u16string& utf16_unit = units_mda[0]; - MATLAB_ASSIGN_OR_ERROR(const auto time_unit, arrow::matlab::type::timeUnitFromString(utf16_unit), - error::UKNOWN_TIME_UNIT_ERROR_ID); + const std::u16string& u16_timeunit = units_mda[0]; + MATLAB_ASSIGN_OR_ERROR(const auto time_unit, + arrow::matlab::type::timeUnitFromString(u16_timeunit), + error::UKNOWN_TIME_UNIT_ERROR_ID) // create the timestamp_type auto data_type = arrow::timestamp(time_unit, timezone); - arrow::TimestampBuilder builder(data_type, arrow::default_memory_pool()); + auto array_length = static_cast(timestamp_mda.getNumberOfElements()); // cast size_t to int64_t - // Get raw pointer of mxArray - auto it(timestamp_mda.cbegin()); - auto dt = it.operator->(); + auto data_buffer = std::make_shared(timestamp_mda); // Pack the validity bitmap values. - const uint8_t* valid_mask = getUnpackedValidityBitmap(validity_bitmap_mda); - const auto num_elements = timestamp_mda.getNumberOfElements(); - - // Append values - MATLAB_ERROR_IF_NOT_OK(builder.AppendValues(dt, num_elements, valid_mask), error::APPEND_VALUES_ERROR_ID); - MATLAB_ASSIGN_OR_ERROR(auto timestamp_array, builder.Finish(), error::BUILD_ARRAY_ERROR_ID); + MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap, + bit::packValid(validity_bitmap_mda), + error::BITPACK_VALIDITY_BITMAP_ERROR_ID); - return std::make_shared(timestamp_array); + auto array_data = arrow::ArrayData::Make(data_type, array_length, {packed_validity_bitmap, data_buffer}); + auto timestamp_array = std::static_pointer_cast(arrow::MakeArray(array_data)); + return std::make_shared(std::move(timestamp_array)); } void TimestampArray::toMATLAB(libmexclass::proxy::method::Context& context) { diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h index ec67245564beb..8f28d6165ed2f 100644 --- a/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h +++ b/matlab/src/cpp/arrow/matlab/array/proxy/timestamp_array.h @@ -23,19 +23,17 @@ #include "libmexclass/proxy/Proxy.h" +#include "arrow/type_fwd.h" + namespace arrow::matlab::array::proxy { class TimestampArray : public arrow::matlab::array::proxy::Array { public: - TimestampArray(const std::shared_ptr timestamp_array) - : arrow::matlab::array::proxy::Array() { - array = timestamp_array; - } + TimestampArray(std::shared_ptr array); static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); protected: - void toMATLAB(libmexclass::proxy::method::Context& context) override; }; diff --git a/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h b/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h new file mode 100644 index 0000000000000..80b237544ded8 --- /dev/null +++ b/matlab/src/cpp/arrow/matlab/buffer/matlab_buffer.h @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#pragma once + +#include "arrow/buffer.h" + +#include "MatlabDataArray.hpp" + +namespace arrow::matlab::buffer { + + namespace mda = ::matlab::data; + + class MatlabBuffer : public arrow::Buffer { + public: + + template + MatlabBuffer(const mda::TypedArray typed_array) + : arrow::Buffer{nullptr, 0} + , array{typed_array} { + + // Get raw pointer of mxArray + auto it(typed_array.cbegin()); + auto dt = it.operator->(); + + data_ = reinterpret_cast(dt); + size_ = sizeof(CType) * static_cast(typed_array.getNumberOfElements()); + capacity_ = size_; + is_mutable_ = false; + } + private: + const mda::Array array; + }; +} \ No newline at end of file diff --git a/matlab/src/matlab/+arrow/+array/NumericArray.m b/matlab/src/matlab/+arrow/+array/NumericArray.m index fa692724c6458..fb2fc1d333939 100644 --- a/matlab/src/matlab/+arrow/+array/NumericArray.m +++ b/matlab/src/matlab/+arrow/+array/NumericArray.m @@ -15,11 +15,6 @@ classdef NumericArray < arrow.array.Array % arrow.array.NumericArray - - - properties (Hidden, SetAccess=protected) - MatlabArray = [] - end properties(Abstract, Access=protected) NullSubstitutionValue; @@ -38,9 +33,6 @@ validElements = arrow.args.parseValidElements(data, opts); opts = struct(MatlabArray=data, Valid=validElements); obj@arrow.array.Array("Name", proxyName, "ConstructorArguments", {opts}); - obj.MatlabArray = cast(obj.MatlabArray, type); - % Store a reference to the array - obj.MatlabArray = data; end function matlabArray = toMATLAB(obj) diff --git a/matlab/test/arrow/array/hNumericArray.m b/matlab/test/arrow/array/hNumericArray.m index 69d77c5394697..f9f5f1d9e4ee3 100644 --- a/matlab/test/arrow/array/hNumericArray.m +++ b/matlab/test/arrow/array/hNumericArray.m @@ -43,14 +43,6 @@ function BasicTest(tc) tc.verifyEqual(className, tc.ArrowArrayClassName); end - function ShallowCopyTest(tc) - % NumericArrays stores a shallow copy of the array keep the - % memory alive. - A = tc.ArrowArrayConstructor(tc.MatlabArrayFcn([1, 2, 3])); - tc.verifyEqual(A.MatlabArray, tc.MatlabArrayFcn([1, 2, 3])); - tc.verifyEqual(toMATLAB(A), tc.MatlabArrayFcn([1 2 3]')); - end - function ToMATLAB(tc) % Create array from a scalar A1 = tc.ArrowArrayConstructor(tc.MatlabArrayFcn(100)); diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake index 1a049f47d1a8f..41d2ee4a705d7 100644 --- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake +++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake @@ -38,8 +38,8 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/c "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/bit" "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/error" "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/type" - "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/type/proxy") - + "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/type/proxy" + "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/buffer") set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/array.cc" "${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/boolean_array.cc"