Repository: arrow Updated Branches: refs/heads/master 6443b8287 -> 9db96fea4
ARROW-811: [GLib] Add GArrowBuffer Author: Kouhei Sutou <[email protected]> Closes #531 from kou/glib-add-buffer and squashes the following commits: 1954c95 [Kouhei Sutou] [GLib] Add GArrowBuffer Project: http://git-wip-us.apache.org/repos/asf/arrow/repo Commit: http://git-wip-us.apache.org/repos/asf/arrow/commit/9db96fea Tree: http://git-wip-us.apache.org/repos/asf/arrow/tree/9db96fea Diff: http://git-wip-us.apache.org/repos/asf/arrow/diff/9db96fea Branch: refs/heads/master Commit: 9db96fea4e5de59860a481da3036b3129eb97e3b Parents: 6443b82 Author: Kouhei Sutou <[email protected]> Authored: Wed Apr 12 12:23:22 2017 -0400 Committer: Wes McKinney <[email protected]> Committed: Wed Apr 12 12:23:22 2017 -0400 ---------------------------------------------------------------------- c_glib/arrow-glib/Makefile.am | 7 +- c_glib/arrow-glib/buffer.cpp | 289 +++++++++++++++++++++++++ c_glib/arrow-glib/buffer.h | 77 +++++++ c_glib/arrow-glib/buffer.hpp | 27 +++ c_glib/doc/reference/arrow-glib-docs.sgml | 4 + c_glib/test/test-buffer.rb | 55 +++++ 6 files changed, 457 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/arrow-glib/Makefile.am ---------------------------------------------------------------------- diff --git a/c_glib/arrow-glib/Makefile.am b/c_glib/arrow-glib/Makefile.am index 387707c..2e7a9a0 100644 --- a/c_glib/arrow-glib/Makefile.am +++ b/c_glib/arrow-glib/Makefile.am @@ -44,14 +44,15 @@ libarrow_glib_la_headers = \ array.h \ array-builder.h \ arrow-glib.h \ - chunked-array.h \ - column.h \ binary-array.h \ binary-array-builder.h \ binary-data-type.h \ boolean-array.h \ boolean-array-builder.h \ boolean-data-type.h \ + buffer.h \ + chunked-array.h \ + column.h \ data-type.h \ double-array.h \ double-array-builder.h \ @@ -136,6 +137,7 @@ libarrow_glib_la_sources = \ boolean-array.cpp \ boolean-array-builder.cpp \ boolean-data-type.cpp \ + buffer.cpp \ chunked-array.cpp \ column.cpp \ data-type.cpp \ @@ -212,6 +214,7 @@ libarrow_glib_la_cpp_headers = \ array.hpp \ array-builder.hpp \ arrow-glib.hpp \ + buffer.hpp \ chunked-array.hpp \ column.hpp \ data-type.hpp \ http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/arrow-glib/buffer.cpp ---------------------------------------------------------------------- diff --git a/c_glib/arrow-glib/buffer.cpp b/c_glib/arrow-glib/buffer.cpp new file mode 100644 index 0000000..0ec52df --- /dev/null +++ b/c_glib/arrow-glib/buffer.cpp @@ -0,0 +1,289 @@ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <arrow-glib/buffer.hpp> +#include <arrow-glib/error.hpp> + +G_BEGIN_DECLS + +/** + * SECTION: buffer + * @short_description: Buffer class + * + * #GArrowBuffer is a class for keeping data. Other classes such as + * #GArrowArray and #GArrowTensor can use data in buffer. + */ + +typedef struct GArrowBufferPrivate_ { + std::shared_ptr<arrow::Buffer> buffer; +} GArrowBufferPrivate; + +enum { + PROP_0, + PROP_BUFFER +}; + +G_DEFINE_TYPE_WITH_PRIVATE(GArrowBuffer, garrow_buffer, G_TYPE_OBJECT) + +#define GARROW_BUFFER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE((obj), GARROW_TYPE_BUFFER, GArrowBufferPrivate)) + +static void +garrow_buffer_finalize(GObject *object) +{ + auto priv = GARROW_BUFFER_GET_PRIVATE(object); + + priv->buffer = nullptr; + + G_OBJECT_CLASS(garrow_buffer_parent_class)->finalize(object); +} + +static void +garrow_buffer_set_property(GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + auto priv = GARROW_BUFFER_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_BUFFER: + priv->buffer = + *static_cast<std::shared_ptr<arrow::Buffer> *>(g_value_get_pointer(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_buffer_get_property(GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +garrow_buffer_init(GArrowBuffer *object) +{ +} + +static void +garrow_buffer_class_init(GArrowBufferClass *klass) +{ + GParamSpec *spec; + + auto gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->finalize = garrow_buffer_finalize; + gobject_class->set_property = garrow_buffer_set_property; + gobject_class->get_property = garrow_buffer_get_property; + + spec = g_param_spec_pointer("buffer", + "Buffer", + "The raw std::shared<arrow::Buffer> *", + static_cast<GParamFlags>(G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(gobject_class, PROP_BUFFER, spec); +} + +/** + * garrow_buffer_new: + * @data: (array length=size): Data for the buffer. + * They aren't owned by the new buffer. + * You must not free the data while the new buffer is alive. + * @size: The number of bytes of the data. + * + * Returns: A newly created #GArrowBuffer. + * + * Since: 0.3.0 + */ +GArrowBuffer * +garrow_buffer_new(const guint8 *data, gint64 size) +{ + auto arrow_buffer = std::make_shared<arrow::Buffer>(data, size); + return garrow_buffer_new_raw(&arrow_buffer); + +} + +/** + * garrow_buffer_is_mutable: + * @buffer: A #GArrowBuffer. + * + * Returns: %TRUE if the buffer is mutable, %FALSE otherwise. + * + * Since: 0.3.0 + */ +gboolean +garrow_buffer_is_mutable(GArrowBuffer *buffer) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + return arrow_buffer->is_mutable(); +} + +/** + * garrow_buffer_get_capacity: + * @buffer: A #GArrowBuffer. + * + * Returns: The number of bytes that where allocated for the buffer in + * total. + * + * Since: 0.3.0 + */ +gint64 +garrow_buffer_get_capacity(GArrowBuffer *buffer) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + return arrow_buffer->capacity(); +} + +/** + * garrow_buffer_get_data: + * @buffer: A #GArrowBuffer. + * @size: (out): The number of bytes of the data. + * + * Returns: (array length=size): The data of the buffer. + * + * Since: 0.3.0 + */ +const guint8 * +garrow_buffer_get_data(GArrowBuffer *buffer, gint64 *size) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + *size = arrow_buffer->size(); + return arrow_buffer->data(); +} + +/** + * garrow_buffer_get_size: + * @buffer: A #GArrowBuffer. + * + * Returns: The number of bytes that might have valid data. + * + * Since: 0.3.0 + */ +gint64 +garrow_buffer_get_size(GArrowBuffer *buffer) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + return arrow_buffer->size(); +} + +/** + * garrow_buffer_get_parent: + * @buffer: A #GArrowBuffer. + * + * Returns: (nullable) (transfer full): + * The parent #GArrowBuffer or %NULL. + * + * Since: 0.3.0 + */ +GArrowBuffer * +garrow_buffer_get_parent(GArrowBuffer *buffer) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + auto arrow_parent_buffer = arrow_buffer->parent(); + + if (arrow_parent_buffer) { + return garrow_buffer_new_raw(&arrow_parent_buffer); + } else { + return NULL; + } +} + +/** + * garrow_buffer_copy: + * @buffer: A #GArrowBuffer. + * @start: An offset of data to be copied in byte. + * @size: The number of bytes to be copied from the start. + * @error: (nullable): Return location for a #GError or %NULL. + * + * Returns: (nullable) (transfer full): + * A newly copied #GArrowBuffer on success, %NULL on error. + * + * Since: 0.3.0 + */ +GArrowBuffer * +garrow_buffer_copy(GArrowBuffer *buffer, + gint64 start, + gint64 size, + GError **error) +{ + auto arrow_buffer = garrow_buffer_get_raw(buffer); + std::shared_ptr<arrow::Buffer> arrow_copied_buffer; + auto status = arrow_buffer->Copy(start, size, &arrow_copied_buffer); + if (status.ok()) { + return garrow_buffer_new_raw(&arrow_copied_buffer); + } else { + garrow_error_set(error, status, "[buffer][copy]"); + return NULL; + } +} + +/** + * garrow_buffer_slice: + * @buffer: A #GArrowBuffer. + * @offset: An offset in the buffer data in byte. + * @size: The number of bytes of the sliced data. + * + * Returns: (transfer full): A newly created #GArrowBuffer that shares + * data of the base #GArrowBuffer. The created #GArrowBuffer has data + * start with offset from the base buffer data and are the specified + * bytes size. + * + * Since: 0.3.0 + */ +GArrowBuffer * +garrow_buffer_slice(GArrowBuffer *buffer, gint64 offset, gint64 size) +{ + auto arrow_parent_buffer = garrow_buffer_get_raw(buffer); + auto arrow_buffer = std::make_shared<arrow::Buffer>(arrow_parent_buffer, + offset, + size); + return garrow_buffer_new_raw(&arrow_buffer); +} + +G_END_DECLS + +GArrowBuffer * +garrow_buffer_new_raw(std::shared_ptr<arrow::Buffer> *arrow_buffer) +{ + auto buffer = GARROW_BUFFER(g_object_new(GARROW_TYPE_BUFFER, + "buffer", arrow_buffer, + NULL)); + return buffer; +} + +std::shared_ptr<arrow::Buffer> +garrow_buffer_get_raw(GArrowBuffer *buffer) +{ + auto priv = GARROW_BUFFER_GET_PRIVATE(buffer); + return priv->buffer; +} http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/arrow-glib/buffer.h ---------------------------------------------------------------------- diff --git a/c_glib/arrow-glib/buffer.h b/c_glib/arrow-glib/buffer.h new file mode 100644 index 0000000..1e7d551 --- /dev/null +++ b/c_glib/arrow-glib/buffer.h @@ -0,0 +1,77 @@ +/* + * 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 <glib-object.h> + +G_BEGIN_DECLS + +#define GARROW_TYPE_BUFFER \ + (garrow_buffer_get_type()) +#define GARROW_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GARROW_TYPE_BUFFER, GArrowBuffer)) +#define GARROW_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), GARROW_TYPE_BUFFER, GArrowBufferClass)) +#define GARROW_IS_BUFFER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GARROW_TYPE_BUFFER)) +#define GARROW_IS_BUFFER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GARROW_TYPE_BUFFER)) +#define GARROW_BUFFER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), GARROW_TYPE_BUFFER, GArrowBufferClass)) + +typedef struct _GArrowBuffer GArrowBuffer; +typedef struct _GArrowBufferClass GArrowBufferClass; + +/** + * GArrowBuffer: + * + * It wraps `arrow::Buffer`. + */ +struct _GArrowBuffer +{ + /*< private >*/ + GObject parent_instance; +}; + +struct _GArrowBufferClass +{ + GObjectClass parent_class; +}; + +GType garrow_buffer_get_type (void) G_GNUC_CONST; + +GArrowBuffer *garrow_buffer_new (const guint8 *data, + gint64 size); +gboolean garrow_buffer_is_mutable (GArrowBuffer *buffer); +gint64 garrow_buffer_get_capacity (GArrowBuffer *buffer); +const guint8 *garrow_buffer_get_data (GArrowBuffer *buffer, + gint64 *size); +gint64 garrow_buffer_get_size (GArrowBuffer *buffer); +GArrowBuffer *garrow_buffer_get_parent (GArrowBuffer *buffer); + +GArrowBuffer *garrow_buffer_copy (GArrowBuffer *buffer, + gint64 start, + gint64 size, + GError **error); +GArrowBuffer *garrow_buffer_slice (GArrowBuffer *buffer, + gint64 offset, + gint64 size); + +G_END_DECLS http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/arrow-glib/buffer.hpp ---------------------------------------------------------------------- diff --git a/c_glib/arrow-glib/buffer.hpp b/c_glib/arrow-glib/buffer.hpp new file mode 100644 index 0000000..00dd3de --- /dev/null +++ b/c_glib/arrow-glib/buffer.hpp @@ -0,0 +1,27 @@ +/* + * 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/api.h> + +#include <arrow-glib/buffer.h> + +GArrowBuffer *garrow_buffer_new_raw(std::shared_ptr<arrow::Buffer> *arrow_buffer); +std::shared_ptr<arrow::Buffer> garrow_buffer_get_raw(GArrowBuffer *buffer); http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/doc/reference/arrow-glib-docs.sgml ---------------------------------------------------------------------- diff --git a/c_glib/doc/reference/arrow-glib-docs.sgml b/c_glib/doc/reference/arrow-glib-docs.sgml index 396dce5..3c1d8d1 100644 --- a/c_glib/doc/reference/arrow-glib-docs.sgml +++ b/c_glib/doc/reference/arrow-glib-docs.sgml @@ -105,6 +105,10 @@ <xi:include href="xml/column.xml"/> <xi:include href="xml/chunked-array.xml"/> </chapter> + <chapter id="buffer"> + <title>Buffer</title> + <xi:include href="xml/buffer.xml"/> + </chapter> <chapter id="error"> <title>Error</title> <xi:include href="xml/error.xml"/> http://git-wip-us.apache.org/repos/asf/arrow/blob/9db96fea/c_glib/test/test-buffer.rb ---------------------------------------------------------------------- diff --git a/c_glib/test/test-buffer.rb b/c_glib/test/test-buffer.rb new file mode 100644 index 0000000..1ea26f2 --- /dev/null +++ b/c_glib/test/test-buffer.rb @@ -0,0 +1,55 @@ +# 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. + +class TestBuffer < Test::Unit::TestCase + def setup + @data = "Hello" + @buffer = Arrow::Buffer.new(@data) + end + + def test_mutable? + assert do + not @buffer.mutable? + end + end + + def test_capacity + assert_equal(@data.bytesize, @buffer.capacity) + end + + def test_data + assert_equal(@data, @buffer.data.pack("C*")) + end + + def test_size + assert_equal(@data.bytesize, @buffer.size) + end + + def test_parent + assert_nil(@buffer.parent) + end + + def test_copy + copied_buffer = @buffer.copy(1, 3) + assert_equal(@data[1, 3], copied_buffer.data.pack("C*")) + end + + def test_slice + sliced_buffer = @buffer.slice(1, 3) + assert_equal(@data[1, 3], sliced_buffer.data.pack("C*")) + end +end
