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

Reply via email to