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 1e057e547d GH-48493: [GLib][Ruby] Add ModeOptions (#48514)
1e057e547d is described below

commit 1e057e547d2524b3381f671a5dd678309ab8662a
Author: Sten Larsson <[email protected]>
AuthorDate: Wed Dec 24 22:43:15 2025 +0100

    GH-48493: [GLib][Ruby] Add ModeOptions (#48514)
    
    ### Rationale for this change
    
    The `ModeOptions` class is not available in GLib/Ruby, and it is used 
together with the `mode` compute function.
    
    ### What changes are included in this PR?
    
    This adds the `ModeOptions` class to GLib.
    
    ### Are these changes tested?
    
    Yes, with Ruby unit tests.
    
    ### Are there any user-facing changes?
    
    Yes, a new class.
    
    * GitHub Issue: #48493
    
    Authored-by: Sten Larsson <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 c_glib/arrow-glib/compute.cpp    | 164 +++++++++++++++++++++++++++++++++++++++
 c_glib/arrow-glib/compute.h      |  13 ++++
 c_glib/arrow-glib/compute.hpp    |   5 ++
 c_glib/test/test-mode-options.rb |  68 ++++++++++++++++
 4 files changed, 250 insertions(+)

diff --git a/c_glib/arrow-glib/compute.cpp b/c_glib/arrow-glib/compute.cpp
index 3ddaae2532..d733bceb53 100644
--- a/c_glib/arrow-glib/compute.cpp
+++ b/c_glib/arrow-glib/compute.cpp
@@ -285,6 +285,8 @@ G_BEGIN_DECLS
  * #GArrowListSliceOptions is a class to customize the `list_slice`
  * function.
  *
+ * #GArrowModeOptions is a class to customize the `mode` function.
+ *
  * There are many functions to compute data on an array.
  */
 
@@ -7878,6 +7880,142 @@ garrow_list_slice_options_new(void)
   return GARROW_LIST_SLICE_OPTIONS(options);
 }
 
+enum {
+  PROP_MODE_OPTIONS_N = 1,
+  PROP_MODE_OPTIONS_SKIP_NULLS,
+  PROP_MODE_OPTIONS_MIN_COUNT,
+};
+
+G_DEFINE_TYPE(GArrowModeOptions, garrow_mode_options, 
GARROW_TYPE_FUNCTION_OPTIONS)
+
+static void
+garrow_mode_options_set_property(GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+  auto options = garrow_mode_options_get_raw(GARROW_MODE_OPTIONS(object));
+
+  switch (prop_id) {
+  case PROP_MODE_OPTIONS_N:
+    options->n = g_value_get_int64(value);
+    break;
+  case PROP_MODE_OPTIONS_SKIP_NULLS:
+    options->skip_nulls = g_value_get_boolean(value);
+    break;
+  case PROP_MODE_OPTIONS_MIN_COUNT:
+    options->min_count = g_value_get_uint(value);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_mode_options_get_property(GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+  auto options = garrow_mode_options_get_raw(GARROW_MODE_OPTIONS(object));
+
+  switch (prop_id) {
+  case PROP_MODE_OPTIONS_N:
+    g_value_set_int64(value, options->n);
+    break;
+  case PROP_MODE_OPTIONS_SKIP_NULLS:
+    g_value_set_boolean(value, options->skip_nulls);
+    break;
+  case PROP_MODE_OPTIONS_MIN_COUNT:
+    g_value_set_uint(value, options->min_count);
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_mode_options_init(GArrowModeOptions *object)
+{
+  auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object);
+  priv->options =
+    static_cast<arrow::compute::FunctionOptions *>(new 
arrow::compute::ModeOptions());
+}
+
+static void
+garrow_mode_options_class_init(GArrowModeOptionsClass *klass)
+{
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->set_property = garrow_mode_options_set_property;
+  gobject_class->get_property = garrow_mode_options_get_property;
+
+  arrow::compute::ModeOptions options;
+
+  GParamSpec *spec;
+  /**
+   * GArrowModeOptions:n:
+   *
+   * Number of distinct most-common values to return.
+   *
+   * Since: 23.0.0
+   */
+  spec = g_param_spec_int64("n",
+                            "N",
+                            "Number of distinct most-common values to return",
+                            1,
+                            G_MAXINT64,
+                            options.n,
+                            static_cast<GParamFlags>(G_PARAM_READWRITE));
+  g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_N, spec);
+
+  /**
+   * GArrowModeOptions:skip-nulls:
+   *
+   * Whether NULLs are skipped or not.
+   *
+   * Since: 23.0.0
+   */
+  spec = g_param_spec_boolean("skip-nulls",
+                              "Skip NULLs",
+                              "Whether NULLs are skipped or not",
+                              options.skip_nulls,
+                              static_cast<GParamFlags>(G_PARAM_READWRITE));
+  g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_SKIP_NULLS, 
spec);
+
+  /**
+   * GArrowModeOptions:min-count:
+   *
+   * If less than this many non-null values are observed, emit null.
+   *
+   * Since: 23.0.0
+   */
+  spec =
+    g_param_spec_uint("min-count",
+                      "Min count",
+                      "If less than this many non-null values are observed, 
emit null",
+                      0,
+                      G_MAXUINT,
+                      options.min_count,
+                      static_cast<GParamFlags>(G_PARAM_READWRITE));
+  g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_MIN_COUNT, 
spec);
+}
+
+/**
+ * garrow_mode_options_new:
+ *
+ * Returns: A newly created #GArrowModeOptions.
+ *
+ * Since: 23.0.0
+ */
+GArrowModeOptions *
+garrow_mode_options_new(void)
+{
+  return GARROW_MODE_OPTIONS(g_object_new(GARROW_TYPE_MODE_OPTIONS, NULL));
+}
+
 G_END_DECLS
 
 arrow::Result<arrow::FieldRef>
@@ -8062,6 +8200,11 @@ garrow_function_options_new_raw(const 
arrow::compute::FunctionOptions *arrow_opt
       static_cast<const arrow::compute::MapLookupOptions *>(arrow_options);
     auto options = garrow_map_lookup_options_new_raw(arrow_map_lookup_options);
     return GARROW_FUNCTION_OPTIONS(options);
+  } else if (arrow_type_name == "ModeOptions") {
+    const auto arrow_mode_options =
+      static_cast<const arrow::compute::ModeOptions *>(arrow_options);
+    auto options = garrow_mode_options_new_raw(arrow_mode_options);
+    return GARROW_FUNCTION_OPTIONS(options);
   } else {
     auto options = g_object_new(GARROW_TYPE_FUNCTION_OPTIONS, NULL);
     return GARROW_FUNCTION_OPTIONS(options);
@@ -8815,3 +8958,24 @@ garrow_list_slice_options_get_raw(GArrowListSliceOptions 
*options)
   return static_cast<arrow::compute::ListSliceOptions *>(
     garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
 }
+
+GArrowModeOptions *
+garrow_mode_options_new_raw(const arrow::compute::ModeOptions *arrow_options)
+{
+  auto options = g_object_new(GARROW_TYPE_MODE_OPTIONS,
+                              "n",
+                              arrow_options->n,
+                              "skip-nulls",
+                              arrow_options->skip_nulls,
+                              "min-count",
+                              arrow_options->min_count,
+                              NULL);
+  return GARROW_MODE_OPTIONS(options);
+}
+
+arrow::compute::ModeOptions *
+garrow_mode_options_get_raw(GArrowModeOptions *options)
+{
+  return static_cast<arrow::compute::ModeOptions *>(
+    garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
+}
diff --git a/c_glib/arrow-glib/compute.h b/c_glib/arrow-glib/compute.h
index 065cf11451..290a91ca0e 100644
--- a/c_glib/arrow-glib/compute.h
+++ b/c_glib/arrow-glib/compute.h
@@ -1420,4 +1420,17 @@ GARROW_AVAILABLE_IN_23_0
 GArrowListSliceOptions *
 garrow_list_slice_options_new(void);
 
+#define GARROW_TYPE_MODE_OPTIONS (garrow_mode_options_get_type())
+GARROW_AVAILABLE_IN_23_0
+G_DECLARE_DERIVABLE_TYPE(
+  GArrowModeOptions, garrow_mode_options, GARROW, MODE_OPTIONS, 
GArrowFunctionOptions)
+struct _GArrowModeOptionsClass
+{
+  GArrowFunctionOptionsClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_23_0
+GArrowModeOptions *
+garrow_mode_options_new(void);
+
 G_END_DECLS
diff --git a/c_glib/arrow-glib/compute.hpp b/c_glib/arrow-glib/compute.hpp
index 15b365af33..7bb93bcee9 100644
--- a/c_glib/arrow-glib/compute.hpp
+++ b/c_glib/arrow-glib/compute.hpp
@@ -236,3 +236,8 @@ GArrowListSliceOptions *
 garrow_list_slice_options_new_raw(const arrow::compute::ListSliceOptions 
*arrow_options);
 arrow::compute::ListSliceOptions *
 garrow_list_slice_options_get_raw(GArrowListSliceOptions *options);
+
+GArrowModeOptions *
+garrow_mode_options_new_raw(const arrow::compute::ModeOptions *arrow_options);
+arrow::compute::ModeOptions *
+garrow_mode_options_get_raw(GArrowModeOptions *options);
diff --git a/c_glib/test/test-mode-options.rb b/c_glib/test/test-mode-options.rb
new file mode 100644
index 0000000000..657e395a41
--- /dev/null
+++ b/c_glib/test/test-mode-options.rb
@@ -0,0 +1,68 @@
+# 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 TestModeOptions < Test::Unit::TestCase
+  include Helper::Buildable
+
+  def setup
+    @options = Arrow::ModeOptions.new
+  end
+
+  def test_n
+    assert_equal(1, @options.n)
+    @options.n = 2
+    assert_equal(2, @options.n)
+  end
+
+  def test_skip_nulls
+    assert do
+      @options.skip_nulls?
+    end
+    @options.skip_nulls = false
+    assert do
+      not @options.skip_nulls?
+    end
+  end
+
+  def test_min_count
+    assert_equal(0, @options.min_count)
+    @options.min_count = 1
+    assert_equal(1, @options.min_count)
+  end
+
+  def test_mode_function_with_all_options
+    args = [
+      Arrow::ArrayDatum.new(build_int32_array([1, 2, 2, 3, 3, 3, 4])),
+    ]
+    @options.n = 2
+    @options.skip_nulls = false
+    @options.min_count = 2
+    mode_function = Arrow::Function.find("mode")
+    result = mode_function.execute(args, @options).value
+    expected = build_struct_array(
+      [
+        Arrow::Field.new("mode", Arrow::Int32DataType.new),
+        Arrow::Field.new("count", Arrow::Int64DataType.new),
+      ],
+      [
+        {"mode" => 3, "count" => 3},
+        {"mode" => 2, "count" => 2},
+      ]
+    )
+    assert_equal(expected, result)
+  end
+end

Reply via email to