carray 2.0.1 → 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 +772 -297
- 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 +229 -791
- 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 +207 -240
- 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 -329
- 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 +1341 -198
- 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 +5 -15
- 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/mailmap +0 -1
- 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/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/carray_lazy.c
ADDED
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
CALazyMarker view + the shared lazy arena.
|
|
4
|
+
|
|
5
|
+
CALazyMarker is a zero-cost marker that holds a CArray entity and
|
|
6
|
+
causes `.sqrt` / `.sin` / etc. on it to build a lazy CAMonOp tree
|
|
7
|
+
instead of evaluating eagerly. A consumer op walks marker->parent
|
|
8
|
+
to drop the marker from the tree, so the marker itself is transient
|
|
9
|
+
— Ruby may keep a reference and re-consume (`m = a.lazy; m.sqrt +
|
|
10
|
+
m.sin`); the marker never mutates during consumption. Otherwise it
|
|
11
|
+
is a pure pass-through: every CArray operation delegates to the
|
|
12
|
+
parent. Detection happens via ca_is_lazy_view().
|
|
13
|
+
|
|
14
|
+
ca_lazy_arena is the shared slot-pool arena that CAMonOp / CABinOp
|
|
15
|
+
/ CAMonCmp / CABinCmp use for scratch during to_ca; slot buffers
|
|
16
|
+
stay alive across calls to amortise mmap into steady-state reuse.
|
|
17
|
+
|
|
18
|
+
---------------------------------------------------------------------------- */
|
|
19
|
+
|
|
20
|
+
#include "carray.h"
|
|
21
|
+
#include "carray_internal.h" /* ca_lazy_arena_*, ca_is_lazy_view */
|
|
22
|
+
|
|
23
|
+
int8_t CA_OBJ_LAZY_MARKER;
|
|
24
|
+
VALUE rb_cCALazyMarker;
|
|
25
|
+
|
|
26
|
+
typedef struct CALazyMarker {
|
|
27
|
+
int16_t obj_type;
|
|
28
|
+
int8_t data_type;
|
|
29
|
+
int8_t ndim;
|
|
30
|
+
int32_t flags;
|
|
31
|
+
ca_size_t bytes;
|
|
32
|
+
ca_size_t elements;
|
|
33
|
+
ca_size_t *dim;
|
|
34
|
+
char *ptr;
|
|
35
|
+
CArray *mask;
|
|
36
|
+
char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
|
|
37
|
+
CArray *parent;
|
|
38
|
+
uint32_t attach;
|
|
39
|
+
uint8_t nosync;
|
|
40
|
+
} CALazyMarker;
|
|
41
|
+
|
|
42
|
+
static size_t
|
|
43
|
+
ca_lazy_marker_dsize (const void *ap)
|
|
44
|
+
{
|
|
45
|
+
const CALazyMarker *ca = (const CALazyMarker *) ap;
|
|
46
|
+
return sizeof(CALazyMarker) + ca->ndim * sizeof(ca_size_t);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const rb_data_type_t calazy_marker_data_type = {
|
|
50
|
+
.parent = &caview_data_type,
|
|
51
|
+
.wrap_struct_name = "CALazyMarker",
|
|
52
|
+
.function = {
|
|
53
|
+
.dmark = ca_mark,
|
|
54
|
+
.dfree = ca_free,
|
|
55
|
+
.dsize = ca_lazy_marker_dsize,
|
|
56
|
+
.dcompact = NULL
|
|
57
|
+
},
|
|
58
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/* ------------------------------------------------------------------- */
|
|
62
|
+
|
|
63
|
+
static int
|
|
64
|
+
ca_lazy_marker_setup (CALazyMarker *ca, CArray *parent)
|
|
65
|
+
{
|
|
66
|
+
ca->obj_type = CA_OBJ_LAZY_MARKER;
|
|
67
|
+
ca->data_type = parent->data_type;
|
|
68
|
+
ca->flags = 0;
|
|
69
|
+
ca->ndim = parent->ndim;
|
|
70
|
+
ca->bytes = parent->bytes;
|
|
71
|
+
ca->elements = parent->elements;
|
|
72
|
+
ca->ptr = NULL;
|
|
73
|
+
ca->mask = NULL;
|
|
74
|
+
ca->dim = ALLOC_N(ca_size_t, parent->ndim);
|
|
75
|
+
ca->parent = parent;
|
|
76
|
+
ca->attach = 0;
|
|
77
|
+
ca->nosync = 0;
|
|
78
|
+
|
|
79
|
+
memcpy(ca->dim, parent->dim, parent->ndim * sizeof(ca_size_t));
|
|
80
|
+
|
|
81
|
+
if ( ca_has_mask(parent) ) {
|
|
82
|
+
ca_create_mask(ca);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if ( ca_is_scalar(parent) ) {
|
|
86
|
+
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* CAREFUL: the marker must be read-only. CArray.fuse depends on
|
|
90
|
+
destructive ops being rejected against a marker, and lazy views
|
|
91
|
+
as a family carry CA_FLAG_READ_ONLY (same shape as CAFake).
|
|
92
|
+
Without this flag, `m[i] = x` would silently write through to
|
|
93
|
+
the parent and violate the shadow semantics. */
|
|
94
|
+
ca_set_flag(ca, CA_FLAG_READ_ONLY);
|
|
95
|
+
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
CALazyMarker *
|
|
100
|
+
ca_lazy_marker_new (CArray *parent)
|
|
101
|
+
{
|
|
102
|
+
CALazyMarker *ca = ALLOC(CALazyMarker);
|
|
103
|
+
ca_lazy_marker_setup(ca, parent);
|
|
104
|
+
return ca;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void
|
|
108
|
+
free_ca_lazy_marker (void *ap)
|
|
109
|
+
{
|
|
110
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
111
|
+
if ( ca != NULL ) {
|
|
112
|
+
ca_free(ca->mask);
|
|
113
|
+
xfree(ca->dim);
|
|
114
|
+
xfree(ca);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* ------------------------------------------------------------------- */
|
|
119
|
+
/* Pass-through operations: everything delegates to parent. */
|
|
120
|
+
/* ------------------------------------------------------------------- */
|
|
121
|
+
|
|
122
|
+
static void *
|
|
123
|
+
ca_lazy_marker_func_clone (void *ap)
|
|
124
|
+
{
|
|
125
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
126
|
+
return ca_lazy_marker_new(ca->parent);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static void
|
|
130
|
+
ca_lazy_marker_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
131
|
+
{
|
|
132
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
133
|
+
if ( dir == CA_XFER_GET ) {
|
|
134
|
+
ca_fetch_index(ca->parent, idx, data);
|
|
135
|
+
} else {
|
|
136
|
+
ca_store_index(ca->parent, idx, data);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static void
|
|
141
|
+
ca_lazy_marker_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
142
|
+
void *data, int dir)
|
|
143
|
+
{
|
|
144
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
145
|
+
ca_xfer_addrs(ca->parent, n, addrs, data, dir);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static void
|
|
149
|
+
ca_lazy_marker_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
150
|
+
ca_size_t *strides, void *data, int dir)
|
|
151
|
+
{
|
|
152
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
153
|
+
ca_xfer_stride(ca->parent, starts, counts, strides, data, dir);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
static void
|
|
157
|
+
ca_lazy_marker_func_xfer_all (void *ap, void *data, int dir)
|
|
158
|
+
{
|
|
159
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
160
|
+
ca_xfer_all(ca->parent, data, dir);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static void
|
|
164
|
+
ca_lazy_marker_func_attach (void *ap)
|
|
165
|
+
{
|
|
166
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
167
|
+
ca_attach(ca->parent);
|
|
168
|
+
ca->ptr = ca->parent->ptr; /* alias */
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static void
|
|
172
|
+
ca_lazy_marker_func_sync (void *ap)
|
|
173
|
+
{
|
|
174
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
175
|
+
ca_sync(ca->parent);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static void
|
|
179
|
+
ca_lazy_marker_func_detach (void *ap)
|
|
180
|
+
{
|
|
181
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
182
|
+
ca->ptr = NULL;
|
|
183
|
+
ca_detach(ca->parent);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static void
|
|
187
|
+
ca_lazy_marker_func_allocate (void *ap)
|
|
188
|
+
{
|
|
189
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
190
|
+
ca_allocate(ca->parent);
|
|
191
|
+
ca->ptr = ca->parent->ptr; /* alias */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static void
|
|
195
|
+
ca_lazy_marker_func_fill_data (void *ap, void *ptr)
|
|
196
|
+
{
|
|
197
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
198
|
+
ca_fill(ca->parent, ptr);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static void
|
|
202
|
+
ca_lazy_marker_func_create_mask (void *ap)
|
|
203
|
+
{
|
|
204
|
+
CALazyMarker *ca = (CALazyMarker *) ap;
|
|
205
|
+
if ( ! ca->parent->mask ) {
|
|
206
|
+
ca_create_mask(ca->parent);
|
|
207
|
+
}
|
|
208
|
+
ca->mask =
|
|
209
|
+
(CArray *) ca_refer_new(ca->parent->mask,
|
|
210
|
+
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
ca_operation_function_t ca_lazy_marker_func = {
|
|
214
|
+
-1, /* CA_OBJ_LAZY_MARKER, set at install time */
|
|
215
|
+
CA_VIEW_ARRAY,
|
|
216
|
+
free_ca_lazy_marker,
|
|
217
|
+
ca_lazy_marker_func_clone,
|
|
218
|
+
ca_lazy_marker_func_allocate,
|
|
219
|
+
ca_lazy_marker_func_attach,
|
|
220
|
+
ca_lazy_marker_func_sync,
|
|
221
|
+
ca_lazy_marker_func_detach,
|
|
222
|
+
ca_lazy_marker_func_fill_data,
|
|
223
|
+
ca_lazy_marker_func_create_mask,
|
|
224
|
+
ca_lazy_marker_func_xfer_index,
|
|
225
|
+
ca_lazy_marker_func_xfer_addrs,
|
|
226
|
+
NULL, /* fold_stride: not implemented */
|
|
227
|
+
ca_lazy_marker_func_xfer_stride,
|
|
228
|
+
ca_lazy_marker_func_xfer_all,
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
/* ------------------------------------------------------------------- */
|
|
232
|
+
|
|
233
|
+
VALUE
|
|
234
|
+
rb_ca_lazy_marker_new (VALUE cary)
|
|
235
|
+
{
|
|
236
|
+
volatile VALUE obj;
|
|
237
|
+
CArray *parent;
|
|
238
|
+
CALazyMarker *ca;
|
|
239
|
+
rb_check_carray_object(cary);
|
|
240
|
+
TypedData_Get_Struct(cary, CArray, &carray_data_type, parent);
|
|
241
|
+
ca = ca_lazy_marker_new(parent);
|
|
242
|
+
obj = ca_wrap_struct(ca);
|
|
243
|
+
rb_ca_set_parent(obj, cary);
|
|
244
|
+
return obj;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* CArray#lazy — return a zero-cost CALazyMarker wrapping self. Subsequent
|
|
248
|
+
* element-wise ops (.sqrt / .sin / .+ / ...) build a lazy CAMonOp / CABinOp
|
|
249
|
+
* tree instead of evaluating eagerly; `.to_ca` materialises. */
|
|
250
|
+
VALUE
|
|
251
|
+
rb_ca_lazy (VALUE self)
|
|
252
|
+
{
|
|
253
|
+
return rb_ca_lazy_marker_new(self);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ------------------------------------------------------------------- */
|
|
257
|
+
/* ca_lazy_arena */
|
|
258
|
+
/* ------------------------------------------------------------------- */
|
|
259
|
+
|
|
260
|
+
/* Slot-pool arena. Each slot is an independent xmalloc'd buffer that
|
|
261
|
+
stays alive across to_ca calls; acquire / release toggles the
|
|
262
|
+
in_use flag, not the buffer itself, so simultaneous nested acquires
|
|
263
|
+
(deep CABinOp chain) hold stable pointers. A single-cursor + LIFO
|
|
264
|
+
stack design would force realloc when an outer acquire grew the
|
|
265
|
+
stack while an inner acquire still held the previous base — the
|
|
266
|
+
slot pool sidesteps that by design.
|
|
267
|
+
|
|
268
|
+
Steady state:
|
|
269
|
+
first to_ca call xmalloc N slots
|
|
270
|
+
subsequent calls reuse warm slots
|
|
271
|
+
best-fit allocation keeps small requests (mask scratch) out of
|
|
272
|
+
large data slots
|
|
273
|
+
|
|
274
|
+
Footprint: 32 slots × max observed size (up to 32 × max_slab_bytes;
|
|
275
|
+
e.g. N=1M f64, depth-8 chain = 8 × 8MB = 64MB kept resident). When
|
|
276
|
+
the slot pool is exhausted the acquire raises: this signals a
|
|
277
|
+
programming error or a pathological chain rather than a graceful
|
|
278
|
+
fallback.
|
|
279
|
+
|
|
280
|
+
CAREFUL: single-thread only (see CLAUDE.md "thread-safety is not a
|
|
281
|
+
goal"). The arena is process-global static state. */
|
|
282
|
+
|
|
283
|
+
#define CA_LAZY_ARENA_SLOTS 32
|
|
284
|
+
|
|
285
|
+
typedef struct ca_lazy_arena_slot {
|
|
286
|
+
void *ptr; /* xmalloc'd buffer, NULL = unused-and-unallocated */
|
|
287
|
+
ca_size_t bytes; /* allocated size of ptr (= capacity of this slot) */
|
|
288
|
+
int in_use; /* 1 = currently acquired, 0 = available */
|
|
289
|
+
} ca_lazy_arena_slot_t;
|
|
290
|
+
|
|
291
|
+
typedef struct ca_lazy_arena {
|
|
292
|
+
ca_lazy_arena_slot_t slots[CA_LAZY_ARENA_SLOTS];
|
|
293
|
+
int depth; /* enter/exit nest count */
|
|
294
|
+
ca_size_t debug_acquire_count; /* test instrumentation */
|
|
295
|
+
ca_size_t debug_xmalloc_count; /* test: how many xmallocs total */
|
|
296
|
+
ca_size_t debug_reuse_count; /* test: how many acquire = reuse */
|
|
297
|
+
} ca_lazy_arena_t;
|
|
298
|
+
|
|
299
|
+
static ca_lazy_arena_t ca_lazy_arena = {0};
|
|
300
|
+
|
|
301
|
+
void
|
|
302
|
+
ca_lazy_arena_enter (void)
|
|
303
|
+
{
|
|
304
|
+
if ( ca_lazy_arena.depth == 0 ) {
|
|
305
|
+
/* Top-level reset to recover from a prior exception that left
|
|
306
|
+
slots in_use without a matching release. Safe because
|
|
307
|
+
depth==0 means no nested caller is mid-acquire. */
|
|
308
|
+
int i;
|
|
309
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
310
|
+
ca_lazy_arena.slots[i].in_use = 0;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
ca_lazy_arena.depth++;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
void
|
|
317
|
+
ca_lazy_arena_exit (void)
|
|
318
|
+
{
|
|
319
|
+
if ( ca_lazy_arena.depth > 0 ) {
|
|
320
|
+
ca_lazy_arena.depth--;
|
|
321
|
+
}
|
|
322
|
+
/* Keep all slot buffers; they amortise into subsequent calls. */
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
void *
|
|
326
|
+
ca_lazy_arena_acquire (ca_size_t bytes)
|
|
327
|
+
{
|
|
328
|
+
int i, best, empty;
|
|
329
|
+
ca_size_t best_bytes;
|
|
330
|
+
|
|
331
|
+
if ( bytes <= 0 ) bytes = 1;
|
|
332
|
+
|
|
333
|
+
ca_lazy_arena.debug_acquire_count++;
|
|
334
|
+
|
|
335
|
+
/* Pass 1: best-fit among unused warm slots (smallest >= bytes).
|
|
336
|
+
CAREFUL: ca_size_t is signed int64_t, so the "no match yet"
|
|
337
|
+
sentinel must be CA_LENGTH_MAX — NOT -1, which would compare
|
|
338
|
+
less than any real capacity. */
|
|
339
|
+
best = -1;
|
|
340
|
+
best_bytes = CA_LENGTH_MAX;
|
|
341
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
342
|
+
ca_lazy_arena_slot_t *s = &ca_lazy_arena.slots[i];
|
|
343
|
+
if ( s->in_use ) continue;
|
|
344
|
+
if ( s->ptr == NULL ) continue;
|
|
345
|
+
if ( s->bytes < bytes ) continue;
|
|
346
|
+
if ( s->bytes < best_bytes ) {
|
|
347
|
+
best = i;
|
|
348
|
+
best_bytes = s->bytes;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if ( best >= 0 ) {
|
|
352
|
+
ca_lazy_arena.slots[best].in_use = 1;
|
|
353
|
+
ca_lazy_arena.debug_reuse_count++;
|
|
354
|
+
return ca_lazy_arena.slots[best].ptr;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
/* Pass 2: empty slot — xmalloc a fresh buffer. */
|
|
359
|
+
empty = -1;
|
|
360
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
361
|
+
if ( ca_lazy_arena.slots[i].ptr == NULL ) {
|
|
362
|
+
empty = i;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if ( empty >= 0 ) {
|
|
367
|
+
ca_lazy_arena.slots[empty].ptr = xmalloc(bytes);
|
|
368
|
+
ca_lazy_arena.slots[empty].bytes = bytes;
|
|
369
|
+
ca_lazy_arena.slots[empty].in_use = 1;
|
|
370
|
+
ca_lazy_arena.debug_xmalloc_count++;
|
|
371
|
+
return ca_lazy_arena.slots[empty].ptr;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* Pass 3: all slots have ptrs. Find a non-in-use slot and grow it
|
|
375
|
+
(= xfree + xmalloc). This pays a mmap roundtrip but only on
|
|
376
|
+
slot pool exhaustion (= unusual size request). */
|
|
377
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
378
|
+
if ( ! ca_lazy_arena.slots[i].in_use ) {
|
|
379
|
+
xfree(ca_lazy_arena.slots[i].ptr);
|
|
380
|
+
ca_lazy_arena.slots[i].ptr = xmalloc(bytes);
|
|
381
|
+
ca_lazy_arena.slots[i].bytes = bytes;
|
|
382
|
+
ca_lazy_arena.slots[i].in_use = 1;
|
|
383
|
+
ca_lazy_arena.debug_xmalloc_count++;
|
|
384
|
+
return ca_lazy_arena.slots[i].ptr;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/* Pass 4: all CA_LAZY_ARENA_SLOTS in use simultaneously. This is
|
|
389
|
+
a programming error or a pathological chain. Raise. */
|
|
390
|
+
rb_raise(rb_eRuntimeError,
|
|
391
|
+
"ca_lazy_arena_acquire: all %d slots in use simultaneously "
|
|
392
|
+
"(chain depth exceeds arena capacity)",
|
|
393
|
+
CA_LAZY_ARENA_SLOTS);
|
|
394
|
+
return NULL; /* unreachable */
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
void
|
|
398
|
+
ca_lazy_arena_release (void *ptr)
|
|
399
|
+
{
|
|
400
|
+
int i;
|
|
401
|
+
if ( ptr == NULL ) return;
|
|
402
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
403
|
+
if ( ca_lazy_arena.slots[i].ptr == ptr ) {
|
|
404
|
+
ca_lazy_arena.slots[i].in_use = 0;
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/* Unknown ptr — could indicate caller mixed arena release with a
|
|
409
|
+
non-arena pointer. Be lenient (= no raise) to avoid masking
|
|
410
|
+
genuine bugs at unrelated callsites. */
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* Test instrumentation — exposed to Ruby for the arena smoke and
|
|
414
|
+
regression assertions. Not user-facing API. */
|
|
415
|
+
static VALUE
|
|
416
|
+
rb_ca_lazy_arena_s_reset_counters (VALUE klass)
|
|
417
|
+
{
|
|
418
|
+
ca_lazy_arena.debug_acquire_count = 0;
|
|
419
|
+
ca_lazy_arena.debug_xmalloc_count = 0;
|
|
420
|
+
ca_lazy_arena.debug_reuse_count = 0;
|
|
421
|
+
return Qnil;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
static VALUE
|
|
425
|
+
rb_ca_lazy_arena_s_acquire_count (VALUE klass)
|
|
426
|
+
{
|
|
427
|
+
return SIZE2NUM(ca_lazy_arena.debug_acquire_count);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
static VALUE
|
|
431
|
+
rb_ca_lazy_arena_s_xmalloc_count (VALUE klass)
|
|
432
|
+
{
|
|
433
|
+
return SIZE2NUM(ca_lazy_arena.debug_xmalloc_count);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
static VALUE
|
|
437
|
+
rb_ca_lazy_arena_s_reuse_count (VALUE klass)
|
|
438
|
+
{
|
|
439
|
+
return SIZE2NUM(ca_lazy_arena.debug_reuse_count);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static VALUE
|
|
443
|
+
rb_ca_lazy_arena_s_depth (VALUE klass)
|
|
444
|
+
{
|
|
445
|
+
return INT2NUM(ca_lazy_arena.depth);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
static VALUE
|
|
449
|
+
rb_ca_lazy_arena_s_slot_in_use_count (VALUE klass)
|
|
450
|
+
{
|
|
451
|
+
int i, n = 0;
|
|
452
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
453
|
+
if ( ca_lazy_arena.slots[i].in_use ) n++;
|
|
454
|
+
}
|
|
455
|
+
return INT2NUM(n);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* Per-slot capacity sweep for observability tests. Returns an
|
|
459
|
+
Array of Integer bytes for every populated slot, so a test can
|
|
460
|
+
assert that mixed boolean (1 byte/cell) and f64 (8 byte/cell)
|
|
461
|
+
acquires develop distinct size classes under best-fit — otherwise
|
|
462
|
+
boolean acquires would sit in oversized f64 slots and force fresh
|
|
463
|
+
xmalloc for subsequent f64 acquires. */
|
|
464
|
+
static VALUE
|
|
465
|
+
rb_ca_lazy_arena_s_slot_capacities (VALUE klass)
|
|
466
|
+
{
|
|
467
|
+
int i;
|
|
468
|
+
VALUE arr = rb_ary_new();
|
|
469
|
+
(void) klass;
|
|
470
|
+
for ( i = 0; i < CA_LAZY_ARENA_SLOTS; i++ ) {
|
|
471
|
+
if ( ca_lazy_arena.slots[i].ptr != NULL ) {
|
|
472
|
+
rb_ary_push(arr, SIZE2NUM(ca_lazy_arena.slots[i].bytes));
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return arr;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* ------------------------------------------------------------------- */
|
|
479
|
+
|
|
480
|
+
/* ca_lazy_wrap_scalar(other, self_ca) — wrap a non-CArray Ruby value
|
|
481
|
+
* as a 1-element CScalar whose data_type follows the array's family,
|
|
482
|
+
* mirroring the array+scalar branch of rb_ca_cast_self_or_other. The
|
|
483
|
+
* scalar takes on self's data_type so binops preserve self's
|
|
484
|
+
* precision (`f32_array + 2.5` stays f32).
|
|
485
|
+
*
|
|
486
|
+
* CA_OBJECT self -> CA_OBJECT
|
|
487
|
+
* CA_BOOLEAN self -> derive from other's Ruby type via
|
|
488
|
+
* ca_value_to_data_type (bool arithmetic is a
|
|
489
|
+
* corner case; eager widens the array, so we
|
|
490
|
+
* just let the scalar choose)
|
|
491
|
+
* numeric self -> self_ca->data_type
|
|
492
|
+
*
|
|
493
|
+
* Callers broadcast against the array via stride 0 in xfer_stride
|
|
494
|
+
* (or wrap the scalar in CAUnboundRepeat when the chain needs it). */
|
|
495
|
+
VALUE
|
|
496
|
+
ca_lazy_wrap_scalar (VALUE other, CArray *self_ca)
|
|
497
|
+
{
|
|
498
|
+
int8_t dt;
|
|
499
|
+
|
|
500
|
+
if ( ca_is_object_type(self_ca) ) {
|
|
501
|
+
dt = CA_OBJECT;
|
|
502
|
+
}
|
|
503
|
+
else if ( self_ca->data_type == CA_BOOLEAN ) {
|
|
504
|
+
dt = ca_value_to_data_type(other);
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
dt = self_ca->data_type;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return rb_cscalar_new_with_value(dt, 0, other);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
static VALUE
|
|
514
|
+
rb_ca_lazy_marker_s_allocate (VALUE klass)
|
|
515
|
+
{
|
|
516
|
+
CALazyMarker *ca;
|
|
517
|
+
return TypedData_Make_Struct(klass, CALazyMarker,
|
|
518
|
+
&calazy_marker_data_type, ca);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
static VALUE
|
|
522
|
+
rb_ca_lazy_marker_initialize_copy (VALUE self, VALUE other)
|
|
523
|
+
{
|
|
524
|
+
CALazyMarker *ca, *cs;
|
|
525
|
+
TypedData_Get_Struct(self, CALazyMarker, &calazy_marker_data_type, ca);
|
|
526
|
+
TypedData_Get_Struct(other, CALazyMarker, &calazy_marker_data_type, cs);
|
|
527
|
+
ca_lazy_marker_setup(ca, cs->parent);
|
|
528
|
+
return self;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
void
|
|
532
|
+
Init_carray_lazy (void)
|
|
533
|
+
{
|
|
534
|
+
rb_cCALazyMarker = rb_define_class("CALazyMarker", rb_cCAView);
|
|
535
|
+
|
|
536
|
+
CA_OBJ_LAZY_MARKER = ca_install_obj_type(rb_cCALazyMarker,
|
|
537
|
+
&calazy_marker_data_type,
|
|
538
|
+
rb_cCArrayMask,
|
|
539
|
+
&carray_mask_data_type,
|
|
540
|
+
&ca_lazy_marker_func, sizeof(ca_lazy_marker_func));
|
|
541
|
+
rb_define_const(rb_cObject, "CA_OBJ_LAZY_MARKER",
|
|
542
|
+
INT2NUM(CA_OBJ_LAZY_MARKER));
|
|
543
|
+
|
|
544
|
+
rb_define_method(rb_cCArray, "lazy", rb_ca_lazy, 0);
|
|
545
|
+
|
|
546
|
+
rb_define_alloc_func(rb_cCALazyMarker, rb_ca_lazy_marker_s_allocate);
|
|
547
|
+
rb_define_method(rb_cCALazyMarker, "initialize_copy",
|
|
548
|
+
rb_ca_lazy_marker_initialize_copy, 1);
|
|
549
|
+
|
|
550
|
+
/* Arena test instrumentation (not user-facing). Bound on CArray
|
|
551
|
+
for symmetry with CAMonOp / CABinOp counters, but the arena is
|
|
552
|
+
a singleton process-wide state. */
|
|
553
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_reset_counters__",
|
|
554
|
+
rb_ca_lazy_arena_s_reset_counters, 0);
|
|
555
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_acquire_count__",
|
|
556
|
+
rb_ca_lazy_arena_s_acquire_count, 0);
|
|
557
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_xmalloc_count__",
|
|
558
|
+
rb_ca_lazy_arena_s_xmalloc_count, 0);
|
|
559
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_reuse_count__",
|
|
560
|
+
rb_ca_lazy_arena_s_reuse_count, 0);
|
|
561
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_depth__",
|
|
562
|
+
rb_ca_lazy_arena_s_depth, 0);
|
|
563
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_slot_in_use_count__",
|
|
564
|
+
rb_ca_lazy_arena_s_slot_in_use_count, 0);
|
|
565
|
+
rb_define_singleton_method(rb_cCArray, "__lazy_arena_slot_capacities__",
|
|
566
|
+
rb_ca_lazy_arena_s_slot_capacities, 0);
|
|
567
|
+
}
|