carray 3.0.3 → 3.0.5
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 +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- 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 +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- 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 +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -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 +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -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 +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -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 +105 -17
- 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 +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- 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 +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -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 +42 -6
- 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 +217 -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 +61 -37
- 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 +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- 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_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- 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/ca_obj_byte_swap.c
CHANGED
|
@@ -193,10 +193,11 @@ VALUE rb_cCAByteSwap;
|
|
|
193
193
|
int
|
|
194
194
|
ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
|
|
195
195
|
{
|
|
196
|
-
|
|
196
|
+
CA_CHECK_DATA_TYPE_GIVEN(parent->data_type);
|
|
197
197
|
|
|
198
198
|
if ( parent->data_type == CA_OBJECT ) {
|
|
199
|
-
rb_raise(rb_eCADataTypeError, "object array can't be byte-swapped"
|
|
199
|
+
rb_raise(rb_eCADataTypeError, "%s: an object array can't be byte-swapped",
|
|
200
|
+
ca_calling_method_name());
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
@@ -223,9 +224,6 @@ ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
|
|
|
223
224
|
ca->nosync = 0;
|
|
224
225
|
ca->data_class = data_class; /* Qnil if parent has no data_class */
|
|
225
226
|
|
|
226
|
-
if ( ca_has_mask(parent) ) {
|
|
227
|
-
ca_create_mask(ca);
|
|
228
|
-
}
|
|
229
227
|
if ( ca_is_scalar(parent) ) {
|
|
230
228
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
231
229
|
}
|
|
@@ -240,6 +238,7 @@ ca_byte_swap_new (CArray *parent, VALUE data_class)
|
|
|
240
238
|
ca_byte_swap_setup(NULL, parent, data_class);
|
|
241
239
|
ca = (CAByteSwap *) ca_array_alloc(CA_OBJ_BYTE_SWAP, parent->ndim);
|
|
242
240
|
ca_byte_swap_setup(ca, parent, data_class);
|
|
241
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
243
242
|
return ca;
|
|
244
243
|
}
|
|
245
244
|
|
|
@@ -464,7 +463,7 @@ ca_byte_swap_func_allocate (void *ap)
|
|
|
464
463
|
{
|
|
465
464
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
466
465
|
ca_attach(ca->parent);
|
|
467
|
-
ca->ptr =
|
|
466
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
468
467
|
}
|
|
469
468
|
|
|
470
469
|
static void
|
|
@@ -472,7 +471,7 @@ ca_byte_swap_func_attach (void *ap)
|
|
|
472
471
|
{
|
|
473
472
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
474
473
|
ca_attach(ca->parent);
|
|
475
|
-
ca->ptr =
|
|
474
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
476
475
|
memcpy(ca->ptr, ca->parent->ptr, ca_length(ca));
|
|
477
476
|
ca_byte_swap_apply(ca, ca->ptr);
|
|
478
477
|
}
|
|
@@ -664,6 +663,7 @@ rb_ca_byte_swap_initialize_copy (VALUE self, VALUE other)
|
|
|
664
663
|
ca_array_pool_alloc(ca, CA_OBJ_BYTE_SWAP, cs->parent->ndim);
|
|
665
664
|
}
|
|
666
665
|
ca_byte_swap_setup(ca, cs->parent, cs->data_class);
|
|
666
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
667
667
|
return self;
|
|
668
668
|
}
|
|
669
669
|
|
data/ext/ca_obj_const_string.c
CHANGED
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
--------------------------------------------------------------------------- */
|
|
32
32
|
|
|
33
33
|
#include "carray.h"
|
|
34
|
+
#include "ruby/util.h"
|
|
34
35
|
#include "carray_internal.h"
|
|
35
36
|
#include "ca_obj_face.h"
|
|
36
37
|
#include <ruby/encoding.h>
|
|
@@ -122,6 +123,12 @@ ca_const_string_setup (CAConstString *ca, CArray *parent, VALUE buffer, int enco
|
|
|
122
123
|
"(parent.data_type must be CA_FIXLEN with bytes == 16)");
|
|
123
124
|
}
|
|
124
125
|
|
|
126
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
127
|
+
run them before it allocates. */
|
|
128
|
+
if ( ca == NULL ) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
125
132
|
ca->obj_type = CA_OBJ_CONST_STRING;
|
|
126
133
|
/* FIXLEN surface auto-gates mkkernel numeric dispatch. */
|
|
127
134
|
ca->data_type = CA_FIXLEN;
|
|
@@ -143,9 +150,6 @@ ca_const_string_setup (CAConstString *ca, CArray *parent, VALUE buffer, int enco
|
|
|
143
150
|
ca->buffer = buffer;
|
|
144
151
|
ca->encoding_id = encoding_id;
|
|
145
152
|
|
|
146
|
-
if ( ca_has_mask(parent) ) {
|
|
147
|
-
ca_create_mask((CArray *) ca);
|
|
148
|
-
}
|
|
149
153
|
|
|
150
154
|
if ( ca_is_scalar(parent) ) {
|
|
151
155
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
@@ -160,8 +164,11 @@ ca_const_string_setup (CAConstString *ca, CArray *parent, VALUE buffer, int enco
|
|
|
160
164
|
CAConstString *
|
|
161
165
|
ca_const_string_new (CArray *parent, VALUE buffer, int encoding_id)
|
|
162
166
|
{
|
|
163
|
-
CAConstString *ca
|
|
167
|
+
CAConstString *ca;
|
|
168
|
+
ca_const_string_setup(NULL, parent, buffer, encoding_id);
|
|
169
|
+
ca = (CAConstString *) ca_array_alloc(CA_OBJ_CONST_STRING, parent->ndim);
|
|
164
170
|
ca_const_string_setup(ca, parent, buffer, encoding_id);
|
|
171
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
165
172
|
return ca;
|
|
166
173
|
}
|
|
167
174
|
|
|
@@ -574,7 +581,9 @@ rb_ca_const_string_copy (VALUE self)
|
|
|
574
581
|
|
|
575
582
|
ca_detach((CArray *) ca);
|
|
576
583
|
|
|
577
|
-
|
|
584
|
+
vout = rb_ca_const_string_wrap(vout, rb_str_freeze(newbuf), ca->encoding_id);
|
|
585
|
+
rb_ca_inherit_attr(vout, self);
|
|
586
|
+
return vout;
|
|
578
587
|
}
|
|
579
588
|
|
|
580
589
|
/* to_ca descends to the same compacting copy. The result is detached
|
|
@@ -649,6 +658,7 @@ ca_const_string_scan_begin_pair (VALUE va, ca_const_string_scan_t *a,
|
|
|
649
658
|
ca_const_string_scan_begin(va, a);
|
|
650
659
|
x.self = vb;
|
|
651
660
|
x.s = b;
|
|
661
|
+
/* protect: ends the first scan, which is not an array */
|
|
652
662
|
rb_protect(ca_const_string_scan_begin_body, (VALUE) &x, &tag);
|
|
653
663
|
if ( tag ) {
|
|
654
664
|
ca_const_string_scan_end(a);
|
|
@@ -827,19 +837,31 @@ rb_ca_const_string_eq (VALUE self, VALUE other)
|
|
|
827
837
|
ca_const_string_scan_end(&b);
|
|
828
838
|
return vout;
|
|
829
839
|
}
|
|
840
|
+
/* Another array is compared cell by cell as Strings, where a CAString
|
|
841
|
+
reconciles it (an object array of Strings, a fixlen or a CAString). */
|
|
842
|
+
if ( rb_obj_is_carray(other) ) {
|
|
843
|
+
return rb_funcall(rb_ca_const_string_to_string(self), rb_intern("eq"), 1,
|
|
844
|
+
other);
|
|
845
|
+
}
|
|
830
846
|
return ca_const_string_predicate(self, other, CA_TEXT_EQ);
|
|
831
847
|
}
|
|
832
848
|
|
|
833
|
-
/* CAConstString#count(value): number of (non-masked) elements byte-equal to
|
|
849
|
+
/* CAConstString#count(value): number of (non-masked) elements byte-equal to
|
|
850
|
+
value. With no value, the number of non-masked elements, as CArray#count
|
|
851
|
+
answers. */
|
|
834
852
|
static VALUE
|
|
835
|
-
rb_ca_const_string_count (VALUE
|
|
853
|
+
rb_ca_const_string_count (int argc, VALUE *argv, VALUE self)
|
|
836
854
|
{
|
|
837
855
|
ca_const_string_scan_t s;
|
|
838
856
|
const char *qp, *p;
|
|
839
857
|
long qlen;
|
|
840
858
|
int64_t len;
|
|
841
859
|
ca_size_t i, c = 0;
|
|
860
|
+
VALUE query;
|
|
842
861
|
|
|
862
|
+
if ( rb_scan_args(argc, argv, "01", &query) == 0 ) {
|
|
863
|
+
return rb_funcall(self, rb_intern("count_not_masked"), 0);
|
|
864
|
+
}
|
|
843
865
|
if ( TYPE(query) != T_STRING ) {
|
|
844
866
|
query = rb_obj_as_string(query);
|
|
845
867
|
}
|
|
@@ -894,13 +916,12 @@ rb_ca_const_string_search (VALUE self, VALUE query)
|
|
|
894
916
|
byte-for-byte faithful to `to_object.sort` with no collation
|
|
895
917
|
loss. */
|
|
896
918
|
|
|
897
|
-
/*
|
|
898
|
-
|
|
899
|
-
static ca_const_string_scan_t *ca_const_string_sort_ctx;
|
|
900
|
-
|
|
919
|
+
/* The scan is passed to the comparator, not held in a static: Ractors
|
|
920
|
+
sort at the same time. */
|
|
901
921
|
static int
|
|
902
|
-
ca_const_string_byte_cmp (const void *a, const void *b)
|
|
922
|
+
ca_const_string_byte_cmp (const void *a, const void *b, void *ctx)
|
|
903
923
|
{
|
|
924
|
+
ca_const_string_scan_t *scan = (ca_const_string_scan_t *) ctx;
|
|
904
925
|
ca_size_t ia = *(const ca_size_t *) a;
|
|
905
926
|
ca_size_t ib = *(const ca_size_t *) b;
|
|
906
927
|
/* sort raises on masked input, so record() always sets these here; the
|
|
@@ -908,13 +929,21 @@ ca_const_string_byte_cmp (const void *a, const void *b)
|
|
|
908
929
|
const char *pa = NULL, *pb = NULL;
|
|
909
930
|
int64_t la = 0, lb = 0;
|
|
910
931
|
int c;
|
|
911
|
-
ca_const_string_record(
|
|
912
|
-
ca_const_string_record(
|
|
932
|
+
ca_const_string_record(scan, ia, &pa, &la);
|
|
933
|
+
ca_const_string_record(scan, ib, &pb, &lb);
|
|
913
934
|
c = memcmp(pa, pb, (size_t) (la < lb ? la : lb));
|
|
914
935
|
if ( c != 0 ) return c;
|
|
915
936
|
return (la > lb) - (la < lb);
|
|
916
937
|
}
|
|
917
938
|
|
|
939
|
+
static int
|
|
940
|
+
ca_const_string_index_cmp (const void *a, const void *b)
|
|
941
|
+
{
|
|
942
|
+
ca_size_t ia = *(const ca_size_t *) a;
|
|
943
|
+
ca_size_t ib = *(const ca_size_t *) b;
|
|
944
|
+
return (ia > ib) - (ia < ib);
|
|
945
|
+
}
|
|
946
|
+
|
|
918
947
|
/* compute the ascending sort permutation; raises on masked input (matches
|
|
919
948
|
base CArray#sort). caller xfree()s the returned index array. */
|
|
920
949
|
static ca_size_t *
|
|
@@ -928,9 +957,19 @@ ca_const_string_sort_perm (ca_const_string_scan_t *s)
|
|
|
928
957
|
}
|
|
929
958
|
idx = ALLOC_N(ca_size_t, s->n);
|
|
930
959
|
for ( i = 0; i < s->n; i++ ) idx[i] = i;
|
|
931
|
-
|
|
932
|
-
qsort
|
|
933
|
-
|
|
960
|
+
ruby_qsort(idx, (size_t) s->n, sizeof(ca_size_t), ca_const_string_byte_cmp, s);
|
|
961
|
+
/* qsort is not stable. Equal strings keep their order, as CArray's own
|
|
962
|
+
sort does, so each run of them is put back in position order. Breaking
|
|
963
|
+
the tie inside the comparator instead doubles the sort on columns with
|
|
964
|
+
many repeats. */
|
|
965
|
+
for ( i = 0; i < s->n; ) {
|
|
966
|
+
ca_size_t j = i + 1;
|
|
967
|
+
while ( j < s->n && ca_const_string_byte_cmp(&idx[i], &idx[j], s) == 0 ) j++;
|
|
968
|
+
if ( j - i > 1 ) {
|
|
969
|
+
qsort(idx + i, (size_t) (j - i), sizeof(ca_size_t), ca_const_string_index_cmp);
|
|
970
|
+
}
|
|
971
|
+
i = j;
|
|
972
|
+
}
|
|
934
973
|
return idx;
|
|
935
974
|
}
|
|
936
975
|
|
|
@@ -1005,6 +1044,128 @@ ca_const_string_extremum (VALUE self, int want_max)
|
|
|
1005
1044
|
static VALUE rb_ca_const_string_min (VALUE self) { return ca_const_string_extremum(self, 0); }
|
|
1006
1045
|
static VALUE rb_ca_const_string_max (VALUE self) { return ca_const_string_extremum(self, 1); }
|
|
1007
1046
|
|
|
1047
|
+
/* ------------------------------------------------------------------- */
|
|
1048
|
+
/* Native factorize: categorize's discovery pass, read from the bytes. The
|
|
1049
|
+
storage cells are byte ranges, so the fixlen lane of
|
|
1050
|
+
CArray#__factorize_appearance__ would tell ranges apart, not strings. A
|
|
1051
|
+
String is made per distinct value only, after the scan's window closes. */
|
|
1052
|
+
|
|
1053
|
+
static uint64_t
|
|
1054
|
+
ca_const_string_hash_bytes (const char *p, int64_t len)
|
|
1055
|
+
{
|
|
1056
|
+
uint64_t h = 1469598103934665603ULL; /* FNV-1a */
|
|
1057
|
+
int64_t i;
|
|
1058
|
+
for ( i = 0; i < len; i++ ) {
|
|
1059
|
+
h ^= (unsigned char) p[i];
|
|
1060
|
+
h *= 1099511628211ULL;
|
|
1061
|
+
}
|
|
1062
|
+
return h;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/* CAConstString#__factorize_appearance__ -> [codes, levels], as the CArray
|
|
1066
|
+
method answers: codes are the narrowest unsigned type holding the k codes
|
|
1067
|
+
and the type-max sentinel, which masked cells store; levels are the k
|
|
1068
|
+
distinct Strings in first-appearance order. */
|
|
1069
|
+
static VALUE
|
|
1070
|
+
rb_ca_const_string_factorize_appearance (VALUE self)
|
|
1071
|
+
{
|
|
1072
|
+
ca_const_string_scan_t s;
|
|
1073
|
+
CAConstString *ca;
|
|
1074
|
+
volatile VALUE vcodes, levels;
|
|
1075
|
+
CArray *co;
|
|
1076
|
+
uint32_t *codes, *slot;
|
|
1077
|
+
int64_t *lev_start, *lev_len;
|
|
1078
|
+
size_t cap = 16, mask_bits;
|
|
1079
|
+
ca_size_t n, i, k = 0;
|
|
1080
|
+
int8_t code_dt;
|
|
1081
|
+
VALUE slot_holder = 0, start_holder = 0, len_holder = 0;
|
|
1082
|
+
|
|
1083
|
+
TypedData_Get_Struct(self, CAConstString, &catext_data_type, ca);
|
|
1084
|
+
n = ca->elements;
|
|
1085
|
+
if ( (uint64_t) n >= 0xFFFFFFFFULL ) {
|
|
1086
|
+
rb_raise(rb_eArgError, "categorize: too many elements for uint32 codes");
|
|
1087
|
+
}
|
|
1088
|
+
while ( cap < (size_t) n * 2 ) {
|
|
1089
|
+
cap <<= 1;
|
|
1090
|
+
}
|
|
1091
|
+
mask_bits = cap - 1;
|
|
1092
|
+
/* Everything the scan writes is allocated before its window opens, and
|
|
1093
|
+
held by the collector: opening the window reads the offsets, which
|
|
1094
|
+
can raise for a parent that answers in Ruby. */
|
|
1095
|
+
vcodes = rb_carray_new(CA_UINT32, ca->ndim, ca->dim, 0, NULL);
|
|
1096
|
+
TypedData_Get_Struct(vcodes, CArray, &carray_data_type, co);
|
|
1097
|
+
codes = (uint32_t *) co->ptr;
|
|
1098
|
+
slot = ALLOCV_N(uint32_t, slot_holder, cap); /* code + 1; 0 is empty */
|
|
1099
|
+
MEMZERO(slot, uint32_t, cap);
|
|
1100
|
+
lev_start = ALLOCV_N(int64_t, start_holder, n > 0 ? n : 1);
|
|
1101
|
+
lev_len = ALLOCV_N(int64_t, len_holder, n > 0 ? n : 1);
|
|
1102
|
+
|
|
1103
|
+
ca_const_string_scan_begin(self, &s);
|
|
1104
|
+
for ( i = 0; i < s.n; i++ ) {
|
|
1105
|
+
const char *p;
|
|
1106
|
+
int64_t len;
|
|
1107
|
+
size_t j;
|
|
1108
|
+
if ( ! ca_const_string_record(&s, i, &p, &len) ) {
|
|
1109
|
+
codes[i] = 0xFFFFFFFFu;
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
j = (size_t) ca_const_string_hash_bytes(p, len) & mask_bits;
|
|
1113
|
+
for (;;) {
|
|
1114
|
+
uint32_t c = slot[j];
|
|
1115
|
+
if ( c == 0 ) {
|
|
1116
|
+
lev_start[k] = (int64_t) (p - s.buf);
|
|
1117
|
+
lev_len[k] = len;
|
|
1118
|
+
slot[j] = (uint32_t) (k + 1);
|
|
1119
|
+
codes[i] = (uint32_t) k;
|
|
1120
|
+
k++;
|
|
1121
|
+
break;
|
|
1122
|
+
}
|
|
1123
|
+
if ( lev_len[c - 1] == len && memcmp(s.buf + lev_start[c - 1], p, (size_t) len) == 0 ) {
|
|
1124
|
+
codes[i] = c - 1;
|
|
1125
|
+
break;
|
|
1126
|
+
}
|
|
1127
|
+
j = (j + 1) & mask_bits;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
ca_const_string_scan_end(&s);
|
|
1131
|
+
ALLOCV_END(slot_holder);
|
|
1132
|
+
|
|
1133
|
+
/* The buffer is the column's frozen String, alive past the window. */
|
|
1134
|
+
levels = rb_ary_new_capa(k);
|
|
1135
|
+
{
|
|
1136
|
+
const char *buf = RSTRING_PTR(ca->buffer);
|
|
1137
|
+
rb_encoding *enc = rb_enc_from_index(ca->encoding_id);
|
|
1138
|
+
for ( i = 0; i < k; i++ ) {
|
|
1139
|
+
rb_ary_push(levels, rb_enc_str_new(buf + lev_start[i], lev_len[i], enc));
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
ALLOCV_END(start_holder);
|
|
1143
|
+
ALLOCV_END(len_holder);
|
|
1144
|
+
|
|
1145
|
+
if ( k <= 0xFF ) { code_dt = CA_UINT8; }
|
|
1146
|
+
else if ( k <= 0xFFFF ) { code_dt = CA_UINT16; }
|
|
1147
|
+
else { code_dt = CA_UINT32; }
|
|
1148
|
+
if ( code_dt != CA_UINT32 ) {
|
|
1149
|
+
VALUE vnarrow = rb_carray_new(code_dt, ca->ndim, ca->dim, 0, NULL);
|
|
1150
|
+
CArray *cn;
|
|
1151
|
+
TypedData_Get_Struct(vnarrow, CArray, &carray_data_type, cn);
|
|
1152
|
+
if ( code_dt == CA_UINT8 ) {
|
|
1153
|
+
uint8_t *cp = (uint8_t *) cn->ptr;
|
|
1154
|
+
for ( i = 0; i < n; i++ ) {
|
|
1155
|
+
cp[i] = codes[i] == 0xFFFFFFFFu ? (uint8_t) 0xFF : (uint8_t) codes[i];
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
else {
|
|
1159
|
+
uint16_t *cp = (uint16_t *) cn->ptr;
|
|
1160
|
+
for ( i = 0; i < n; i++ ) {
|
|
1161
|
+
cp[i] = codes[i] == 0xFFFFFFFFu ? (uint16_t) 0xFFFF : (uint16_t) codes[i];
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
vcodes = vnarrow;
|
|
1165
|
+
}
|
|
1166
|
+
return rb_ary_new3(2, vcodes, levels);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1008
1169
|
/* ------------------------------------------------------------------- */
|
|
1009
1170
|
|
|
1010
1171
|
static VALUE
|
|
@@ -1028,6 +1189,7 @@ rb_ca_const_string_initialize_copy (VALUE self, VALUE other)
|
|
|
1028
1189
|
ca_array_pool_alloc(ca, CA_OBJ_CONST_STRING, cs->parent->ndim);
|
|
1029
1190
|
}
|
|
1030
1191
|
ca_const_string_setup(ca, cs->parent, cs->buffer, cs->encoding_id);
|
|
1192
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
1031
1193
|
return self;
|
|
1032
1194
|
}
|
|
1033
1195
|
|
|
@@ -1066,7 +1228,7 @@ Init_ca_obj_const_string (void)
|
|
|
1066
1228
|
/* native byte ops (§3.7) */
|
|
1067
1229
|
rb_define_method(rb_cCAConstString, "byte_length", rb_ca_const_string_byte_length, 0);
|
|
1068
1230
|
rb_define_method(rb_cCAConstString, "eq", rb_ca_const_string_eq, 1);
|
|
1069
|
-
rb_define_method(rb_cCAConstString, "count", rb_ca_const_string_count, 1);
|
|
1231
|
+
rb_define_method(rb_cCAConstString, "count", rb_ca_const_string_count, -1);
|
|
1070
1232
|
rb_define_method(rb_cCAConstString, "start_with?", rb_ca_const_string_start_with, 1);
|
|
1071
1233
|
rb_define_method(rb_cCAConstString, "end_with?", rb_ca_const_string_end_with, 1);
|
|
1072
1234
|
rb_define_method(rb_cCAConstString, "include?", rb_ca_const_string_include, 1);
|
|
@@ -1080,10 +1242,14 @@ Init_ca_obj_const_string (void)
|
|
|
1080
1242
|
/* Native flat sort permutation / min / max (§3.7), byte-memcmp
|
|
1081
1243
|
comparator. The public ordering surface is built on these in
|
|
1082
1244
|
lib/carray/const_string.rb; see the comment above their definitions. */
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1245
|
+
rb_define_private_method(rb_cCAConstString, "sort_addr_by_bytes",
|
|
1246
|
+
rb_ca_const_string_sort_index, 0);
|
|
1247
|
+
rb_define_private_method(rb_cCAConstString, "min_string_by_bytes",
|
|
1248
|
+
rb_ca_const_string_min, 0);
|
|
1249
|
+
rb_define_private_method(rb_cCAConstString, "__factorize_appearance__",
|
|
1250
|
+
rb_ca_const_string_factorize_appearance, 0);
|
|
1251
|
+
rb_define_private_method(rb_cCAConstString, "max_string_by_bytes",
|
|
1252
|
+
rb_ca_const_string_max, 0);
|
|
1087
1253
|
|
|
1088
1254
|
/* Y-pilot: Face-local C-level fast path for per-cell scalar fetch. */
|
|
1089
1255
|
ca_face_register_storage_to_element(CA_OBJ_CONST_STRING, rb_ca_const_string_storage_to_element);
|