This is an automated email from the ASF dual-hosted git repository.
kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new e79d60d943 GH-45486: [GLib] Add `GArrowArrayStatistics` (#45490)
e79d60d943 is described below
commit e79d60d943700494143c2b1d4e52041a555c901d
Author: Sutou Kouhei <[email protected]>
AuthorDate: Wed Feb 12 14:48:07 2025 +0900
GH-45486: [GLib] Add `GArrowArrayStatistics` (#45490)
### Rationale for this change
GLib should be able to use `arrow::ArrayStatistics`.
### What changes are included in this PR?
Add `GArrowArrayStatistics` with minimal features.
### Are these changes tested?
Yes.
### Are there any user-facing changes?
Yes.
* GitHub Issue: #45486
Authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
c_glib/arrow-glib/basic-array.cpp | 130 +++++++++++++++++++++++++++++++++++
c_glib/arrow-glib/basic-array.h | 20 ++++++
c_glib/arrow-glib/basic-array.hpp | 4 ++
c_glib/test/test-array-statistics.rb | 51 ++++++++++++++
4 files changed, 205 insertions(+)
diff --git a/c_glib/arrow-glib/basic-array.cpp
b/c_glib/arrow-glib/basic-array.cpp
index 0704687fed..a2e0fdef25 100644
--- a/c_glib/arrow-glib/basic-array.cpp
+++ b/c_glib/arrow-glib/basic-array.cpp
@@ -37,6 +37,8 @@ G_BEGIN_DECLS
* @title: Basic array classes
* @include: arrow-glib/arrow-glib.h
*
+ * #GArrowArrayStatistics is a class for statistics of an array.
+ *
* #GArrowArray is a base class for all array classes such as
* #GArrowBooleanArray.
*
@@ -364,6 +366,106 @@ garrow_equal_options_is_approx(GArrowEqualOptions
*options)
return priv->approx;
}
+struct GArrowArrayStatisticsPrivate
+{
+ arrow::ArrayStatistics statistics;
+};
+
+enum {
+ PROP_STATISTICS = 1,
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowArrayStatistics, garrow_array_statistics,
G_TYPE_OBJECT)
+
+#define GARROW_ARRAY_STATISTICS_GET_PRIVATE(object)
\
+ static_cast<GArrowArrayStatisticsPrivate *>(
\
+
garrow_array_statistics_get_instance_private(GARROW_ARRAY_STATISTICS(object)))
+
+static void
+garrow_array_statistics_finalize(GObject *object)
+{
+ auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);
+ priv->statistics.~ArrayStatistics();
+ G_OBJECT_CLASS(garrow_array_statistics_parent_class)->finalize(object);
+}
+
+static void
+garrow_array_statistics_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_STATISTICS:
+ priv->statistics = *static_cast<arrow::ArrayStatistics
*>(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_array_statistics_init(GArrowArrayStatistics *object)
+{
+ auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(object);
+ new (&priv->statistics) arrow::ArrayStatistics;
+}
+
+static void
+garrow_array_statistics_class_init(GArrowArrayStatisticsClass *klass)
+{
+ auto gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->finalize = garrow_array_statistics_finalize;
+ gobject_class->set_property = garrow_array_statistics_set_property;
+
+ auto spec = g_param_spec_pointer(
+ "statistics",
+ "Statistics",
+ "The raw arrow::ArrayStatistics *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_STATISTICS, spec);
+}
+
+/**
+ * garrow_array_statistics_has_null_count:
+ * @statistics: A #GArrowArrayStatistics.
+ *
+ * Returns: %TRUE if @statistics has a valid null count value,
+ * %FALSE otherwise.
+ *
+ * Since: 20.0.0
+ */
+gboolean
+garrow_array_statistics_has_null_count(GArrowArrayStatistics *statistics)
+{
+ auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
+ return priv->statistics.null_count.has_value();
+}
+
+/**
+ * garrow_array_statistics_get_null_count:
+ * @statistics: A #GArrowArrayStatistics.
+ *
+ * Returns: 0 or larger value if @statistics has a valid null count value,
+ * -1 otherwise.
+ *
+ * Since: 20.0.0
+ */
+gint64
+garrow_array_statistics_get_null_count(GArrowArrayStatistics *statistics)
+{
+ auto priv = GARROW_ARRAY_STATISTICS_GET_PRIVATE(statistics);
+ const auto &null_count = priv->statistics.null_count;
+ if (null_count) {
+ return null_count.value();
+ } else {
+ return -1;
+ }
+}
+
typedef struct GArrowArrayPrivate_
{
std::shared_ptr<arrow::Array> array;
@@ -1049,6 +1151,27 @@ garrow_array_validate_full(GArrowArray *array, GError
**error)
return garrow::check(error, arrow_array->ValidateFull(),
"[array][validate-full]");
}
+/**
+ * garrow_array_get_statistics:
+ * @array: A #GArrowArray.
+ *
+ * Returns: (transfer full): The associated #GArrowArrayStatistics of @array,
+ * %NULL if @array doesn't have any associated statistics.
+ *
+ * Since: 20.0.0
+ */
+GArrowArrayStatistics *
+garrow_array_get_statistics(GArrowArray *array)
+{
+ const auto arrow_array = garrow_array_get_raw(array);
+ const auto &statistics = arrow_array->statistics();
+ if (statistics) {
+ return garrow_array_statistics_new_raw(statistics.get());
+ } else {
+ return nullptr;
+ }
+}
+
G_DEFINE_TYPE(GArrowNullArray, garrow_null_array, GARROW_TYPE_ARRAY)
static void
@@ -3468,6 +3591,13 @@ garrow_equal_options_get_raw(GArrowEqualOptions
*equal_options)
return &(priv->options);
}
+GArrowArrayStatistics *
+garrow_array_statistics_new_raw(arrow::ArrayStatistics *arrow_statistics)
+{
+ return GARROW_ARRAY_STATISTICS(
+ g_object_new(GARROW_TYPE_ARRAY_STATISTICS, "statistics", arrow_statistics,
nullptr));
+}
+
GArrowArray *
garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array)
{
diff --git a/c_glib/arrow-glib/basic-array.h b/c_glib/arrow-glib/basic-array.h
index bc597a8a93..8e13afbf57 100644
--- a/c_glib/arrow-glib/basic-array.h
+++ b/c_glib/arrow-glib/basic-array.h
@@ -42,6 +42,22 @@ GARROW_AVAILABLE_IN_5_0
gboolean
garrow_equal_options_is_approx(GArrowEqualOptions *options);
+#define GARROW_TYPE_ARRAY_STATISTICS (garrow_array_statistics_get_type())
+GARROW_AVAILABLE_IN_20_0
+G_DECLARE_DERIVABLE_TYPE(
+ GArrowArrayStatistics, garrow_array_statistics, GARROW, ARRAY_STATISTICS,
GObject)
+struct _GArrowArrayStatisticsClass
+{
+ GObjectClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_20_0
+gboolean
+garrow_array_statistics_has_null_count(GArrowArrayStatistics *statistics);
+GARROW_AVAILABLE_IN_20_0
+gint64
+garrow_array_statistics_get_null_count(GArrowArrayStatistics *statistics);
+
GARROW_AVAILABLE_IN_6_0
GArrowArray *
garrow_array_import(gpointer c_abi_array, GArrowDataType *data_type, GError
**error);
@@ -134,6 +150,10 @@ GARROW_AVAILABLE_IN_20_0
gboolean
garrow_array_validate_full(GArrowArray *array, GError **error);
+GARROW_AVAILABLE_IN_20_0
+GArrowArrayStatistics *
+garrow_array_get_statistics(GArrowArray *array);
+
#define GARROW_TYPE_NULL_ARRAY (garrow_null_array_get_type())
GARROW_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE(
diff --git a/c_glib/arrow-glib/basic-array.hpp
b/c_glib/arrow-glib/basic-array.hpp
index b2a7ed6ae0..361d367773 100644
--- a/c_glib/arrow-glib/basic-array.hpp
+++ b/c_glib/arrow-glib/basic-array.hpp
@@ -27,6 +27,10 @@ GARROW_EXTERN
arrow::EqualOptions *
garrow_equal_options_get_raw(GArrowEqualOptions *equal_options);
+GARROW_EXTERN
+GArrowArrayStatistics *
+garrow_array_statistics_new_raw(arrow::ArrayStatistics *arrow_statistics);
+
GARROW_EXTERN
GArrowArray *
garrow_array_new_raw(std::shared_ptr<arrow::Array> *arrow_array);
diff --git a/c_glib/test/test-array-statistics.rb
b/c_glib/test/test-array-statistics.rb
new file mode 100644
index 0000000000..bf470b4e72
--- /dev/null
+++ b/c_glib/test/test-array-statistics.rb
@@ -0,0 +1,51 @@
+# 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 TestArrayStatistics < Test::Unit::TestCase
+ include Helper::Buildable
+
+ def setup
+ omit("Parquet is required") unless defined?(::Parquet)
+
+ Tempfile.create(["data", ".parquet"]) do |file|
+ @file = file
+ array = build_int64_array([nil, -(2 ** 32), 2 ** 32])
+ @table = build_table("int64" => array)
+ writer = Parquet::ArrowFileWriter.new(@table.schema, @file.path)
+ chunk_size = 1024
+ writer.write_table(@table, chunk_size)
+ writer.close
+ reader = Parquet::ArrowFileReader.new(@file.path)
+ begin
+ @statistics =
reader.read_table.get_column_data(0).get_chunk(0).statistics
+ yield
+ ensure
+ reader.unref
+ end
+ end
+ end
+
+ test("#has_null_count?") do
+ assert do
+ @statistics.has_null_count?
+ end
+ end
+
+ test("#null_count") do
+ assert_equal(1, @statistics.null_count)
+ end
+end