carray 3.0.3 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +78 -10
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +11 -4
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +182 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +53 -36
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/ruby_carray.c
CHANGED
|
@@ -38,6 +38,7 @@ void Init_carray_attribute ();
|
|
|
38
38
|
void Init_carray_loop ();
|
|
39
39
|
void Init_carray_mask ();
|
|
40
40
|
void Init_carray_hold ();
|
|
41
|
+
void Init_carray_key_windows ();
|
|
41
42
|
void Init_carray_mask_fast_paths (); /* patches generated bit-op tables;
|
|
42
43
|
must run AFTER Init_ca_op_ipower */
|
|
43
44
|
void Init_carray_access ();
|
|
@@ -60,6 +61,7 @@ void Init_carray_median_percentile (); /* median / percentile / quantile */
|
|
|
60
61
|
void Init_carray_sort (); /* sort / sort_copy / sort_addr / axis2addr */
|
|
61
62
|
void Init_carray_count ();
|
|
62
63
|
void Init_carray_kernels (); /* mkkernel-generated: reductions + maps */
|
|
64
|
+
void Init_carray_round ();
|
|
63
65
|
void Init_carray_utils ();
|
|
64
66
|
void Init_carray_generate ();
|
|
65
67
|
void Init_carray_copy ();
|
|
@@ -183,13 +185,13 @@ Init_carray_ext (void)
|
|
|
183
185
|
/* The flags this build's arithmetic was compiled with. Anything that
|
|
184
186
|
computes what these kernels compute, somewhere other than in them, has
|
|
185
187
|
to be built the same way to arrive at the same answer. */
|
|
186
|
-
rb_define_const(rb_cCArray, "BUILD_FLAGS", rb_str_new2(CA_BUILD_FLAGS));
|
|
187
|
-
rb_define_const(rb_cCArray, "VERSION", rb_str_new2(CA_VERSION));
|
|
188
|
+
rb_define_const(rb_cCArray, "BUILD_FLAGS", rb_obj_freeze(rb_str_new2(CA_BUILD_FLAGS)));
|
|
189
|
+
rb_define_const(rb_cCArray, "VERSION", rb_obj_freeze(rb_str_new2(CA_VERSION)));
|
|
188
190
|
rb_define_const(rb_cCArray, "VERSION_CODE", INT2NUM(CA_VERSION_CODE));
|
|
189
191
|
rb_define_const(rb_cCArray, "VERSION_MAJOR", INT2NUM(CA_VERSION_MAJOR));
|
|
190
192
|
rb_define_const(rb_cCArray, "VERSION_MINOR", INT2NUM(CA_VERSION_MINOR));
|
|
191
193
|
rb_define_const(rb_cCArray, "VERSION_TEENY", INT2NUM(CA_VERSION_TEENY));
|
|
192
|
-
rb_define_const(rb_cCArray, "VERSION_DATE", rb_str_new2(CA_VERSION_DATE));
|
|
194
|
+
rb_define_const(rb_cCArray, "VERSION_DATE", rb_obj_freeze(rb_str_new2(CA_VERSION_DATE)));
|
|
193
195
|
|
|
194
196
|
/* -- system -- */
|
|
195
197
|
rb_define_const(rb_cObject, "CA_RANK_MAX", INT2NUM(CA_RANK_MAX));
|
|
@@ -199,8 +201,10 @@ Init_carray_ext (void)
|
|
|
199
201
|
absence. C code only ever compares against it; the value is never
|
|
200
202
|
read and must never be passed in from Ruby. The constant exists to
|
|
201
203
|
anchor the object against the GC. */
|
|
202
|
-
CA_UNSPECIFIED = rb_funcall(rb_cObject, rb_intern("new"), 0);
|
|
204
|
+
CA_UNSPECIFIED = rb_obj_freeze(rb_funcall(rb_cObject, rb_intern("new"), 0));
|
|
203
205
|
rb_define_const(rb_cCArray, "UNSPECIFIED", CA_UNSPECIFIED);
|
|
206
|
+
/* Compared by identity in C, so it must not move. */
|
|
207
|
+
rb_gc_register_mark_object(CA_UNSPECIFIED);
|
|
204
208
|
|
|
205
209
|
#ifdef HAVE_COMPLEX_H
|
|
206
210
|
/* @private */
|
|
@@ -284,6 +288,7 @@ Init_carray_ext (void)
|
|
|
284
288
|
Init_carray_undef();
|
|
285
289
|
Init_carray_mask();
|
|
286
290
|
Init_carray_hold();
|
|
291
|
+
Init_carray_key_windows();
|
|
287
292
|
Init_carray_loop();
|
|
288
293
|
Init_carray_access();
|
|
289
294
|
Init_carray_index_classifier();
|
|
@@ -308,6 +313,7 @@ Init_carray_ext (void)
|
|
|
308
313
|
Init_carray_sort(); /* sort / sort_copy / sort_addr / axis2addr */
|
|
309
314
|
Init_carray_count();
|
|
310
315
|
Init_carray_kernels(); /* mkkernel-generated: reductions + maps */
|
|
316
|
+
Init_carray_round(); /* round(ndigits); after the generated round */
|
|
311
317
|
|
|
312
318
|
Init_carray_utils();
|
|
313
319
|
|
data/ext/version.h
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#define CA_VERSION "3.0.
|
|
2
|
-
#define CA_VERSION_CODE
|
|
1
|
+
#define CA_VERSION "3.0.4"
|
|
2
|
+
#define CA_VERSION_CODE 30004
|
|
3
3
|
#define CA_VERSION_MAJOR 3
|
|
4
4
|
#define CA_VERSION_MINOR 0
|
|
5
|
-
#define CA_VERSION_TEENY
|
|
6
|
-
#define CA_VERSION_DATE "2026/10/
|
|
5
|
+
#define CA_VERSION_TEENY 4
|
|
6
|
+
#define CA_VERSION_DATE "2026/10/19"
|
data/lib/carray/attribute.rb
CHANGED
|
@@ -31,11 +31,35 @@
|
|
|
31
31
|
# The walk stops at a lazy operation view (CAMonOp / CABinOp /
|
|
32
32
|
# CATriOp / CAMonCmp / CABinCmp): its cells are computed, not the
|
|
33
33
|
# parent's cells, so the parent's attributes do not describe them.
|
|
34
|
-
# `a.lazy` itself (CALazyMarker) is a view of `a` and walks through
|
|
34
|
+
# `a.lazy` itself (CALazyMarker) is a view of `a` and walks through,
|
|
35
|
+
# and so does a lazy type conversion (the cast lane `promote_list`
|
|
36
|
+
# and `wrap_readonly` build), for the reason `to_type` carries them.
|
|
37
|
+
# A view of a Face shows the attributes of the Face it was taken
|
|
38
|
+
# from (the walk goes to that Face, which the view's own parent
|
|
39
|
+
# chain skips).
|
|
40
|
+
# A view of several arrays (CAStack / CAMeld, so `stack`, `meld` and
|
|
41
|
+
# `montage`) shows, below its own @attr, the keys every one of its
|
|
42
|
+
# arrays shows with the same value; a key they disagree on, or one
|
|
43
|
+
# some of them lack, is not shown.
|
|
35
44
|
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
45
|
+
# Stored values are frozen copies, nested Arrays and Hashes included, so
|
|
46
|
+
# an attribute changes only through set_attr / set_attrs: a value read
|
|
47
|
+
# back cannot be changed in place, and a copy that shares it with its
|
|
48
|
+
# source cannot change the source. A frozen array takes no new
|
|
49
|
+
# attribute.
|
|
50
|
+
#
|
|
51
|
+
# A mask array (`a.mask`) holds no attributes: set_attr / set_attrs raise.
|
|
52
|
+
#
|
|
53
|
+
# Copies: `dup` and `clone` give the new array its own Hash of the
|
|
54
|
+
# receiver's own attributes. `copy` and `to_type` give the new array the attributes the
|
|
55
|
+
# source shows, as its own Hash; `concatenate`, `mosaic` and `tabulate`
|
|
56
|
+
# give it the keys every piece shows with the same value, as the views
|
|
57
|
+
# do. A conversion to another type or representation (`to_type`,
|
|
58
|
+
# `categorize`, a CAFrame `cast` / `parse_to_time` / `to_time`) carries
|
|
59
|
+
# them. Arithmetic and reductions do not -- the result is a different
|
|
60
|
+
# quantity -- including those that pick a value (`first`, `last`, `min`,
|
|
61
|
+
# `max`, `unique`). A CAFrame index built from a key column's values
|
|
62
|
+
# (group and pivot) shows the key column's attributes.
|
|
39
63
|
|
|
40
64
|
class CArray
|
|
41
65
|
|
|
@@ -63,9 +87,15 @@ class CArray
|
|
|
63
87
|
# store.
|
|
64
88
|
# @param key [Symbol, String] attribute key.
|
|
65
89
|
# @param value [Object] JSON-compatible value.
|
|
66
|
-
#
|
|
90
|
+
# The value is stored as a frozen copy (nested Arrays and Hashes
|
|
91
|
+
# too).
|
|
92
|
+
# @return [Object] the stored value.
|
|
67
93
|
# @raise [TypeError] when `key` or `value` is not accepted.
|
|
94
|
+
# @raise [ArgumentError] when `value` nests more than 32 levels.
|
|
95
|
+
# @raise [FrozenError] when `self` is frozen.
|
|
96
|
+
# @raise [TypeError] when `self` is a mask array.
|
|
68
97
|
def set_attr (key, value)
|
|
98
|
+
attr_check_writable
|
|
69
99
|
attr_validate_value(value)
|
|
70
100
|
(@attr ||= {})[attr_normalize_key(key)] = attr_coerce_value(value)
|
|
71
101
|
end
|
|
@@ -79,7 +109,11 @@ class CArray
|
|
|
79
109
|
# @param hash [Hash{Symbol, String => Object}] attributes to set.
|
|
80
110
|
# @return [CArray] self.
|
|
81
111
|
# @raise [TypeError] when a key or a value is not accepted.
|
|
112
|
+
# @raise [ArgumentError] when a value nests more than 32 levels.
|
|
113
|
+
# @raise [FrozenError] when `self` is frozen.
|
|
114
|
+
# @raise [TypeError] when `self` is a mask array.
|
|
82
115
|
def set_attrs (hash)
|
|
116
|
+
attr_check_writable
|
|
83
117
|
unless hash.is_a?(Hash)
|
|
84
118
|
raise TypeError, "set_attrs takes a Hash (got #{hash.class})"
|
|
85
119
|
end
|
|
@@ -94,8 +128,23 @@ class CArray
|
|
|
94
128
|
self
|
|
95
129
|
end
|
|
96
130
|
|
|
131
|
+
# @overload delete_attr(key)
|
|
132
|
+
# Removes attribute `key` from `self` (not from any parent) and
|
|
133
|
+
# returns its value, or `nil` when `self` has no such key. A key a
|
|
134
|
+
# view shows from its parent stays visible after this, as `set_attr`
|
|
135
|
+
# writes to `self` only.
|
|
136
|
+
# @param key [Symbol, String] attribute key.
|
|
137
|
+
# @return [Object, nil] the removed value.
|
|
138
|
+
# @raise [FrozenError] when `self` is frozen.
|
|
139
|
+
def delete_attr (key)
|
|
140
|
+
k = attr_normalize_key(key)
|
|
141
|
+
return nil unless instance_variable_defined?(:@attr) && @attr
|
|
142
|
+
attr_check_not_frozen
|
|
143
|
+
@attr.delete(k)
|
|
144
|
+
end
|
|
145
|
+
|
|
97
146
|
# @overload attrs
|
|
98
|
-
# Returns a frozen
|
|
147
|
+
# Returns a frozen Hash of all attributes visible on
|
|
99
148
|
# `self`, merged along the parent chain (deeper writes shadow
|
|
100
149
|
# shallower ones on a per-key basis).
|
|
101
150
|
# @return [Hash{String => Object}]
|
|
@@ -135,32 +184,85 @@ class CArray
|
|
|
135
184
|
private
|
|
136
185
|
|
|
137
186
|
# Yield each non-nil @attr Hash along the parent chain (self first).
|
|
138
|
-
#
|
|
139
|
-
# real CArray view chains rarely exceed a handful of levels.
|
|
140
|
-
MAX_CHAIN_DEPTH = 64
|
|
141
|
-
private_constant :MAX_CHAIN_DEPTH
|
|
142
|
-
|
|
187
|
+
# The chain has no fixed bound; an array seen twice ends the walk.
|
|
143
188
|
def attr_each_chain
|
|
144
189
|
ca = self
|
|
145
|
-
|
|
190
|
+
seen = nil
|
|
191
|
+
loop do
|
|
146
192
|
if ca.instance_variable_defined?(:@attr)
|
|
147
193
|
h = ca.instance_variable_get(:@attr)
|
|
148
194
|
yield(h) if h
|
|
149
195
|
end
|
|
150
196
|
return nil if attr_computing_view?(ca)
|
|
151
|
-
|
|
152
|
-
|
|
197
|
+
if ca.is_a?(CAStack) || ca.is_a?(CAMeld)
|
|
198
|
+
shared = CArray.__send__(:attrs_shared_by, ca.parents)
|
|
199
|
+
yield(shared) unless shared.empty?
|
|
200
|
+
return nil
|
|
201
|
+
end
|
|
202
|
+
parent = ca.is_a?(CArray) ? ca.__send__(:attribute_parent) : nil
|
|
203
|
+
return nil if parent.nil?
|
|
204
|
+
seen ||= {}.compare_by_identity
|
|
205
|
+
return nil if seen.key?(parent)
|
|
206
|
+
seen[ca] = true
|
|
153
207
|
ca = parent
|
|
154
208
|
end
|
|
155
|
-
nil
|
|
156
209
|
end
|
|
157
210
|
|
|
211
|
+
def attr_check_not_frozen
|
|
212
|
+
raise FrozenError.new("can't modify frozen #{self.class}: attributes", receiver: self) if frozen?
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def attr_check_writable
|
|
216
|
+
attr_check_not_frozen
|
|
217
|
+
raise TypeError, "a mask array holds no attributes" if mask_array?
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Give `out`, a new array holding self's values in another type or
|
|
221
|
+
# representation, the attributes self shows; returns `out`. A view of
|
|
222
|
+
# self that already shows them is left alone.
|
|
223
|
+
def carry_attrs (out)
|
|
224
|
+
return out if out.equal?(self)
|
|
225
|
+
shown = attrs
|
|
226
|
+
out.set_attrs(shown) unless shown.empty? || out.attrs == shown
|
|
227
|
+
out
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Remove what `out`, a new array a reduction made, holds of self's
|
|
231
|
+
# attributes; returns `out`.
|
|
232
|
+
def drop_carried_attrs (out)
|
|
233
|
+
out.remove_instance_variable(:@attr) if out.instance_variable_defined?(:@attr)
|
|
234
|
+
out
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# The attributes every array in `list` shows with the same value.
|
|
238
|
+
def self.attrs_shared_by (list)
|
|
239
|
+
first, *rest = list.map(&:attrs)
|
|
240
|
+
return {} if first.nil?
|
|
241
|
+
first.select { |k, v| rest.all? { |h| h.key?(k) && h[k] == v } }
|
|
242
|
+
end
|
|
243
|
+
private_class_method :attrs_shared_by
|
|
244
|
+
|
|
158
245
|
def attr_computing_view? (ca)
|
|
159
|
-
ca.
|
|
246
|
+
return ca.__op_id__ < CAMonOp::CAST_BASE if ca.is_a?(CAMonOp)
|
|
247
|
+
ca.is_a?(CABinOp) || ca.is_a?(CATriOp) ||
|
|
160
248
|
ca.is_a?(CAMonCmp) || ca.is_a?(CABinCmp)
|
|
161
249
|
end
|
|
162
250
|
|
|
163
251
|
def attr_normalize_key (key)
|
|
252
|
+
CArray.__send__(:attr_normalize_key, key)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def attr_validate_value (v)
|
|
256
|
+
CArray.__send__(:attr_validate_value, v)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def attr_coerce_value (v)
|
|
260
|
+
CArray.__send__(:attr_coerce_value, v)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# The key and value rules, as class methods so that CAFrame's attributes
|
|
264
|
+
# follow the same ones.
|
|
265
|
+
def self.attr_normalize_key (key)
|
|
164
266
|
case key
|
|
165
267
|
when String then key
|
|
166
268
|
when Symbol then key.to_s
|
|
@@ -169,7 +271,7 @@ class CArray
|
|
|
169
271
|
end
|
|
170
272
|
end
|
|
171
273
|
|
|
172
|
-
def attr_validate_value (v, depth = 0)
|
|
274
|
+
def self.attr_validate_value (v, depth = 0)
|
|
173
275
|
raise ArgumentError, "attribute value nests too deep" if depth > 32
|
|
174
276
|
case v
|
|
175
277
|
when String, Integer, Float, true, false, nil, Symbol
|
|
@@ -189,17 +291,19 @@ class CArray
|
|
|
189
291
|
end
|
|
190
292
|
end
|
|
191
293
|
|
|
192
|
-
def attr_coerce_value (v)
|
|
294
|
+
def self.attr_coerce_value (v)
|
|
193
295
|
case v
|
|
194
|
-
when Symbol then v.to_s
|
|
195
|
-
when
|
|
296
|
+
when Symbol then v.to_s.freeze
|
|
297
|
+
when String then v.frozen? ? v : v.dup.freeze
|
|
298
|
+
when Array then v.map { |e| attr_coerce_value(e) }.freeze
|
|
196
299
|
when Hash
|
|
197
300
|
v.each_with_object({}) do |(k, vv), h|
|
|
198
|
-
h[k.is_a?(Symbol) ? k.to_s : k] = attr_coerce_value(vv)
|
|
199
|
-
end
|
|
301
|
+
h[(k.is_a?(Symbol) ? k.to_s : k.dup).freeze] = attr_coerce_value(vv)
|
|
302
|
+
end.freeze
|
|
200
303
|
else
|
|
201
304
|
v
|
|
202
305
|
end
|
|
203
306
|
end
|
|
307
|
+
private_class_method :attr_normalize_key, :attr_validate_value, :attr_coerce_value
|
|
204
308
|
|
|
205
309
|
end
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# after autoload_method_extension is installed. Split by intent:
|
|
7
7
|
#
|
|
8
8
|
# (1) Top-level feature files under carray/ — constant class + entry
|
|
9
|
-
# methods (Serializer,
|
|
9
|
+
# methods (Serializer, iterators, aggregation
|
|
10
10
|
# accumulators, categorical / axis-group).
|
|
11
11
|
# (2) Single-feature method files under carray/methods/ — each first
|
|
12
12
|
# call requires its file, whose definitions overwrite the stubs
|
|
@@ -20,21 +20,6 @@
|
|
|
20
20
|
# (1) Top-level feature files
|
|
21
21
|
# ============================================================================
|
|
22
22
|
|
|
23
|
-
# ---- Inspection (#inspect / #source_code) ----------------------------------
|
|
24
|
-
#
|
|
25
|
-
# CArray::Inspector (:nodoc:) and #inspect / #source_code live in carray/inspect.rb.
|
|
26
|
-
# #inspect is an implicit method (p / pp / irb / error interpolation), so the
|
|
27
|
-
# stub loads the file the first time any CArray is displayed. Nothing in the
|
|
28
|
-
# eager core references it at load time; #desc is private (code-internal) and
|
|
29
|
-
# Inspector is internal, so only the two public methods need stubs.
|
|
30
|
-
|
|
31
|
-
class CArray
|
|
32
|
-
inspect_rb = "carray/inspect"
|
|
33
|
-
autoload_method "inspect", inspect_rb
|
|
34
|
-
autoload_method "inspect_full", inspect_rb
|
|
35
|
-
autoload_method "source_code", inspect_rb
|
|
36
|
-
end
|
|
37
|
-
|
|
38
23
|
# ---- Serializer / Marshal / dump / load ------------------------------------
|
|
39
24
|
|
|
40
25
|
class CArray
|
|
@@ -64,21 +49,6 @@ class CARecord
|
|
|
64
49
|
autoload_method "marshal_dump", "carray/serialize"
|
|
65
50
|
end
|
|
66
51
|
|
|
67
|
-
# ---- Arrow tensor IPC (interop) --------------------------------------------
|
|
68
|
-
|
|
69
|
-
class CArray
|
|
70
|
-
arrow_tensor_rb = "carray/arrow_tensor"
|
|
71
|
-
autoload :ArrowTensor, arrow_tensor_rb
|
|
72
|
-
autoload_method "self.load_arrow_tensor", arrow_tensor_rb
|
|
73
|
-
autoload_method "save_arrow_tensor", arrow_tensor_rb
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# ---- Table (row-major dispatch helper) -------------------------------------
|
|
77
|
-
|
|
78
|
-
class CArray
|
|
79
|
-
autoload :TableMethods, "carray/table"
|
|
80
|
-
end
|
|
81
|
-
|
|
82
52
|
# ---- Fusion (reading a lazy expression as a plan) --------------------------
|
|
83
53
|
#
|
|
84
54
|
# Nothing in the core asks for a plan -- CArray can always walk the view --
|
|
@@ -101,6 +71,7 @@ end
|
|
|
101
71
|
|
|
102
72
|
autoload :CASlabIterator, "carray/slab_iterator"
|
|
103
73
|
autoload :CAWindowIterator, "carray/window_iterator"
|
|
74
|
+
autoload :CAKeyWindowIterator, "carray/key_windows"
|
|
104
75
|
autoload :CABlockIterator, "carray/block_iterator"
|
|
105
76
|
|
|
106
77
|
class CArray
|
|
@@ -174,6 +145,10 @@ autoload :CAUnion, "carray/struct"
|
|
|
174
145
|
autoload :CAFrame, "carray/frame"
|
|
175
146
|
autoload :GroupedFrame, "carray/frame"
|
|
176
147
|
|
|
148
|
+
class CArray
|
|
149
|
+
autoload_method "to_frame", "carray/frame"
|
|
150
|
+
end
|
|
151
|
+
|
|
177
152
|
class CArray
|
|
178
153
|
struct_rb = "carray/struct"
|
|
179
154
|
autoload_method "self.struct", struct_rb
|
|
@@ -231,10 +206,12 @@ class CArray
|
|
|
231
206
|
autoload_method "intersection", "carray/methods/is_in"
|
|
232
207
|
autoload_method "difference", "carray/methods/is_in"
|
|
233
208
|
autoload_method "union", "carray/methods/is_in"
|
|
209
|
+
autoload_method "is_between", "carray/methods/is_between"
|
|
234
210
|
autoload_method "self.align_addr", "carray/methods/align_addr"
|
|
235
211
|
autoload_method "self.align_nearest_addr", "carray/methods/align_addr"
|
|
236
212
|
autoload_method "value_counts", "carray/methods/value_counts"
|
|
237
213
|
autoload_method "nunique", "carray/methods/nunique"
|
|
214
|
+
autoload_method "lag", "carray/methods/lag"
|
|
238
215
|
autoload_method "is_mode", "carray/methods/mode"
|
|
239
216
|
autoload_method "mode", "carray/methods/mode"
|
|
240
217
|
autoload_method "snap", "carray/methods/snap"
|
|
@@ -32,8 +32,18 @@ module AutoloadMethodExtension
|
|
|
32
32
|
private
|
|
33
33
|
|
|
34
34
|
def autoload_define (target, name, library, original_spec)
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
library = Ractor.make_shareable(library.to_s.dup)
|
|
36
|
+
original_spec = Ractor.make_shareable(original_spec.to_s.dup)
|
|
37
|
+
# Shareable, so the stub answers in any Ractor. Only the main Ractor
|
|
38
|
+
# loads the library: Ractors that require at the same time can deadlock
|
|
39
|
+
# (Ruby 3.4), so another Ractor is told what to load there instead.
|
|
40
|
+
target.define_method(name, &Ractor.make_shareable(proc do |*args, **kwargs, &block|
|
|
41
|
+
unless Ractor.current == Ractor.main
|
|
42
|
+
raise Ractor::IsolationError,
|
|
43
|
+
"'#{original_spec}' is loaded on first use from '#{library}'; " \
|
|
44
|
+
"require it in the main Ractor before other Ractors use it"
|
|
45
|
+
end
|
|
46
|
+
stub_location = target.instance_method(name).source_location
|
|
37
47
|
begin
|
|
38
48
|
require library
|
|
39
49
|
rescue LoadError
|
|
@@ -45,14 +55,13 @@ module AutoloadMethodExtension
|
|
|
45
55
|
# forwarding would land straight back here and keep doing so until the
|
|
46
56
|
# stack gave out -- naming neither the method nor the library. Say
|
|
47
57
|
# which, once.
|
|
48
|
-
if target.instance_method(name) ==
|
|
58
|
+
if target.instance_method(name).source_location == stub_location
|
|
49
59
|
raise NoMethodError,
|
|
50
60
|
"'#{original_spec}' is registered for autoload from " \
|
|
51
61
|
"'#{library}', but that library defines no such method"
|
|
52
62
|
end
|
|
53
63
|
send(name, *args, **kwargs, &block)
|
|
54
|
-
end
|
|
55
|
-
stub = target.instance_method(name)
|
|
64
|
+
end))
|
|
56
65
|
# The library replaces the stub with a plain `def`, which `ruby -w`
|
|
57
66
|
# reports as a redefinition. Replacing is what the stub is for, so mark
|
|
58
67
|
# it as aliased: Ruby does not warn when the old definition has an alias.
|