Skip to content

Commit 1e057e5

Browse files
authored
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]>
1 parent 3dc9821 commit 1e057e5

File tree

4 files changed

+250
-0
lines changed

4 files changed

+250
-0
lines changed

c_glib/arrow-glib/compute.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ G_BEGIN_DECLS
285285
* #GArrowListSliceOptions is a class to customize the `list_slice`
286286
* function.
287287
*
288+
* #GArrowModeOptions is a class to customize the `mode` function.
289+
*
288290
* There are many functions to compute data on an array.
289291
*/
290292

@@ -7878,6 +7880,142 @@ garrow_list_slice_options_new(void)
78787880
return GARROW_LIST_SLICE_OPTIONS(options);
78797881
}
78807882

7883+
enum {
7884+
PROP_MODE_OPTIONS_N = 1,
7885+
PROP_MODE_OPTIONS_SKIP_NULLS,
7886+
PROP_MODE_OPTIONS_MIN_COUNT,
7887+
};
7888+
7889+
G_DEFINE_TYPE(GArrowModeOptions, garrow_mode_options, GARROW_TYPE_FUNCTION_OPTIONS)
7890+
7891+
static void
7892+
garrow_mode_options_set_property(GObject *object,
7893+
guint prop_id,
7894+
const GValue *value,
7895+
GParamSpec *pspec)
7896+
{
7897+
auto options = garrow_mode_options_get_raw(GARROW_MODE_OPTIONS(object));
7898+
7899+
switch (prop_id) {
7900+
case PROP_MODE_OPTIONS_N:
7901+
options->n = g_value_get_int64(value);
7902+
break;
7903+
case PROP_MODE_OPTIONS_SKIP_NULLS:
7904+
options->skip_nulls = g_value_get_boolean(value);
7905+
break;
7906+
case PROP_MODE_OPTIONS_MIN_COUNT:
7907+
options->min_count = g_value_get_uint(value);
7908+
break;
7909+
default:
7910+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
7911+
break;
7912+
}
7913+
}
7914+
7915+
static void
7916+
garrow_mode_options_get_property(GObject *object,
7917+
guint prop_id,
7918+
GValue *value,
7919+
GParamSpec *pspec)
7920+
{
7921+
auto options = garrow_mode_options_get_raw(GARROW_MODE_OPTIONS(object));
7922+
7923+
switch (prop_id) {
7924+
case PROP_MODE_OPTIONS_N:
7925+
g_value_set_int64(value, options->n);
7926+
break;
7927+
case PROP_MODE_OPTIONS_SKIP_NULLS:
7928+
g_value_set_boolean(value, options->skip_nulls);
7929+
break;
7930+
case PROP_MODE_OPTIONS_MIN_COUNT:
7931+
g_value_set_uint(value, options->min_count);
7932+
break;
7933+
default:
7934+
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
7935+
break;
7936+
}
7937+
}
7938+
7939+
static void
7940+
garrow_mode_options_init(GArrowModeOptions *object)
7941+
{
7942+
auto priv = GARROW_FUNCTION_OPTIONS_GET_PRIVATE(object);
7943+
priv->options =
7944+
static_cast<arrow::compute::FunctionOptions *>(new arrow::compute::ModeOptions());
7945+
}
7946+
7947+
static void
7948+
garrow_mode_options_class_init(GArrowModeOptionsClass *klass)
7949+
{
7950+
auto gobject_class = G_OBJECT_CLASS(klass);
7951+
7952+
gobject_class->set_property = garrow_mode_options_set_property;
7953+
gobject_class->get_property = garrow_mode_options_get_property;
7954+
7955+
arrow::compute::ModeOptions options;
7956+
7957+
GParamSpec *spec;
7958+
/**
7959+
* GArrowModeOptions:n:
7960+
*
7961+
* Number of distinct most-common values to return.
7962+
*
7963+
* Since: 23.0.0
7964+
*/
7965+
spec = g_param_spec_int64("n",
7966+
"N",
7967+
"Number of distinct most-common values to return",
7968+
1,
7969+
G_MAXINT64,
7970+
options.n,
7971+
static_cast<GParamFlags>(G_PARAM_READWRITE));
7972+
g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_N, spec);
7973+
7974+
/**
7975+
* GArrowModeOptions:skip-nulls:
7976+
*
7977+
* Whether NULLs are skipped or not.
7978+
*
7979+
* Since: 23.0.0
7980+
*/
7981+
spec = g_param_spec_boolean("skip-nulls",
7982+
"Skip NULLs",
7983+
"Whether NULLs are skipped or not",
7984+
options.skip_nulls,
7985+
static_cast<GParamFlags>(G_PARAM_READWRITE));
7986+
g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_SKIP_NULLS, spec);
7987+
7988+
/**
7989+
* GArrowModeOptions:min-count:
7990+
*
7991+
* If less than this many non-null values are observed, emit null.
7992+
*
7993+
* Since: 23.0.0
7994+
*/
7995+
spec =
7996+
g_param_spec_uint("min-count",
7997+
"Min count",
7998+
"If less than this many non-null values are observed, emit null",
7999+
0,
8000+
G_MAXUINT,
8001+
options.min_count,
8002+
static_cast<GParamFlags>(G_PARAM_READWRITE));
8003+
g_object_class_install_property(gobject_class, PROP_MODE_OPTIONS_MIN_COUNT, spec);
8004+
}
8005+
8006+
/**
8007+
* garrow_mode_options_new:
8008+
*
8009+
* Returns: A newly created #GArrowModeOptions.
8010+
*
8011+
* Since: 23.0.0
8012+
*/
8013+
GArrowModeOptions *
8014+
garrow_mode_options_new(void)
8015+
{
8016+
return GARROW_MODE_OPTIONS(g_object_new(GARROW_TYPE_MODE_OPTIONS, NULL));
8017+
}
8018+
78818019
G_END_DECLS
78828020

78838021
arrow::Result<arrow::FieldRef>
@@ -8062,6 +8200,11 @@ garrow_function_options_new_raw(const arrow::compute::FunctionOptions *arrow_opt
80628200
static_cast<const arrow::compute::MapLookupOptions *>(arrow_options);
80638201
auto options = garrow_map_lookup_options_new_raw(arrow_map_lookup_options);
80648202
return GARROW_FUNCTION_OPTIONS(options);
8203+
} else if (arrow_type_name == "ModeOptions") {
8204+
const auto arrow_mode_options =
8205+
static_cast<const arrow::compute::ModeOptions *>(arrow_options);
8206+
auto options = garrow_mode_options_new_raw(arrow_mode_options);
8207+
return GARROW_FUNCTION_OPTIONS(options);
80658208
} else {
80668209
auto options = g_object_new(GARROW_TYPE_FUNCTION_OPTIONS, NULL);
80678210
return GARROW_FUNCTION_OPTIONS(options);
@@ -8815,3 +8958,24 @@ garrow_list_slice_options_get_raw(GArrowListSliceOptions *options)
88158958
return static_cast<arrow::compute::ListSliceOptions *>(
88168959
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
88178960
}
8961+
8962+
GArrowModeOptions *
8963+
garrow_mode_options_new_raw(const arrow::compute::ModeOptions *arrow_options)
8964+
{
8965+
auto options = g_object_new(GARROW_TYPE_MODE_OPTIONS,
8966+
"n",
8967+
arrow_options->n,
8968+
"skip-nulls",
8969+
arrow_options->skip_nulls,
8970+
"min-count",
8971+
arrow_options->min_count,
8972+
NULL);
8973+
return GARROW_MODE_OPTIONS(options);
8974+
}
8975+
8976+
arrow::compute::ModeOptions *
8977+
garrow_mode_options_get_raw(GArrowModeOptions *options)
8978+
{
8979+
return static_cast<arrow::compute::ModeOptions *>(
8980+
garrow_function_options_get_raw(GARROW_FUNCTION_OPTIONS(options)));
8981+
}

c_glib/arrow-glib/compute.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,4 +1420,17 @@ GARROW_AVAILABLE_IN_23_0
14201420
GArrowListSliceOptions *
14211421
garrow_list_slice_options_new(void);
14221422

1423+
#define GARROW_TYPE_MODE_OPTIONS (garrow_mode_options_get_type())
1424+
GARROW_AVAILABLE_IN_23_0
1425+
G_DECLARE_DERIVABLE_TYPE(
1426+
GArrowModeOptions, garrow_mode_options, GARROW, MODE_OPTIONS, GArrowFunctionOptions)
1427+
struct _GArrowModeOptionsClass
1428+
{
1429+
GArrowFunctionOptionsClass parent_class;
1430+
};
1431+
1432+
GARROW_AVAILABLE_IN_23_0
1433+
GArrowModeOptions *
1434+
garrow_mode_options_new(void);
1435+
14231436
G_END_DECLS

c_glib/arrow-glib/compute.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,8 @@ GArrowListSliceOptions *
236236
garrow_list_slice_options_new_raw(const arrow::compute::ListSliceOptions *arrow_options);
237237
arrow::compute::ListSliceOptions *
238238
garrow_list_slice_options_get_raw(GArrowListSliceOptions *options);
239+
240+
GArrowModeOptions *
241+
garrow_mode_options_new_raw(const arrow::compute::ModeOptions *arrow_options);
242+
arrow::compute::ModeOptions *
243+
garrow_mode_options_get_raw(GArrowModeOptions *options);

c_glib/test/test-mode-options.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
class TestModeOptions < Test::Unit::TestCase
19+
include Helper::Buildable
20+
21+
def setup
22+
@options = Arrow::ModeOptions.new
23+
end
24+
25+
def test_n
26+
assert_equal(1, @options.n)
27+
@options.n = 2
28+
assert_equal(2, @options.n)
29+
end
30+
31+
def test_skip_nulls
32+
assert do
33+
@options.skip_nulls?
34+
end
35+
@options.skip_nulls = false
36+
assert do
37+
not @options.skip_nulls?
38+
end
39+
end
40+
41+
def test_min_count
42+
assert_equal(0, @options.min_count)
43+
@options.min_count = 1
44+
assert_equal(1, @options.min_count)
45+
end
46+
47+
def test_mode_function_with_all_options
48+
args = [
49+
Arrow::ArrayDatum.new(build_int32_array([1, 2, 2, 3, 3, 3, 4])),
50+
]
51+
@options.n = 2
52+
@options.skip_nulls = false
53+
@options.min_count = 2
54+
mode_function = Arrow::Function.find("mode")
55+
result = mode_function.execute(args, @options).value
56+
expected = build_struct_array(
57+
[
58+
Arrow::Field.new("mode", Arrow::Int32DataType.new),
59+
Arrow::Field.new("count", Arrow::Int64DataType.new),
60+
],
61+
[
62+
{"mode" => 3, "count" => 3},
63+
{"mode" => 2, "count" => 2},
64+
]
65+
)
66+
assert_equal(expected, result)
67+
end
68+
end

0 commit comments

Comments
 (0)