carray 2.0.0 → 3.0.0
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/.yardopts +5 -25
- data/CHANGELOG.md +16 -0
- data/LICENSE +1 -1
- data/NEWS.md +3 -0
- data/README.md +128 -44
- data/carray.gemspec +22 -24
- data/ext/ca_array_pool.c +91 -0
- data/ext/ca_axis_descriptor.h +186 -0
- data/ext/ca_axis_dispatch.c +924 -0
- data/ext/ca_axis_group.c +1208 -0
- data/ext/ca_bincmp_dispatch.c +76 -0
- data/ext/ca_bincmp_dispatch.h +85 -0
- data/ext/ca_binop_dispatch.c +125 -0
- data/ext/ca_binop_dispatch.h +159 -0
- data/ext/ca_categorical_iterator.c +1375 -0
- data/ext/ca_compare.c +94 -0
- data/ext/ca_compare.h +26 -0
- data/ext/ca_composite_dispatch.c +414 -0
- data/ext/ca_composite_dispatch.h +116 -0
- data/ext/ca_for_buffer.h +96 -0
- data/ext/ca_for_each_element.h +241 -0
- data/ext/ca_group_iter.c +304 -0
- data/ext/ca_iter_substrate.h +325 -0
- data/ext/ca_kernel_iterator.c +4321 -0
- data/ext/ca_kernel_iterator.h +2603 -0
- data/ext/ca_moncmp_dispatch.c +37 -0
- data/ext/ca_moncmp_dispatch.h +62 -0
- data/ext/ca_monop_dispatch.c +200 -0
- data/ext/ca_monop_dispatch.h +235 -0
- data/ext/ca_obj_array.c +355 -359
- data/ext/ca_obj_bincmp.c +809 -0
- data/ext/ca_obj_binop.c +892 -0
- data/ext/ca_obj_bitarray.c +369 -164
- data/ext/ca_obj_bitfield.c +294 -234
- data/ext/ca_obj_block.c +189 -711
- data/ext/ca_obj_byte_swap.c +766 -0
- data/ext/ca_obj_const_string.c +965 -0
- data/ext/ca_obj_face.c +670 -0
- data/ext/ca_obj_face.h +247 -0
- data/ext/ca_obj_fake.c +228 -100
- data/ext/ca_obj_farray.c +54 -441
- data/ext/ca_obj_field.c +82 -529
- data/ext/ca_obj_fixlen_string.c +306 -0
- data/ext/ca_obj_grid.c +858 -440
- data/ext/ca_obj_meld.c +1034 -0
- data/ext/ca_obj_moncmp.c +569 -0
- data/ext/ca_obj_monop.c +1111 -0
- data/ext/ca_obj_object.c +774 -298
- data/ext/ca_obj_record.c +468 -0
- data/ext/ca_obj_reduce.c +97 -82
- data/ext/ca_obj_refer.c +569 -459
- data/ext/ca_obj_remap.c +475 -0
- data/ext/ca_obj_repeat.c +92 -477
- data/ext/ca_obj_roll.c +616 -0
- data/ext/ca_obj_select.c +344 -296
- data/ext/ca_obj_select_axis.c +1296 -0
- data/ext/ca_obj_shift.c +230 -792
- data/ext/ca_obj_source.c +78 -0
- data/ext/ca_obj_stack.c +1173 -0
- data/ext/ca_obj_stride.c +2501 -0
- data/ext/ca_obj_string.c +268 -0
- data/ext/ca_obj_tile.c +614 -0
- data/ext/ca_obj_time.c +546 -0
- data/ext/ca_obj_timedelta.c +435 -0
- data/ext/ca_obj_transpose.c +62 -516
- data/ext/ca_obj_triop.c +746 -0
- data/ext/ca_obj_unbound_repeat.c +208 -241
- data/ext/ca_obj_window.c +1131 -563
- data/ext/ca_op_byte_swap.c +175 -0
- data/ext/ca_op_ipower.c +319 -0
- data/ext/ca_op_powi.h +88 -0
- data/ext/ca_sort_kernels.h +132 -0
- data/ext/ca_sweep_engine.c +430 -0
- data/ext/ca_sweep_engine.h +157 -0
- data/ext/ca_transform_common.c +228 -0
- data/ext/ca_triop_dispatch.c +55 -0
- data/ext/ca_triop_dispatch.h +62 -0
- data/ext/carray.h +795 -402
- data/ext/carray_access.c +831 -711
- data/ext/carray_attribute.c +98 -330
- data/ext/carray_bincount.c +255 -0
- data/ext/carray_broadcast.c +283 -0
- data/ext/carray_call_cfunc.c +1360 -828
- data/ext/carray_call_cfunc.h +160 -0
- data/ext/carray_cast.c +1212 -301
- data/ext/carray_cast_func.rb +81 -40
- data/ext/carray_class.c +53 -63
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +350 -346
- data/ext/carray_copy.c +156 -268
- data/ext/carray_core.c +1342 -199
- data/ext/carray_count.c +312 -0
- data/ext/carray_data_type.c +43 -19
- data/ext/carray_element.c +585 -213
- data/ext/carray_factorize.c +2542 -0
- data/ext/carray_generate.c +230 -559
- data/ext/carray_histogram.c +490 -0
- data/ext/carray_hold.c +228 -0
- data/ext/carray_index_classifier.c +1035 -0
- data/ext/carray_index_classifier.h +27 -0
- data/ext/carray_internal.h +120 -0
- data/ext/carray_kernels_bincmp.c +4445 -0
- data/ext/carray_kernels_binop.c +10979 -0
- data/ext/carray_kernels_init.c +36 -0
- data/ext/carray_kernels_map.c +3466 -0
- data/ext/carray_kernels_moncmp.c +2096 -0
- data/ext/carray_kernels_monop.c +18312 -0
- data/ext/carray_kernels_reduce_aggregate.c +25836 -0
- data/ext/carray_kernels_reduce_boolean.c +329 -0
- data/ext/carray_kernels_reduce_cumulative.c +14592 -0
- data/ext/carray_kernels_reduce_extreme.c +16947 -0
- data/ext/carray_kernels_reduce_variance.c +3909 -0
- data/ext/carray_kernels_scan.c +3692 -0
- data/ext/carray_kernels_search.c +32137 -0
- data/ext/carray_kernels_sort.c +10625 -0
- data/ext/carray_kernels_triop.c +1391 -0
- data/ext/carray_lazy.c +567 -0
- data/ext/carray_loop.c +88 -200
- data/ext/carray_mask.c +848 -154
- data/ext/carray_math_kernel.h +120 -0
- data/ext/carray_mathfunc.c +10 -241
- data/ext/carray_median_percentile.c +1257 -0
- data/ext/carray_memory_view.c +1625 -0
- data/ext/carray_operator.c +1526 -318
- data/ext/carray_order.c +664 -1394
- data/ext/carray_partition.c +416 -0
- data/ext/carray_random.c +518 -0
- data/ext/carray_scatter.c +357 -0
- data/ext/carray_slab.c +1219 -0
- data/ext/carray_slab.h +84 -0
- data/ext/carray_sort.c +829 -0
- data/ext/carray_sort_kernel.c +620 -0
- data/ext/carray_struct.c +695 -0
- data/ext/carray_test.c +343 -229
- data/ext/carray_undef.c +34 -17
- data/ext/carray_utils.c +175 -74
- data/ext/extconf.rb +216 -55
- data/ext/mk_call_cfunc.rb +480 -0
- data/ext/mkkernel.rb +8842 -0
- data/ext/ruby_carray.c +202 -101
- data/ext/version.h +4 -14
- data/ext/version.rb +5 -13
- data/lib/carray/arrow_tensor.rb +401 -0
- data/lib/carray/attribute.rb +166 -0
- data/lib/carray/autoload_carray.rb +220 -0
- data/lib/carray/autoload_method_extension.rb +44 -0
- data/lib/carray/axis_group.rb +711 -0
- data/lib/carray/basics.rb +481 -0
- data/lib/carray/bincount_nd.rb +358 -0
- data/lib/carray/block_iterator.rb +604 -0
- data/lib/carray/boolean_reduce.rb +109 -0
- data/lib/carray/categorical.rb +561 -0
- data/lib/carray/categorical_iterator.rb +1062 -0
- data/lib/carray/complex.rb +150 -0
- data/lib/carray/conditional.rb +216 -0
- data/lib/carray/const_string.rb +228 -0
- data/lib/carray/construct.rb +139 -328
- data/lib/carray/core_extensions.rb +240 -0
- data/lib/carray/data_type_extension.rb +233 -0
- data/lib/carray/fixlen_string.rb +95 -0
- data/lib/carray/frame/concat.rb +132 -0
- data/lib/carray/frame/convert.rb +95 -0
- data/lib/carray/frame/csv_parser.rb +211 -0
- data/lib/carray/frame/frame.rb +649 -0
- data/lib/carray/frame/group.rb +186 -0
- data/lib/carray/frame/io.rb +164 -0
- data/lib/carray/frame/join.rb +248 -0
- data/lib/carray/frame/records.rb +99 -0
- data/lib/carray/frame/sort.rb +113 -0
- data/lib/carray/frame/verbs.rb +299 -0
- data/lib/carray/frame.rb +16 -0
- data/lib/carray/histogram.rb +512 -0
- data/lib/carray/inspect.rb +37 -20
- data/lib/carray/iterator.rb +57 -349
- data/lib/carray/lazy.rb +889 -0
- data/lib/carray/mask_gap_fill.rb +200 -0
- data/lib/carray/math.rb +78 -342
- data/lib/carray/meld_reduce.rb +289 -0
- data/lib/carray/methods/align_addr.rb +116 -0
- data/lib/carray/methods/bin.rb +128 -0
- data/lib/carray/methods/bincount.rb +87 -0
- data/lib/carray/methods/bit_string.rb +92 -0
- data/lib/carray/methods/broadcast.rb +63 -0
- data/lib/carray/methods/choose.rb +39 -0
- data/lib/carray/methods/composition.rb +280 -0
- data/lib/carray/methods/gather_nd.rb +206 -0
- data/lib/carray/methods/index.rb +39 -0
- data/lib/carray/methods/insert_block.rb +99 -0
- data/lib/carray/methods/is_in.rb +141 -0
- data/lib/carray/methods/join.rb +90 -0
- data/lib/carray/methods/locate_addr.rb +47 -0
- data/lib/carray/methods/mask_duplicates.rb +41 -0
- data/lib/carray/methods/meshgrid.rb +91 -0
- data/lib/carray/methods/mode.rb +126 -0
- data/lib/carray/methods/nunique.rb +46 -0
- data/lib/carray/methods/resize.rb +56 -0
- data/lib/carray/methods/snap.rb +156 -0
- data/lib/carray/methods/string_format.rb +57 -0
- data/lib/carray/methods/unique.rb +47 -0
- data/lib/carray/methods/value_counts.rb +71 -0
- data/lib/carray/mkmf.rb +124 -101
- data/lib/carray/runtime.rb +108 -0
- data/lib/carray/serialize.rb +478 -167
- data/lib/carray/slab_iterator.rb +292 -0
- data/lib/carray/stack.rb +291 -0
- data/lib/carray/string.rb +56 -180
- data/lib/carray/string_operation_extension.rb +289 -0
- data/lib/carray/struct.rb +335 -323
- data/lib/carray/struct_builder.rb +697 -0
- data/lib/carray/table.rb +41 -2
- data/lib/carray/time.rb +2255 -38
- data/lib/carray/window_iterator.rb +655 -0
- data/lib/carray.rb +55 -57
- metadata +163 -130
- data/Rakefile +0 -51
- data/TODO.md +0 -18
- data/ext/ca_iter_block.c +0 -257
- data/ext/ca_iter_dimension.c +0 -299
- data/ext/ca_iter_window.c +0 -214
- data/ext/ca_obj_mapping.c +0 -644
- data/ext/carray_iterator.c +0 -641
- data/ext/carray_math.rb +0 -850
- data/ext/carray_numeric.c +0 -259
- data/ext/carray_sort_addr.c +0 -254
- data/ext/carray_stat.c +0 -2100
- data/ext/carray_stat_proc.rb +0 -1999
- data/ext/mkmath.rb +0 -741
- data/ext/ruby_ccomplex.c +0 -509
- data/ext/ruby_float_func.c +0 -86
- data/lib/carray/array.rb +0 -8
- data/lib/carray/autoload/autoload_base.rb +0 -19
- data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
- data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
- data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
- data/lib/carray/autoload/autoload_gem_random.rb +0 -8
- data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
- data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
- data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
- data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
- data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
- data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
- data/lib/carray/autoload/autoload_object_link.rb +0 -1
- data/lib/carray/autoload/autoload_object_pack.rb +0 -2
- data/lib/carray/autoload.rb +0 -141
- data/lib/carray/basic.rb +0 -191
- data/lib/carray/broadcast.rb +0 -101
- data/lib/carray/compose.rb +0 -315
- data/lib/carray/convert.rb +0 -115
- data/lib/carray/info.rb +0 -110
- data/lib/carray/io/imagemagick.rb +0 -235
- data/lib/carray/mask.rb +0 -102
- data/lib/carray/math/histogram.rb +0 -177
- data/lib/carray/math/recurrence.rb +0 -93
- data/lib/carray/object/ca_obj_iterator.rb +0 -50
- data/lib/carray/object/ca_obj_link.rb +0 -50
- data/lib/carray/object/ca_obj_pack.rb +0 -99
- data/lib/carray/obsolete.rb +0 -256
- data/lib/carray/ordering.rb +0 -181
- data/lib/carray/testing.rb +0 -51
- data/lib/carray/transform.rb +0 -109
- data/misc/Methods.ja.md +0 -182
- data/misc/NOTE +0 -51
- data/spec/Classes/CABitfield_spec.rb +0 -58
- data/spec/Classes/CABlockIterator_spec.rb +0 -114
- data/spec/Classes/CABlock_spec.rb +0 -205
- data/spec/Classes/CAField_spec.rb +0 -39
- data/spec/Classes/CAGrid_spec.rb +0 -75
- data/spec/Classes/CAMap_spec.rb +0 -0
- data/spec/Classes/CAMapping_spec.rb +0 -105
- data/spec/Classes/CAObject_attribute_spec.rb +0 -33
- data/spec/Classes/CAObject_spec.rb +0 -33
- data/spec/Classes/CARefer_spec.rb +0 -93
- data/spec/Classes/CARepeat_spec.rb +0 -65
- data/spec/Classes/CASelect_spec.rb +0 -22
- data/spec/Classes/CAShift_spec.rb +0 -16
- data/spec/Classes/CAStruct_spec.rb +0 -71
- data/spec/Classes/CATranspose_spec.rb +0 -60
- data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
- data/spec/Classes/CAWindow_spec.rb +0 -54
- data/spec/Classes/CAWrap_spec.rb +0 -8
- data/spec/Classes/CArray_spec.rb +0 -184
- data/spec/Classes/CScalar_spec.rb +0 -55
- data/spec/Classes/ex1.rb +0 -46
- data/spec/Features/feature_130_spec.rb +0 -19
- data/spec/Features/feature_attributes_spec.rb +0 -280
- data/spec/Features/feature_boolean_spec.rb +0 -98
- data/spec/Features/feature_broadcast.rb +0 -116
- data/spec/Features/feature_cast_function.rb +0 -19
- data/spec/Features/feature_cast_spec.rb +0 -33
- data/spec/Features/feature_class_spec.rb +0 -84
- data/spec/Features/feature_complex_spec.rb +0 -42
- data/spec/Features/feature_composite_spec.rb +0 -124
- data/spec/Features/feature_convert_spec.rb +0 -46
- data/spec/Features/feature_copy_spec.rb +0 -123
- data/spec/Features/feature_creation_spec.rb +0 -84
- data/spec/Features/feature_element_spec.rb +0 -144
- data/spec/Features/feature_extream_spec.rb +0 -54
- data/spec/Features/feature_generate_spec.rb +0 -74
- data/spec/Features/feature_index_spec.rb +0 -69
- data/spec/Features/feature_mask_spec.rb +0 -580
- data/spec/Features/feature_math_spec.rb +0 -97
- data/spec/Features/feature_order_spec.rb +0 -146
- data/spec/Features/feature_ref_store_spec.rb +0 -209
- data/spec/Features/feature_serialization_spec.rb +0 -125
- data/spec/Features/feature_stat_spec.rb +0 -397
- data/spec/Features/feature_virtual_spec.rb +0 -48
- data/spec/Features/method_eq_spec.rb +0 -81
- data/spec/Features/method_is_nan_spec.rb +0 -12
- data/spec/Features/method_map_spec.rb +0 -54
- data/spec/Features/method_max_with.rb +0 -20
- data/spec/Features/method_min_with.rb +0 -19
- data/spec/Features/method_ne_spec.rb +0 -18
- data/spec/Features/method_project_spec.rb +0 -188
- data/spec/Features/method_ref_spec.rb +0 -27
- data/spec/Features/method_round_spec.rb +0 -11
- data/spec/Features/method_s_linspace_spec.rb +0 -48
- data/spec/Features/method_s_span_spec.rb +0 -14
- data/spec/Features/method_seq_spec.rb +0 -47
- data/spec/Features/method_sort_with.rb +0 -43
- data/spec/Features/method_sorted_with.rb +0 -29
- data/spec/Features/method_span_spec.rb +0 -42
- data/spec/Features/method_wrap_readonly_spec.rb +0 -43
- data/spec/UnitTest/test_CAVirtual.rb +0 -214
- data/spec/spec_all.rb +0 -10
- data/utils/ca_ase.rb +0 -21
- data/utils/ca_methods.rb +0 -15
- data/utils/cast_checker.rb +0 -30
- data/utils/convert_test.rb +0 -73
- data/utils/extract_yard.rb +0 -22
- data/utils/guess_shape.rb +0 -76
- data/utils/monkey_patch_methods.rb +0 -62
- data/utils/remove_resource_fork.sh +0 -5
data/ext/ca_obj_record.c
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
CARecord — composite Face for CAStruct-backed arrays. Face wrap for
|
|
4
|
+
arrays whose element type is a CAStruct subclass; data_class is
|
|
5
|
+
attached only to CARecord (not to bare CArray).
|
|
6
|
+
|
|
7
|
+
Storage layout matches the CAStruct backing (CA_FIXLEN bytes blob,
|
|
8
|
+
unchanged). Storage ops thin-forward to the parent via `ca_face_*`;
|
|
9
|
+
the tail holds `VALUE data_class`, pinned by a custom dmark.
|
|
10
|
+
|
|
11
|
+
Also housed here: data_class identity predicates
|
|
12
|
+
(`rb_obj_is_data_class` / `ca_check_data_class` /
|
|
13
|
+
`CArray.data_class?`) since data_class is a CARecord concern.
|
|
14
|
+
|
|
15
|
+
Sibling pattern references (VALUE tail + custom dmark):
|
|
16
|
+
ca_obj_time.c numeric Face
|
|
17
|
+
ca_obj_byte_swap.c endian Face
|
|
18
|
+
|
|
19
|
+
---------------------------------------------------------------------------- */
|
|
20
|
+
|
|
21
|
+
#include "carray.h"
|
|
22
|
+
#include "ca_obj_face.h"
|
|
23
|
+
|
|
24
|
+
typedef struct {
|
|
25
|
+
/* === CAView prefix === */
|
|
26
|
+
int16_t obj_type;
|
|
27
|
+
int8_t data_type; /* fixed to CA_FIXLEN */
|
|
28
|
+
int8_t ndim;
|
|
29
|
+
int32_t flags; /* CA_FLAG_IS_FACE set */
|
|
30
|
+
ca_size_t bytes; /* = data_class::DATA_SIZE */
|
|
31
|
+
ca_size_t elements;
|
|
32
|
+
ca_size_t *dim;
|
|
33
|
+
char *ptr;
|
|
34
|
+
CArray *mask;
|
|
35
|
+
char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
|
|
36
|
+
CArray *parent;
|
|
37
|
+
uint32_t attach;
|
|
38
|
+
uint8_t nosync;
|
|
39
|
+
/* === Face tail === */
|
|
40
|
+
VALUE data_class; /* CAStruct subclass (marked by custom dmark) */
|
|
41
|
+
} CARecord;
|
|
42
|
+
|
|
43
|
+
static size_t
|
|
44
|
+
ca_record_dsize (const void *ap)
|
|
45
|
+
{
|
|
46
|
+
const CARecord *ca = (const CARecord *) ap;
|
|
47
|
+
return sizeof(CARecord) + ca->ndim * sizeof(ca_size_t);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Pool framework hooks: single ndim-sized tail (dim) in the _pool
|
|
51
|
+
buffer, uniform with the rest of the pool-migrated views. */
|
|
52
|
+
static size_t
|
|
53
|
+
ca_record_pool_bytes (int8_t ndim)
|
|
54
|
+
{
|
|
55
|
+
ca_size_t n = (ndim > 0) ? ndim : 1;
|
|
56
|
+
return (size_t) n * sizeof(ca_size_t);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void
|
|
60
|
+
ca_record_pool_init (void *ap, int8_t ndim)
|
|
61
|
+
{
|
|
62
|
+
CARecord *ca = (CARecord *) ap;
|
|
63
|
+
ca->dim = (ca_size_t *) ca->_pool;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Custom dmark: ca_mark handles the standard prefix; the data_class
|
|
67
|
+
tail VALUE must be marked explicitly (CAFace itself carries none). */
|
|
68
|
+
static void
|
|
69
|
+
ca_record_mark (void *ap)
|
|
70
|
+
{
|
|
71
|
+
CARecord *ca = (CARecord *) ap;
|
|
72
|
+
ca_mark(ca);
|
|
73
|
+
rb_gc_mark(ca->data_class);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const rb_data_type_t carecord_data_type = {
|
|
77
|
+
.parent = &caface_data_type,
|
|
78
|
+
.wrap_struct_name = "CARecord",
|
|
79
|
+
.function = {
|
|
80
|
+
.dmark = ca_record_mark,
|
|
81
|
+
.dfree = ca_free,
|
|
82
|
+
.dsize = ca_record_dsize,
|
|
83
|
+
.dcompact = NULL
|
|
84
|
+
},
|
|
85
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
int8_t CA_OBJ_RECORD; /* non-static: read by rb_ca_data_class in carray_attribute.c */
|
|
89
|
+
VALUE rb_cCARecord; /* non-static: exported for cross-file use */
|
|
90
|
+
|
|
91
|
+
/* ------------------------------------------------------------------- */
|
|
92
|
+
|
|
93
|
+
int
|
|
94
|
+
ca_record_setup (CARecord *ca, CArray *parent, VALUE data_class)
|
|
95
|
+
{
|
|
96
|
+
if ( parent->data_type != CA_FIXLEN ) {
|
|
97
|
+
rb_raise(rb_eTypeError,
|
|
98
|
+
"CARecord requires a CA_FIXLEN parent (got data_type=%d)",
|
|
99
|
+
parent->data_type);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ca->obj_type = CA_OBJ_RECORD;
|
|
103
|
+
ca->data_type = CA_FIXLEN;
|
|
104
|
+
ca->flags = CA_FLAG_IS_FACE;
|
|
105
|
+
ca->ndim = parent->ndim;
|
|
106
|
+
ca->bytes = parent->bytes;
|
|
107
|
+
ca->elements = parent->elements;
|
|
108
|
+
ca->ptr = NULL;
|
|
109
|
+
ca->mask = NULL;
|
|
110
|
+
if ( ! ca->_pool ) {
|
|
111
|
+
ca->dim = ALLOC_N(ca_size_t, parent->ndim);
|
|
112
|
+
}
|
|
113
|
+
memcpy(ca->dim, parent->dim, sizeof(ca_size_t) * parent->ndim);
|
|
114
|
+
|
|
115
|
+
ca->parent = parent;
|
|
116
|
+
ca->attach = 0;
|
|
117
|
+
ca->nosync = 0;
|
|
118
|
+
|
|
119
|
+
ca->data_class = data_class;
|
|
120
|
+
|
|
121
|
+
if ( ca_has_mask(parent) ) {
|
|
122
|
+
ca_create_mask((CArray *) ca);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ( ca_is_scalar(parent) ) {
|
|
126
|
+
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if ( ca_test_flag(parent, CA_FLAG_READ_ONLY) ) {
|
|
130
|
+
ca_set_flag(ca, CA_FLAG_READ_ONLY);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
CARecord *
|
|
137
|
+
ca_record_new (CArray *parent, VALUE data_class)
|
|
138
|
+
{
|
|
139
|
+
CARecord *ca = (CARecord *) ca_array_alloc(CA_OBJ_RECORD, parent->ndim);
|
|
140
|
+
ca_record_setup(ca, parent, data_class);
|
|
141
|
+
return ca;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static void
|
|
145
|
+
free_ca_record (void *ap)
|
|
146
|
+
{
|
|
147
|
+
CARecord *ca = (CARecord *) ap;
|
|
148
|
+
if ( ca != NULL ) {
|
|
149
|
+
ca_free(ca->mask);
|
|
150
|
+
if ( ca->_pool ) {
|
|
151
|
+
ca_array_free(ca); /* dim lives in _pool */
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
xfree(ca->dim);
|
|
155
|
+
xfree(ca);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ------------------------------------------------------------------- */
|
|
161
|
+
|
|
162
|
+
static void *
|
|
163
|
+
ca_record_func_clone (void *ap)
|
|
164
|
+
{
|
|
165
|
+
CARecord *ca = (CARecord *) ap;
|
|
166
|
+
return ca_record_new(ca->parent, ca->data_class);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static void
|
|
170
|
+
ca_record_func_allocate (void *ap)
|
|
171
|
+
{
|
|
172
|
+
CARecord *ca = (CARecord *) ap;
|
|
173
|
+
/* alias: parent attach + alias parent->ptr (Face has identical data layout) */
|
|
174
|
+
ca_attach(ca->parent);
|
|
175
|
+
ca->ptr = ca->parent->ptr;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static void
|
|
179
|
+
ca_record_func_create_mask (void *ap)
|
|
180
|
+
{
|
|
181
|
+
CARecord *ca = (CARecord *) ap;
|
|
182
|
+
ca_update_mask(ca->parent);
|
|
183
|
+
if ( ! ca->parent->mask ) {
|
|
184
|
+
ca_create_mask(ca->parent);
|
|
185
|
+
}
|
|
186
|
+
ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
|
|
187
|
+
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
ca_operation_function_t ca_record_func = {
|
|
191
|
+
-1, /* CA_OBJ_RECORD — filled by ca_install_obj_type */
|
|
192
|
+
CA_VIEW_ARRAY,
|
|
193
|
+
free_ca_record,
|
|
194
|
+
ca_record_func_clone,
|
|
195
|
+
ca_record_func_allocate,
|
|
196
|
+
ca_face_attach,
|
|
197
|
+
ca_face_sync,
|
|
198
|
+
ca_face_detach,
|
|
199
|
+
ca_face_fill_data,
|
|
200
|
+
ca_record_func_create_mask,
|
|
201
|
+
ca_face_xfer_index,
|
|
202
|
+
ca_face_xfer_addrs,
|
|
203
|
+
NULL, /* fold_stride: identity Face is not foldable */
|
|
204
|
+
ca_face_xfer_stride,
|
|
205
|
+
ca_face_xfer_all
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/* ------------------------------------------------------------------- */
|
|
209
|
+
|
|
210
|
+
/* Internal C builder — shared by .new (self-allocated parent) and
|
|
211
|
+
.wrap (user-supplied parent) paths. Pins parent_val via
|
|
212
|
+
rb_ca_set_parent for GC + lifecycle protection, and preallocates
|
|
213
|
+
the `member` ivar Hash used by rb_ca_face_field as a field-view
|
|
214
|
+
memoisation cache. */
|
|
215
|
+
static VALUE
|
|
216
|
+
ca_record_build (VALUE klass, VALUE data_class, VALUE parent_val)
|
|
217
|
+
{
|
|
218
|
+
CArray *parent_ca;
|
|
219
|
+
CARecord *ca;
|
|
220
|
+
VALUE obj;
|
|
221
|
+
|
|
222
|
+
if ( ! RTEST(rb_obj_is_data_class(data_class)) ) {
|
|
223
|
+
rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
|
|
224
|
+
}
|
|
225
|
+
TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent_ca);
|
|
226
|
+
if ( parent_ca->data_type != CA_FIXLEN ) {
|
|
227
|
+
rb_raise(rb_eTypeError,
|
|
228
|
+
"CARecord requires a CA_FIXLEN parent (got data_type=%d)",
|
|
229
|
+
parent_ca->data_type);
|
|
230
|
+
}
|
|
231
|
+
ca = ca_record_new(parent_ca, data_class);
|
|
232
|
+
obj = TypedData_Wrap_Struct(klass, &carecord_data_type, ca);
|
|
233
|
+
rb_ca_set_parent(obj, parent_val);
|
|
234
|
+
rb_ivar_set(obj, rb_intern("member"), rb_hash_new());
|
|
235
|
+
return obj;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* CARecord.new(data_class, *shape) or Sub.new(*shape) — atomic path:
|
|
239
|
+
allocate a fresh CA_FIXLEN entity and wrap it. Base class takes
|
|
240
|
+
`data_class` explicitly; a subclass that pinned its type via the
|
|
241
|
+
`data_class GeoCoord` DSL accepts only shape args. */
|
|
242
|
+
static VALUE
|
|
243
|
+
rb_ca_record_s_new (int argc, VALUE *argv, VALUE klass)
|
|
244
|
+
{
|
|
245
|
+
VALUE data_class, klass_dc, parent_val;
|
|
246
|
+
ca_size_t bytes;
|
|
247
|
+
ca_size_t dim[CA_RANK_MAX];
|
|
248
|
+
int ndim, shape_offset, i;
|
|
249
|
+
|
|
250
|
+
klass_dc = rb_iv_get(klass, "@data_class");
|
|
251
|
+
if ( ! NIL_P(klass_dc) ) {
|
|
252
|
+
/* subclass with DSL fix: shape args only */
|
|
253
|
+
data_class = klass_dc;
|
|
254
|
+
shape_offset = 0;
|
|
255
|
+
if ( argc > 0 && RTEST(rb_obj_is_data_class(argv[0])) ) {
|
|
256
|
+
rb_raise(rb_eArgError,
|
|
257
|
+
"subclass has fixed data_class via DSL; don't pass it again");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
/* base direct: first arg = data_class */
|
|
262
|
+
if ( argc < 1 ) {
|
|
263
|
+
rb_raise(rb_eArgError, "data_class required as first argument");
|
|
264
|
+
}
|
|
265
|
+
data_class = argv[0];
|
|
266
|
+
shape_offset = 1;
|
|
267
|
+
}
|
|
268
|
+
ndim = argc - shape_offset;
|
|
269
|
+
if ( ndim < 0 || ndim > CA_RANK_MAX ) {
|
|
270
|
+
rb_raise(rb_eArgError, "invalid number of shape arguments (%d)", ndim);
|
|
271
|
+
}
|
|
272
|
+
for ( i = 0; i < ndim; i++ ) {
|
|
273
|
+
dim[i] = NUM2SIZE(argv[shape_offset + i]);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if ( ! RTEST(rb_obj_is_data_class(data_class)) ) {
|
|
277
|
+
rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
|
|
278
|
+
}
|
|
279
|
+
bytes = NUM2SIZE(rb_const_get(data_class, rb_intern("DATA_SIZE")));
|
|
280
|
+
|
|
281
|
+
parent_val = rb_carray_new(CA_FIXLEN, ndim, dim, bytes, NULL);
|
|
282
|
+
return ca_record_build(klass, data_class, parent_val);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* CARecord.wrap(entity, data_class) or Sub.wrap(entity) — zero-copy
|
|
286
|
+
Face wrap of an existing CA_FIXLEN entity. Sibling of
|
|
287
|
+
CATime.wrap. */
|
|
288
|
+
static VALUE
|
|
289
|
+
rb_ca_record_s_wrap (int argc, VALUE *argv, VALUE klass)
|
|
290
|
+
{
|
|
291
|
+
VALUE entity_val, data_class, klass_dc;
|
|
292
|
+
|
|
293
|
+
klass_dc = rb_iv_get(klass, "@data_class");
|
|
294
|
+
if ( ! NIL_P(klass_dc) ) {
|
|
295
|
+
rb_scan_args(argc, argv, "1", &entity_val);
|
|
296
|
+
data_class = klass_dc;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
rb_scan_args(argc, argv, "2", &entity_val, &data_class);
|
|
300
|
+
}
|
|
301
|
+
rb_check_carray_object(entity_val);
|
|
302
|
+
return ca_record_build(klass, data_class, entity_val);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* Direct C accessor for the CARecord tail data_class. Called by
|
|
306
|
+
rb_ca_data_class in carray_attribute.c, dispatched on obj_type so
|
|
307
|
+
there is no Ruby roundtrip. */
|
|
308
|
+
VALUE
|
|
309
|
+
rb_ca_record_get_data_class (CArray *ca)
|
|
310
|
+
{
|
|
311
|
+
return ((CARecord *) ca)->data_class;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* Subclass DSL: `data_class Foo` inside `class Sub < CARecord`.
|
|
315
|
+
Set once and then immutable (reassignment raises). A zero-arg call
|
|
316
|
+
acts as a getter. The class ivar is what `.new` / `.wrap` read via
|
|
317
|
+
`rb_iv_get(klass, "@data_class")` to omit the explicit arg. */
|
|
318
|
+
static VALUE
|
|
319
|
+
rb_ca_record_s_data_class_dsl (int argc, VALUE *argv, VALUE klass)
|
|
320
|
+
{
|
|
321
|
+
VALUE current, given;
|
|
322
|
+
|
|
323
|
+
current = rb_iv_get(klass, "@data_class");
|
|
324
|
+
if ( argc == 0 ) {
|
|
325
|
+
return NIL_P(current) ? Qnil : current;
|
|
326
|
+
}
|
|
327
|
+
rb_scan_args(argc, argv, "1", &given);
|
|
328
|
+
if ( ! NIL_P(current) ) {
|
|
329
|
+
rb_raise(rb_eRuntimeError,
|
|
330
|
+
"data_class already fixed to %"PRIsVALUE
|
|
331
|
+
"; CARecord subclass data_class is immutable once set",
|
|
332
|
+
current);
|
|
333
|
+
}
|
|
334
|
+
if ( ! RTEST(rb_obj_is_data_class(given)) ) {
|
|
335
|
+
rb_raise(rb_eTypeError, "data_class must be a CAStruct subclass");
|
|
336
|
+
}
|
|
337
|
+
rb_iv_set(klass, "@data_class", given);
|
|
338
|
+
return given;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static VALUE
|
|
342
|
+
rb_ca_record_s_allocate (VALUE klass)
|
|
343
|
+
{
|
|
344
|
+
CARecord *ca;
|
|
345
|
+
return TypedData_Make_Struct(klass, CARecord, &carecord_data_type, ca);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static VALUE
|
|
349
|
+
rb_ca_record_initialize_copy (VALUE self, VALUE other)
|
|
350
|
+
{
|
|
351
|
+
CARecord *ca, *cs;
|
|
352
|
+
TypedData_Get_Struct(self, CARecord, &carecord_data_type, ca);
|
|
353
|
+
TypedData_Get_Struct(other, CARecord, &carecord_data_type, cs);
|
|
354
|
+
if ( ca_func[CA_OBJ_RECORD].pool_init ) {
|
|
355
|
+
ca_array_pool_alloc(ca, CA_OBJ_RECORD, cs->parent->ndim);
|
|
356
|
+
}
|
|
357
|
+
ca_record_setup(ca, cs->parent, cs->data_class);
|
|
358
|
+
return self;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/* ---------------------------------------------------------------------------
|
|
362
|
+
data_class identity predicates. A Ruby class that can serve as the
|
|
363
|
+
element type of a CARecord (i.e. the inner struct definition such as
|
|
364
|
+
GeoCoord / Pixel, not the CARecord subclass CAGeoCoord) must provide
|
|
365
|
+
the constants + methods checked below. `CArray.struct {...}` /
|
|
366
|
+
`CArray.union {...}` generate them automatically.
|
|
367
|
+
|
|
368
|
+
rb_obj_is_data_class(klass) duck-type predicate, Qtrue/Qfalse
|
|
369
|
+
ca_check_data_class(klass) same, raises on failure
|
|
370
|
+
CArray.data_class?(klass) Ruby surface for the predicate
|
|
371
|
+
|
|
372
|
+
Signatures stay in carray.h for cross-file extern use.
|
|
373
|
+
------------------------------------------------------------------------- */
|
|
374
|
+
|
|
375
|
+
VALUE
|
|
376
|
+
rb_obj_is_data_class (VALUE rtype)
|
|
377
|
+
{
|
|
378
|
+
VALUE has_data_size, has_member_names, has_member_table;
|
|
379
|
+
VALUE has_encode, has_decode;
|
|
380
|
+
if ( TYPE(rtype) == T_CLASS ) {
|
|
381
|
+
has_data_size =
|
|
382
|
+
rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("DATA_SIZE"));
|
|
383
|
+
has_member_names =
|
|
384
|
+
rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("MEMBERS"));
|
|
385
|
+
has_member_table =
|
|
386
|
+
rb_funcall(rtype, rb_intern("const_defined?"), 1, rb_str_new2("MEMBER_TABLE"));
|
|
387
|
+
has_encode =
|
|
388
|
+
rb_funcall(rtype, rb_intern("method_defined?"), 1, rb_str_new2("encode"));
|
|
389
|
+
has_decode = rb_respond_to(rtype, rb_intern("decode"));
|
|
390
|
+
return ( RTEST(has_data_size) &&
|
|
391
|
+
RTEST(has_member_table) && RTEST(has_member_names) &&
|
|
392
|
+
RTEST(has_encode) && RTEST(has_decode) ) ? Qtrue : Qfalse;
|
|
393
|
+
}
|
|
394
|
+
return Qfalse;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
void
|
|
398
|
+
ca_check_data_class (VALUE rtype)
|
|
399
|
+
{
|
|
400
|
+
if ( ! rb_obj_is_data_class(rtype) ) {
|
|
401
|
+
VALUE inspect = rb_inspect(rtype);
|
|
402
|
+
rb_raise(rb_eRuntimeError,
|
|
403
|
+
"<%s> is not a data_class, which should has the features\n" \
|
|
404
|
+
" * constant data_class::DATA_SIZE -> integer\n" \
|
|
405
|
+
" * constant data_class::MEMBERS -> array of string\n" \
|
|
406
|
+
" * constant data_class::MEMBER_TABLE -> hash\n" \
|
|
407
|
+
" * method data_class.decode(str) -> data_class object\n" \
|
|
408
|
+
" * method data_class#encode() -> string", StringValuePtr(inspect));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
static VALUE
|
|
413
|
+
rb_ca_s_is_data_class (VALUE self, VALUE rklass)
|
|
414
|
+
{
|
|
415
|
+
return rb_obj_is_data_class(rklass);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Face-state homogeneity callback for promote_list / CAStack. Two
|
|
419
|
+
CARecord instances are compatible iff their data_class is identical;
|
|
420
|
+
without this, multi-parent constructions would silently mix records
|
|
421
|
+
with different DATA_SIZE or field schema. */
|
|
422
|
+
static int
|
|
423
|
+
ca_record_state_compatible (CArray *a, CArray *b)
|
|
424
|
+
{
|
|
425
|
+
CARecord *ra = (CARecord *) a;
|
|
426
|
+
CARecord *rb = (CARecord *) b;
|
|
427
|
+
return (ra->data_class == rb->data_class) ? 1 : 0;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/* ------------------------------------------------------------------------- */
|
|
431
|
+
|
|
432
|
+
void
|
|
433
|
+
Init_ca_obj_record (void)
|
|
434
|
+
{
|
|
435
|
+
rb_cCARecord = rb_define_class("CARecord", rb_cCAFace);
|
|
436
|
+
|
|
437
|
+
ca_record_func.struct_size = sizeof(CARecord);
|
|
438
|
+
ca_record_func.pool_bytes = ca_record_pool_bytes;
|
|
439
|
+
ca_record_func.pool_init = ca_record_pool_init;
|
|
440
|
+
|
|
441
|
+
CA_OBJ_RECORD = ca_install_obj_type(rb_cCARecord,
|
|
442
|
+
&carecord_data_type,
|
|
443
|
+
rb_cCArrayMask,
|
|
444
|
+
&carray_mask_data_type,
|
|
445
|
+
&ca_record_func, sizeof(ca_record_func));
|
|
446
|
+
rb_define_const(rb_cObject, "CA_OBJ_RECORD", INT2NUM(CA_OBJ_RECORD));
|
|
447
|
+
|
|
448
|
+
/* Homogeneity gate for promote_list / CAStack. The Ruby class is
|
|
449
|
+
always CARecord, so the default class-equality check cannot tell
|
|
450
|
+
GeoCoord apart from Pixel; the callback compares data_class per
|
|
451
|
+
instance. */
|
|
452
|
+
ca_face_register_state_compatible(CA_OBJ_RECORD,
|
|
453
|
+
ca_record_state_compatible);
|
|
454
|
+
|
|
455
|
+
rb_define_alloc_func(rb_cCARecord, rb_ca_record_s_allocate);
|
|
456
|
+
rb_define_method(rb_cCARecord, "initialize_copy",
|
|
457
|
+
rb_ca_record_initialize_copy, 1);
|
|
458
|
+
|
|
459
|
+
rb_define_singleton_method(rb_cCARecord, "new", rb_ca_record_s_new, -1);
|
|
460
|
+
rb_define_singleton_method(rb_cCARecord, "wrap", rb_ca_record_s_wrap, -1);
|
|
461
|
+
rb_define_singleton_method(rb_cCARecord, "data_class",
|
|
462
|
+
rb_ca_record_s_data_class_dsl, -1);
|
|
463
|
+
|
|
464
|
+
/* #data_class is inherited from CArray via the universal Face
|
|
465
|
+
dispatch (rb_ca_data_class reads the tail through obj_type). */
|
|
466
|
+
|
|
467
|
+
rb_define_singleton_method(rb_cCArray, "data_class?", rb_ca_s_is_data_class, 1);
|
|
468
|
+
}
|