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/carray_mask.c
CHANGED
|
@@ -423,85 +423,221 @@ ca_create_mask_attach (VALUE arg)
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
CArray *
|
|
426
|
-
|
|
426
|
+
ca_mask_standin_new (CArray *parent)
|
|
427
427
|
{
|
|
428
|
-
*
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if ( ca_is_readonly(p) ) {
|
|
433
|
-
ca_set_flag(z, CA_FLAG_READ_ONLY);
|
|
434
|
-
}
|
|
435
|
-
*standin = z;
|
|
436
|
-
return z;
|
|
428
|
+
CArray *z = carray_new(CA_BOOLEAN, parent->ndim, parent->dim, 0, NULL);
|
|
429
|
+
MEMZERO(z->ptr, boolean8_t, z->elements);
|
|
430
|
+
if ( ca_is_readonly(parent) ) {
|
|
431
|
+
ca_set_flag(z, CA_FLAG_READ_ONLY);
|
|
437
432
|
}
|
|
438
|
-
|
|
439
|
-
return p->mask;
|
|
433
|
+
return z;
|
|
440
434
|
}
|
|
441
435
|
|
|
442
436
|
/* A value array or a mask array: a parent that can never be given a mask,
|
|
443
437
|
whose stand-in therefore stays in place for good. */
|
|
444
438
|
static int
|
|
445
|
-
|
|
439
|
+
ca_mask_standin_parent_unmaskable (CArray *parent)
|
|
440
|
+
{
|
|
441
|
+
return ca_is_value_array(parent) || ca_is_mask_array(parent);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
CArray *
|
|
445
|
+
ca_mask_standin_current (CArray *mask_view, CArray *reading, CArray *parent,
|
|
446
|
+
CArray *standin)
|
|
446
447
|
{
|
|
447
|
-
|
|
448
|
+
if ( standin == NULL || reading != standin
|
|
449
|
+
|| ca_mask_standin_parent_unmaskable(parent) ) {
|
|
450
|
+
return reading;
|
|
451
|
+
}
|
|
452
|
+
/* Not inside an attach window whose buffer is out: that buffer and the
|
|
453
|
+
detach to come are those of the stand-in. The attach and allocate
|
|
454
|
+
slots run before the buffer is published, and may still give way. */
|
|
455
|
+
if ( CAVIEW(mask_view)->attach > 0 && mask_view->ptr != NULL ) {
|
|
456
|
+
return reading;
|
|
457
|
+
}
|
|
458
|
+
/* A read-only parent (a lazy expression, a broadcast) is never given a
|
|
459
|
+
mask by a write, but can still have one later through its operand or
|
|
460
|
+
root. */
|
|
461
|
+
if ( ! ca_has_mask(parent) ) {
|
|
462
|
+
return reading;
|
|
463
|
+
}
|
|
464
|
+
ca_create_mask(parent);
|
|
465
|
+
return ( parent->mask != NULL ) ? parent->mask : reading;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
void
|
|
469
|
+
ca_mask_standin_settle (CArray *parent, CArray *standin)
|
|
470
|
+
{
|
|
471
|
+
volatile VALUE holder = 0;
|
|
472
|
+
boolean8_t *z, one = 1;
|
|
473
|
+
ca_size_t *addrs;
|
|
474
|
+
ca_size_t i, m = 0, n;
|
|
475
|
+
|
|
476
|
+
if ( standin == NULL || ca_test_flag(standin, CA_FLAG_READ_ONLY) ) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
z = (boolean8_t *) standin->ptr;
|
|
480
|
+
n = standin->elements;
|
|
481
|
+
for ( i = 0; i < n && ! z[i]; i++ ) ;
|
|
482
|
+
if ( i == n ) {
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
if ( ca_mask_standin_parent_unmaskable(parent) ) {
|
|
486
|
+
MEMZERO(z, boolean8_t, n);
|
|
487
|
+
rb_raise(rb_eTypeError, "can not create mask array for the %s array",
|
|
488
|
+
ca_is_value_array(parent) ? "value" : "mask");
|
|
489
|
+
}
|
|
490
|
+
ca_create_mask(parent);
|
|
491
|
+
/* The trues are added to the parent's mask, not copied over it: the
|
|
492
|
+
parent may have come to have masked cells of its own meanwhile. */
|
|
493
|
+
addrs = ALLOCV_N(ca_size_t, holder, n);
|
|
494
|
+
for ( ; i < n; i++ ) {
|
|
495
|
+
if ( z[i] ) {
|
|
496
|
+
addrs[m++] = i;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
ca_fill_addrs(parent->mask, m, addrs, &one);
|
|
500
|
+
ALLOCV_END(holder);
|
|
501
|
+
MEMZERO(z, boolean8_t, n);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
CArray *
|
|
505
|
+
ca_multi_parent_mask (CArray *p, CArray **standin)
|
|
506
|
+
{
|
|
507
|
+
*standin = NULL;
|
|
508
|
+
if ( ! ca_has_mask(p) ) {
|
|
509
|
+
*standin = ca_mask_standin_new(p);
|
|
510
|
+
return *standin;
|
|
511
|
+
}
|
|
512
|
+
ca_create_mask(p);
|
|
513
|
+
return p->mask;
|
|
448
514
|
}
|
|
449
515
|
|
|
450
516
|
void
|
|
451
517
|
ca_multi_parent_mask_refresh (CArray *mask, CArray **parents,
|
|
452
|
-
CArray **standins, int32_t n
|
|
518
|
+
CArray **standins, int32_t n)
|
|
453
519
|
{
|
|
454
520
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
455
521
|
int32_t k;
|
|
456
|
-
|
|
457
|
-
the parents it was opened with. The attach and allocate slots run
|
|
458
|
-
before the buffer is published, and replace the stand-ins then. */
|
|
459
|
-
if ( standins == NULL || ( CAVIEW(mask)->attach > 0 && mask->ptr != NULL ) ) {
|
|
522
|
+
if ( standins == NULL ) {
|
|
460
523
|
return;
|
|
461
524
|
}
|
|
462
525
|
/* A replaced stand-in stays allocated until the view is freed: a copy
|
|
463
526
|
of the mask (dup) may still point at it. */
|
|
464
527
|
for ( k = 0; k < n; k++ ) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|| ca_test_flag(z, CA_FLAG_READ_ONLY)
|
|
468
|
-
|| ca_multi_parent_mask_unmaskable(parents[k]) ) {
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
if ( ! ( for_write || ca_has_mask(parents[k]) ) ) {
|
|
472
|
-
continue;
|
|
473
|
-
}
|
|
474
|
-
ca_create_mask(parents[k]);
|
|
475
|
-
mp->parents[k] = parents[k]->mask;
|
|
476
|
-
if ( k == 0 ) {
|
|
477
|
-
CAVIEW(mask)->parent = parents[k]->mask;
|
|
478
|
-
}
|
|
528
|
+
mp->parents[k] = ca_mask_standin_current(mask, mp->parents[k], parents[k],
|
|
529
|
+
standins[k]);
|
|
479
530
|
}
|
|
531
|
+
CAVIEW(mask)->parent = mp->parents[0];
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
typedef struct {
|
|
535
|
+
CArray *mask;
|
|
536
|
+
CArray **blanks;
|
|
537
|
+
CArray **saved;
|
|
538
|
+
CArray *saved_parent;
|
|
539
|
+
int32_t n;
|
|
540
|
+
int finished;
|
|
541
|
+
VALUE (*body)(VALUE);
|
|
542
|
+
VALUE arg;
|
|
543
|
+
} ca_mp_trial_t;
|
|
544
|
+
|
|
545
|
+
static VALUE
|
|
546
|
+
ca_mp_trial_body (VALUE p)
|
|
547
|
+
{
|
|
548
|
+
ca_mp_trial_t *t = (ca_mp_trial_t *) p;
|
|
549
|
+
t->body(t->arg);
|
|
550
|
+
t->finished = 1;
|
|
551
|
+
return Qnil;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
static void
|
|
555
|
+
ca_mp_trial_free_blanks (ca_mp_trial_t *t)
|
|
556
|
+
{
|
|
557
|
+
int32_t k;
|
|
558
|
+
for ( k = 0; k < t->n; k++ ) {
|
|
559
|
+
ca_free(t->blanks[k]);
|
|
560
|
+
t->blanks[k] = NULL;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
static VALUE
|
|
565
|
+
ca_mp_trial_restore (VALUE p)
|
|
566
|
+
{
|
|
567
|
+
ca_mp_trial_t *t = (ca_mp_trial_t *) p;
|
|
568
|
+
CAMultiParent *mp = (CAMultiParent *) t->mask;
|
|
569
|
+
int32_t k;
|
|
570
|
+
for ( k = 0; k < t->n; k++ ) {
|
|
571
|
+
mp->parents[k] = t->saved[k];
|
|
572
|
+
}
|
|
573
|
+
CAVIEW(t->mask)->parent = t->saved_parent;
|
|
574
|
+
if ( ! t->finished ) {
|
|
575
|
+
ca_mp_trial_free_blanks(t);
|
|
576
|
+
}
|
|
577
|
+
return Qnil;
|
|
480
578
|
}
|
|
481
579
|
|
|
482
580
|
void
|
|
483
|
-
|
|
484
|
-
|
|
581
|
+
ca_multi_parent_mask_refuse_first (CArray *mask, CArray **parents,
|
|
582
|
+
CArray **standins, int32_t n,
|
|
583
|
+
VALUE (*body)(VALUE), VALUE arg)
|
|
485
584
|
{
|
|
486
585
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
487
|
-
|
|
586
|
+
volatile VALUE h_blank = 0, h_saved = 0;
|
|
587
|
+
ca_mp_trial_t t;
|
|
588
|
+
int32_t k, refused = -1;
|
|
488
589
|
if ( standins == NULL ) {
|
|
489
590
|
return;
|
|
490
591
|
}
|
|
491
592
|
for ( k = 0; k < n; k++ ) {
|
|
492
|
-
|
|
593
|
+
if ( standins[k] != NULL && mp->parents[k] == standins[k]
|
|
594
|
+
&& ca_mask_standin_parent_unmaskable(parents[k]) ) {
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if ( k == n ) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
t.mask = mask;
|
|
602
|
+
t.n = n;
|
|
603
|
+
t.finished = 0;
|
|
604
|
+
t.body = body;
|
|
605
|
+
t.arg = arg;
|
|
606
|
+
t.saved_parent = CAVIEW(mask)->parent;
|
|
607
|
+
t.blanks = ALLOCV_N(CArray *, h_blank, n);
|
|
608
|
+
t.saved = ALLOCV_N(CArray *, h_saved, n);
|
|
609
|
+
for ( k = 0; k < n; k++ ) {
|
|
610
|
+
t.blanks[k] = NULL;
|
|
611
|
+
}
|
|
612
|
+
for ( k = 0; k < n; k++ ) {
|
|
613
|
+
CArray *m = mp->parents[k];
|
|
614
|
+
t.saved[k] = m;
|
|
615
|
+
t.blanks[k] = carray_new(CA_BOOLEAN, m->ndim, m->dim, 0, NULL);
|
|
616
|
+
MEMZERO(t.blanks[k]->ptr, boolean8_t, t.blanks[k]->elements);
|
|
617
|
+
}
|
|
618
|
+
for ( k = 0; k < n; k++ ) {
|
|
619
|
+
mp->parents[k] = t.blanks[k];
|
|
620
|
+
}
|
|
621
|
+
CAVIEW(mask)->parent = t.blanks[0];
|
|
622
|
+
rb_ensure(ca_mp_trial_body, (VALUE) &t, ca_mp_trial_restore, (VALUE) &t);
|
|
623
|
+
for ( k = 0; k < n && refused < 0; k++ ) {
|
|
624
|
+
CArray *z = t.blanks[k];
|
|
493
625
|
ca_size_t i;
|
|
494
|
-
if (
|
|
495
|
-
|| !
|
|
626
|
+
if ( standins[k] == NULL || t.saved[k] != standins[k]
|
|
627
|
+
|| ! ca_mask_standin_parent_unmaskable(parents[k]) ) {
|
|
496
628
|
continue;
|
|
497
629
|
}
|
|
498
630
|
for ( i = 0; i < z->elements && ! ((boolean8_t *) z->ptr)[i]; i++ ) ;
|
|
499
|
-
if ( i
|
|
500
|
-
|
|
631
|
+
if ( i < z->elements ) {
|
|
632
|
+
refused = k;
|
|
501
633
|
}
|
|
502
|
-
|
|
634
|
+
}
|
|
635
|
+
ca_mp_trial_free_blanks(&t);
|
|
636
|
+
ALLOCV_END(h_blank);
|
|
637
|
+
ALLOCV_END(h_saved);
|
|
638
|
+
if ( refused >= 0 ) {
|
|
503
639
|
rb_raise(rb_eTypeError, "can not create mask array for the %s array",
|
|
504
|
-
ca_is_value_array(parents[
|
|
640
|
+
ca_is_value_array(parents[refused]) ? "value" : "mask");
|
|
505
641
|
}
|
|
506
642
|
}
|
|
507
643
|
|
|
@@ -510,26 +646,20 @@ ca_multi_parent_mask_settle (CArray *mask, CArray **parents,
|
|
|
510
646
|
CArray **standins, int32_t n)
|
|
511
647
|
{
|
|
512
648
|
CAMultiParent *mp = (CAMultiParent *) mask;
|
|
513
|
-
int32_t k;
|
|
649
|
+
int32_t k, pass;
|
|
514
650
|
if ( standins == NULL ) {
|
|
515
651
|
return;
|
|
516
652
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
for ( i = 0; i < z->elements && ! ((boolean8_t *) z->ptr)[i]; i++ ) ;
|
|
527
|
-
if ( i == z->elements ) {
|
|
528
|
-
continue;
|
|
653
|
+
/* The parts that can have no mask first, so that a refused true leaves
|
|
654
|
+
the other parts as they were. */
|
|
655
|
+
for ( pass = 0; pass < 2; pass++ ) {
|
|
656
|
+
for ( k = 0; k < n; k++ ) {
|
|
657
|
+
if ( standins[k] == NULL || mp->parents[k] != standins[k]
|
|
658
|
+
|| ca_mask_standin_parent_unmaskable(parents[k]) != ( pass == 0 ) ) {
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
ca_mask_standin_settle(parents[k], standins[k]);
|
|
529
662
|
}
|
|
530
|
-
ca_create_mask(parents[k]);
|
|
531
|
-
ca_xfer_all(parents[k]->mask, z->ptr, CA_XFER_PUT);
|
|
532
|
-
MEMZERO(z->ptr, boolean8_t, z->elements);
|
|
533
663
|
}
|
|
534
664
|
}
|
|
535
665
|
|
|
@@ -553,6 +683,10 @@ ca_create_mask (void *ap)
|
|
|
553
683
|
}
|
|
554
684
|
|
|
555
685
|
ca_func[ca->obj_type].create_mask(ca);
|
|
686
|
+
if ( ! ca->mask ) {
|
|
687
|
+
/* a lazy expression with no masked operand has no mask to make */
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
556
690
|
ca_set_flag(ca->mask, CA_FLAG_MASK_ARRAY); /* set array as mask array */
|
|
557
691
|
if ( ca_is_view(ca) ) {
|
|
558
692
|
if ( CAVIEW(ca)->attach ) {
|
|
@@ -561,6 +695,7 @@ ca_create_mask (void *ap)
|
|
|
561
695
|
then comes off again, since the view's sync and detach would
|
|
562
696
|
find it attached to nothing. */
|
|
563
697
|
int tag = 0;
|
|
698
|
+
/* protect: the mask comes off its view before it is freed */
|
|
564
699
|
rb_protect(ca_create_mask_attach, (VALUE) ca->mask, &tag);
|
|
565
700
|
if ( tag ) {
|
|
566
701
|
CArray *mask = ca->mask;
|
|
@@ -606,6 +741,13 @@ ca_setup_mask (void *ap, CArray *mask)
|
|
|
606
741
|
{
|
|
607
742
|
CArray *ca = (CArray *) ap;
|
|
608
743
|
|
|
744
|
+
if ( mask ) {
|
|
745
|
+
if ( ! ca_is_boolean_type(mask) ) {
|
|
746
|
+
rb_raise(rb_eCADataTypeError, "a mask is a boolean array");
|
|
747
|
+
}
|
|
748
|
+
ca_check_same_elements(ca, mask);
|
|
749
|
+
}
|
|
750
|
+
|
|
609
751
|
ca_update_mask(ca);
|
|
610
752
|
|
|
611
753
|
if ( mask ) {
|
|
@@ -685,6 +827,21 @@ ca_copy_mask_overlay_core (CArray *ca, ca_size_t elements, int n,
|
|
|
685
827
|
char *modes;
|
|
686
828
|
int i, some_has_mask = 0;
|
|
687
829
|
|
|
830
|
+
if ( elements > ca->elements ) {
|
|
831
|
+
elements = ca->elements;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/* An array source is read cell by cell over the destination's cells;
|
|
835
|
+
a scalar source's one cell applies to all of them. */
|
|
836
|
+
for (i=0; i<n; i++) {
|
|
837
|
+
cs = slist[i];
|
|
838
|
+
if ( cs && ! ca_is_scalar(cs) && cs->elements < elements ) {
|
|
839
|
+
rb_raise(rb_eArgError,
|
|
840
|
+
"mask source has %lld elements, fewer than the %lld of the destination",
|
|
841
|
+
(long long) cs->elements, (long long) elements);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
688
845
|
for (i=0; i<n; i++) {
|
|
689
846
|
if ( slist[i] && ca_has_mask(slist[i]) ) {
|
|
690
847
|
some_has_mask = 1;
|
|
@@ -703,10 +860,6 @@ ca_copy_mask_overlay_core (CArray *ca, ca_size_t elements, int n,
|
|
|
703
860
|
return;
|
|
704
861
|
}
|
|
705
862
|
|
|
706
|
-
if ( elements > ca->elements ) {
|
|
707
|
-
elements = ca->elements;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
863
|
o.list = ALLOCA_N(CArray *, n + 1);
|
|
711
864
|
o.snap = ALLOCA_N(boolean8_t *, n);
|
|
712
865
|
o.att = ALLOCA_N(CArray *, n);
|
|
@@ -900,6 +1053,10 @@ ca_unmask (void *ap, char *fill_value)
|
|
|
900
1053
|
{
|
|
901
1054
|
CArray *ca = (CArray *) ap;
|
|
902
1055
|
|
|
1056
|
+
if ( ca_is_readonly(ca) ) {
|
|
1057
|
+
ca_refuse_read_only();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
903
1060
|
ca_update_mask(ca);
|
|
904
1061
|
if ( ca->mask ) {
|
|
905
1062
|
if ( ! fill_value ) {
|
|
@@ -1258,6 +1415,72 @@ rb_ca_mask_array (VALUE self)
|
|
|
1258
1415
|
}
|
|
1259
1416
|
}
|
|
1260
1417
|
|
|
1418
|
+
/* dup / clone of a mask. The mask of a view is a view over its parent's
|
|
1419
|
+
mask, and its dup, like the dup of any view, is another view onto the
|
|
1420
|
+
same parent mask: it follows later changes and a write to it lands in
|
|
1421
|
+
the parent's mask (copy makes a mask of its own). A mask over a cast, a
|
|
1422
|
+
byte swap, a Face or a lazy expression is shown as CArrayMask, whose
|
|
1423
|
+
allocator makes an entity, so Object#dup would copy its cells; it is
|
|
1424
|
+
rebuilt here from its own view instead. The mask of an entity is an
|
|
1425
|
+
entity and is copied. */
|
|
1426
|
+
static VALUE
|
|
1427
|
+
ca_mask_view_dup (VALUE self)
|
|
1428
|
+
{
|
|
1429
|
+
volatile VALUE obj;
|
|
1430
|
+
const rb_data_type_t *type;
|
|
1431
|
+
CArray *ca, *cp;
|
|
1432
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1433
|
+
cp = (CArray *) ca_func[ca->obj_type].clone(ca);
|
|
1434
|
+
ca_keep_chain_flags(cp, ca);
|
|
1435
|
+
type = ca_typeddata[ca->obj_type];
|
|
1436
|
+
if ( type->function.dfree != ca_free ) {
|
|
1437
|
+
type = &carray_data_type; /* the copy is this object's to free */
|
|
1438
|
+
}
|
|
1439
|
+
obj = TypedData_Wrap_Struct(rb_obj_class(self), type, cp);
|
|
1440
|
+
rb_ivar_set(obj, rb_intern("masked_array"),
|
|
1441
|
+
rb_ivar_get(self, rb_intern("masked_array")));
|
|
1442
|
+
return obj;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
static VALUE
|
|
1446
|
+
rb_ca_mask_dup (VALUE self)
|
|
1447
|
+
{
|
|
1448
|
+
CArray *ca;
|
|
1449
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1450
|
+
if ( ! ca_is_view(ca) ) {
|
|
1451
|
+
return rb_call_super(0, NULL);
|
|
1452
|
+
}
|
|
1453
|
+
return ca_mask_view_dup(self);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
static VALUE
|
|
1457
|
+
rb_ca_mask_clone (int argc, VALUE *argv, VALUE self)
|
|
1458
|
+
{
|
|
1459
|
+
VALUE opts = Qnil, vfreeze = Qnil;
|
|
1460
|
+
volatile VALUE obj;
|
|
1461
|
+
CArray *ca;
|
|
1462
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1463
|
+
if ( ! ca_is_view(ca) ) {
|
|
1464
|
+
return rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
|
|
1465
|
+
}
|
|
1466
|
+
rb_scan_args(argc, argv, "0:", &opts);
|
|
1467
|
+
if ( ! NIL_P(opts) ) {
|
|
1468
|
+
/* rb_get_kwargs refuses any key but freeze:, as Kernel#clone does. */
|
|
1469
|
+
ID kw[1];
|
|
1470
|
+
VALUE val[1];
|
|
1471
|
+
kw[0] = rb_intern("freeze");
|
|
1472
|
+
rb_get_kwargs(opts, kw, 0, 1, val);
|
|
1473
|
+
if ( val[0] != Qundef ) {
|
|
1474
|
+
vfreeze = val[0];
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
obj = ca_mask_view_dup(self);
|
|
1478
|
+
if ( RTEST(vfreeze) || ( NIL_P(vfreeze) && OBJ_FROZEN(self) ) ) {
|
|
1479
|
+
rb_obj_freeze(obj);
|
|
1480
|
+
}
|
|
1481
|
+
return obj;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1261
1484
|
/* @overload mask= (new_mask)
|
|
1262
1485
|
|
|
1263
1486
|
(Mask, Modification)
|
|
@@ -1491,14 +1714,9 @@ rb_ca_mask_fill (VALUE self, VALUE fval)
|
|
|
1491
1714
|
return rb_ca_unmask_method(1, &fval, self);
|
|
1492
1715
|
}
|
|
1493
1716
|
|
|
1494
|
-
/*
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
Returns new unmasked array.
|
|
1498
|
-
If the optional argument <code>fill_value</code> is given,
|
|
1499
|
-
the masked elements are filled by <code>fill_value</code>.
|
|
1500
|
-
The returned array doesn't have the mask array.
|
|
1501
|
-
*/
|
|
1717
|
+
/* A copy without the mask: with a fill value, the masked cells hold it.
|
|
1718
|
+
Behind rb_ca_unmask_copy / rb_ca_mask_fill_copy (C only; the Ruby
|
|
1719
|
+
surface is strip_mask). */
|
|
1502
1720
|
|
|
1503
1721
|
static VALUE
|
|
1504
1722
|
rb_ca_unmask_copy_method (int argc, VALUE *argv, VALUE self)
|
|
@@ -2202,7 +2420,7 @@ rb_ca_inherit_mask_replace_ruby (int argc, VALUE *argv, VALUE self)
|
|
|
2202
2420
|
void
|
|
2203
2421
|
Init_carray_mask (void)
|
|
2204
2422
|
{
|
|
2205
|
-
rb_define_private_method(rb_cCArray, "
|
|
2423
|
+
rb_define_private_method(rb_cCArray, "add_mask", rb_ca_create_mask, 0);
|
|
2206
2424
|
/*
|
|
2207
2425
|
rb_define_private_method(rb_cCArray, "__update_mask__", rb_ca_update_mask, 0);
|
|
2208
2426
|
*/
|
|
@@ -2213,6 +2431,8 @@ Init_carray_mask (void)
|
|
|
2213
2431
|
|
|
2214
2432
|
rb_define_method(rb_cCArray, "value", rb_ca_value_array, 0);
|
|
2215
2433
|
rb_define_method(rb_cCArray, "mask", rb_ca_mask_array, 0);
|
|
2434
|
+
rb_define_method(rb_cCArrayMask, "dup", rb_ca_mask_dup, 0);
|
|
2435
|
+
rb_define_method(rb_cCArrayMask, "clone", rb_ca_mask_clone, -1);
|
|
2216
2436
|
rb_define_method(rb_cCArray, "mask=", rb_ca_set_mask, 1);
|
|
2217
2437
|
rb_define_method(rb_cCArray, "is_masked", rb_ca_is_masked, 0);
|
|
2218
2438
|
rb_define_method(rb_cCArray, "is_not_masked", rb_ca_is_not_masked, 0);
|