carray 3.0.1 → 3.0.3
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 +824 -0
- data/README.md +5 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +258 -4
- data/ext/ca_axis_group.c +368 -184
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +90 -41
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +960 -245
- data/ext/ca_kernel_iterator.h +352 -181
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +194 -42
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +5 -4
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +180 -50
- data/ext/ca_obj_face.c +428 -62
- data/ext/ca_obj_face.h +107 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +39 -26
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +235 -55
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +551 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +88 -75
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -123
- data/ext/ca_obj_stride.c +267 -35
- data/ext/ca_obj_string.c +25 -22
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +157 -29
- data/ext/ca_op_ipower.c +25 -13
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +385 -198
- data/ext/ca_sweep_engine.h +31 -23
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +90 -28
- data/ext/carray_access.c +487 -231
- data/ext/carray_address_basis.c +731 -0
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +49 -17
- data/ext/carray_call_cfunc.c +667 -511
- data/ext/carray_cast.c +1556 -247
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +84 -38
- data/ext/carray_core.c +591 -119
- data/ext/carray_count.c +148 -96
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +604 -291
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +400 -1
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +88 -66
- data/ext/carray_mask.c +705 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +263 -63
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1093 -363
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +582 -204
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +183 -70
- data/ext/carray_sort.c +235 -240
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +103 -118
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1349 -851
- data/ext/ruby_carray.c +17 -2
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +18 -0
- data/lib/carray/axis_group.rb +245 -20
- data/lib/carray/basics.rb +95 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +200 -54
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +244 -59
- data/lib/carray/categorical_iterator.rb +391 -757
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +177 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +590 -76
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +205 -35
- data/lib/carray/frame/group.rb +199 -40
- data/lib/carray/frame/io.rb +452 -60
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +54 -19
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +726 -56
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +71 -20
- data/lib/carray/iterator.rb +157 -2
- data/lib/carray/lazy.rb +54 -67
- data/lib/carray/mask_gap_fill.rb +66 -50
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +130 -6
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +235 -21
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +91 -0
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +52 -3
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +109 -40
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +9 -4
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +535 -105
- data/lib/carray/window_iterator.rb +259 -82
- data/lib/carray.rb +4 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +11 -4
- data/yard-stubs/carray_access.rb +6 -5
- data/yard-stubs/carray_broadcast.rb +2 -2
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -83
- data/yard-stubs/carray_count.rb +16 -2
- data/yard-stubs/carray_lazy.rb +210 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +1499 -4
- data/yard-stubs/carray_median_percentile.rb +26 -8
- data/yard-stubs/carray_order.rb +43 -82
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +11 -8
- data/yard-stubs/carray_sort.rb +50 -8
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -25837
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14593
- data/ext/carray_kernels_reduce_extreme.c +0 -16948
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32138
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/ca_obj_const_string.c
CHANGED
|
@@ -26,11 +26,12 @@
|
|
|
26
26
|
bytes once in logical order, without offset-sharing dedup.
|
|
27
27
|
|
|
28
28
|
Sibling of ca_obj_record.c (Face + VALUE tail + custom dmark) and
|
|
29
|
-
ca_obj_time.c (int64 Face +
|
|
29
|
+
ca_obj_time.c (int64 Face + storage_to_element fast path).
|
|
30
30
|
|
|
31
31
|
--------------------------------------------------------------------------- */
|
|
32
32
|
|
|
33
33
|
#include "carray.h"
|
|
34
|
+
#include "carray_internal.h"
|
|
34
35
|
#include "ca_obj_face.h"
|
|
35
36
|
#include <ruby/encoding.h>
|
|
36
37
|
|
|
@@ -38,10 +39,10 @@
|
|
|
38
39
|
typedef struct {
|
|
39
40
|
/* === CAView prefix === */
|
|
40
41
|
int16_t obj_type;
|
|
41
|
-
int8_t data_type; /* CA_FIXLEN surface (numeric gate); storage is
|
|
42
|
+
int8_t data_type; /* CA_FIXLEN surface (numeric gate); storage is fixlen-16 */
|
|
42
43
|
int8_t ndim;
|
|
43
44
|
int32_t flags; /* CA_FLAG_IS_FACE set */
|
|
44
|
-
ca_size_t bytes; /* sizeof(int64_t) =
|
|
45
|
+
ca_size_t bytes; /* 2 * sizeof(int64_t) = 16 (one (start,end) pair per element) */
|
|
45
46
|
ca_size_t elements;
|
|
46
47
|
ca_size_t *dim;
|
|
47
48
|
char *ptr;
|
|
@@ -200,18 +201,6 @@ ca_const_string_func_allocate (void *ap)
|
|
|
200
201
|
ca->ptr = ca->parent->ptr;
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
static void
|
|
204
|
-
ca_const_string_func_create_mask (void *ap)
|
|
205
|
-
{
|
|
206
|
-
CAConstString *ca = (CAConstString *) ap;
|
|
207
|
-
ca_update_mask(ca->parent);
|
|
208
|
-
if ( ! ca->parent->mask ) {
|
|
209
|
-
ca_create_mask(ca->parent);
|
|
210
|
-
}
|
|
211
|
-
ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
|
|
212
|
-
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
204
|
ca_operation_function_t ca_const_string_func = {
|
|
216
205
|
-1, /* CA_OBJ_CONST_STRING — filled by ca_install_obj_type */
|
|
217
206
|
CA_VIEW_ARRAY,
|
|
@@ -222,7 +211,7 @@ ca_operation_function_t ca_const_string_func = {
|
|
|
222
211
|
ca_face_sync,
|
|
223
212
|
ca_face_detach,
|
|
224
213
|
ca_face_fill_data,
|
|
225
|
-
|
|
214
|
+
ca_view_func_create_mask,
|
|
226
215
|
ca_face_xfer_index,
|
|
227
216
|
ca_face_xfer_addrs,
|
|
228
217
|
NULL, /* fold_stride: identity Face is not foldable */
|
|
@@ -255,12 +244,12 @@ ca_const_string_decode (CAConstString *ca, int64_t start, int64_t end)
|
|
|
255
244
|
return rb_str_freeze(s);
|
|
256
245
|
}
|
|
257
246
|
|
|
258
|
-
/*
|
|
247
|
+
/* storage_to_element in C (= skip rb_funcall on the per-cell fetch hot
|
|
259
248
|
path). Since the Face surface is CA_FIXLEN (16 bytes), fetch delivers a
|
|
260
249
|
16-byte raw String = the (start,end) int64 pair. Decode the buffer slice
|
|
261
250
|
→ frozen Ruby String (plain frozen String, no Scalar wrapper). */
|
|
262
251
|
static VALUE
|
|
263
|
-
|
|
252
|
+
rb_ca_const_string_storage_to_element (VALUE self, VALUE raw)
|
|
264
253
|
{
|
|
265
254
|
CAConstString *ca;
|
|
266
255
|
int64_t pair[2];
|
|
@@ -269,7 +258,7 @@ rb_ca_const_string_storage_to_scalar (VALUE self, VALUE raw)
|
|
|
269
258
|
|
|
270
259
|
if ( TYPE(raw) != T_STRING || RSTRING_LEN(raw) != (long) sizeof(pair) ) {
|
|
271
260
|
rb_raise(rb_eArgError,
|
|
272
|
-
"CAConstString#
|
|
261
|
+
"CAConstString#storage_to_element: expected a %lu-byte (start,end) cell",
|
|
273
262
|
(unsigned long) sizeof(pair));
|
|
274
263
|
}
|
|
275
264
|
memcpy(pair, RSTRING_PTR(raw), sizeof(pair));
|
|
@@ -299,6 +288,54 @@ rb_ca_const_string_wrap (VALUE parent_val, VALUE buffer, int encoding_id)
|
|
|
299
288
|
rb_raise(rb_eTypeError, "CAConstString.wrap: buffer: must be a String");
|
|
300
289
|
}
|
|
301
290
|
|
|
291
|
+
/* This is the one door through which already-built offsets enter, so it
|
|
292
|
+
validates rather than assumes. Everything downstream -- the per-cell
|
|
293
|
+
decode, the native byte scans, the sort comparator -- reads `buf + start`
|
|
294
|
+
for `end - start` bytes on the strength of these pairs; an out-of-range
|
|
295
|
+
one is an out-of-bounds read of the heap, not a wrong answer. Refuse it
|
|
296
|
+
here, while the input is still in the caller's hands, rather than letting
|
|
297
|
+
it surface as an IndexError from a decode or as a crash from a scan.
|
|
298
|
+
|
|
299
|
+
A masked cell is exempt: its bytes may be anything at all, that being the
|
|
300
|
+
CArray mask contract, and no reader dereferences them (the scan skips on
|
|
301
|
+
the mask before touching an offset; `.value`, the explicit strip, raises
|
|
302
|
+
from the decode). */
|
|
303
|
+
{
|
|
304
|
+
ca_size_t i, n;
|
|
305
|
+
int64_t *pair;
|
|
306
|
+
boolean8_t *m;
|
|
307
|
+
|
|
308
|
+
ca_update_mask(parent);
|
|
309
|
+
ca_attach(parent); /* window: detached before its one raise */
|
|
310
|
+
n = parent->elements;
|
|
311
|
+
pair = (int64_t *) parent->ptr;
|
|
312
|
+
m = parent->mask ? (boolean8_t *) parent->mask->ptr : NULL;
|
|
313
|
+
for ( i = 0; i < n; i++ ) {
|
|
314
|
+
int64_t start = pair[2 * i], end = pair[2 * i + 1];
|
|
315
|
+
if ( m && m[i] ) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if ( start < 0 || end < start || end > (int64_t) RSTRING_LEN(buffer) ) {
|
|
319
|
+
ca_detach(parent);
|
|
320
|
+
rb_raise(rb_eArgError,
|
|
321
|
+
"CAConstString.wrap: element %lld has range [%lld,%lld), "
|
|
322
|
+
"outside the %ld-byte buffer",
|
|
323
|
+
(long long) i, (long long) start, (long long) end,
|
|
324
|
+
(long) RSTRING_LEN(buffer));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
ca_detach(parent);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* Take ownership of the offsets, the way CACategorical.from_codes takes
|
|
331
|
+
ownership of its codes. Without this the Face is read-only but its
|
|
332
|
+
storage is not, so `cs.parent[i] = <anything>` walks straight past the
|
|
333
|
+
check above and back into an out-of-bounds read. The flag rather than
|
|
334
|
+
#freeze, for the reason from_codes gives: freeze would propagate through
|
|
335
|
+
views and Faces. A caller that wants to keep a mutable entity of its own
|
|
336
|
+
passes `.copy`. */
|
|
337
|
+
ca_set_flag(parent, CA_FLAG_READ_ONLY);
|
|
338
|
+
|
|
302
339
|
ca = ca_const_string_new(parent, rb_str_freeze(buffer), encoding_id);
|
|
303
340
|
obj = TypedData_Wrap_Struct(rb_cCAConstString, &catext_data_type, ca);
|
|
304
341
|
rb_ca_set_parent(obj, parent_val); /* pin parent VALUE for GC */
|
|
@@ -397,10 +434,13 @@ rb_ca_const_string_encoding (VALUE self)
|
|
|
397
434
|
return rb_enc_from_encoding(rb_enc_from_index(ca->encoding_id));
|
|
398
435
|
}
|
|
399
436
|
|
|
400
|
-
/* `CAConstString#buffer` — returns the frozen internal byte buffer
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
path.
|
|
437
|
+
/* `CAConstString#buffer` — returns the frozen internal byte buffer: a pure
|
|
438
|
+
concatenation of the element bytes, with no per-record length prefix (=
|
|
439
|
+
the Arrow values buffer). Exposes the defining tail state for
|
|
440
|
+
introspection and the Arrow-boundary component-buffer export path. The
|
|
441
|
+
ranges that index it live in the storage, one (start,end) int64 pair per
|
|
442
|
+
element; `wrap` is where a hand-built pair array is checked against a
|
|
443
|
+
buffer. */
|
|
404
444
|
static VALUE
|
|
405
445
|
rb_ca_const_string_buffer (VALUE self)
|
|
406
446
|
{
|
|
@@ -411,6 +451,54 @@ rb_ca_const_string_buffer (VALUE self)
|
|
|
411
451
|
|
|
412
452
|
/* ------------------------------------------------------------------- */
|
|
413
453
|
|
|
454
|
+
/* to_string: the cells as a CAString over an object array of Strings, in
|
|
455
|
+
one pass over the buffer (shape and mask carried). */
|
|
456
|
+
static VALUE
|
|
457
|
+
rb_ca_const_string_to_string (VALUE self)
|
|
458
|
+
{
|
|
459
|
+
CAConstString *ca;
|
|
460
|
+
volatile VALUE vpairs, out;
|
|
461
|
+
CArray *pe, *co;
|
|
462
|
+
rb_encoding *enc;
|
|
463
|
+
const char *buf;
|
|
464
|
+
const int64_t *pair;
|
|
465
|
+
boolean8_t *m;
|
|
466
|
+
VALUE *cells;
|
|
467
|
+
ca_size_t i;
|
|
468
|
+
|
|
469
|
+
TypedData_Get_Struct(self, CAConstString, &catext_data_type, ca);
|
|
470
|
+
vpairs = rb_ca_parent(self);
|
|
471
|
+
TypedData_Get_Struct(vpairs, CArray, &carray_data_type, pe);
|
|
472
|
+
if ( ! ca_is_entity(pe) ) {
|
|
473
|
+
vpairs = rb_ca_copy(vpairs);
|
|
474
|
+
TypedData_Get_Struct(vpairs, CArray, &carray_data_type, pe);
|
|
475
|
+
}
|
|
476
|
+
enc = rb_enc_from_index(ca->encoding_id);
|
|
477
|
+
out = rb_carray_new(CA_OBJECT, pe->ndim, pe->dim, 0, NULL);
|
|
478
|
+
TypedData_Get_Struct(out, CArray, &carray_data_type, co);
|
|
479
|
+
m = ca_has_mask(pe) ? (boolean8_t *) pe->mask->ptr : NULL;
|
|
480
|
+
if ( m ) {
|
|
481
|
+
ca_create_mask(co);
|
|
482
|
+
memcpy(co->mask->ptr, m, pe->elements);
|
|
483
|
+
}
|
|
484
|
+
buf = RSTRING_PTR(ca->buffer);
|
|
485
|
+
pair = (const int64_t *) pe->ptr;
|
|
486
|
+
cells = (VALUE *) co->ptr;
|
|
487
|
+
for (i = 0; i < pe->elements; i++) {
|
|
488
|
+
if ( m && m[i] ) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
/* out is reachable and marks its cells, so each String is held as it
|
|
492
|
+
is stored */
|
|
493
|
+
cells[i] = rb_enc_str_new(buf + pair[2 * i],
|
|
494
|
+
(long) ( pair[2 * i + 1] - pair[2 * i] ), enc);
|
|
495
|
+
}
|
|
496
|
+
RB_GC_GUARD(vpairs);
|
|
497
|
+
RB_GC_GUARD(self);
|
|
498
|
+
return rb_funcall(rb_const_get(rb_cObject, rb_intern("CAString")),
|
|
499
|
+
rb_intern("wrap"), 1, out);
|
|
500
|
+
}
|
|
501
|
+
|
|
414
502
|
/* copy = compacting deep copy — the only chain-descent point in
|
|
415
503
|
CAConstString. Produces a standalone CAConstString:
|
|
416
504
|
- a fresh contiguous fixlen-16 (start,end) pair entity
|
|
@@ -435,8 +523,8 @@ rb_ca_const_string_copy (VALUE self)
|
|
|
435
523
|
TypedData_Get_Struct(self, CAConstString, &catext_data_type, ca);
|
|
436
524
|
|
|
437
525
|
/* materialize logical-order (start,end) pairs + mask */
|
|
438
|
-
ca_attach((CArray *) ca);
|
|
439
526
|
ca_update_mask((CArray *) ca);
|
|
527
|
+
ca_attach((CArray *) ca); /* window: detached before its one raise */
|
|
440
528
|
|
|
441
529
|
n = ca->elements;
|
|
442
530
|
src_pair = (int64_t *) ca->ptr;
|
|
@@ -516,12 +604,14 @@ typedef struct {
|
|
|
516
604
|
ca_size_t n;
|
|
517
605
|
} ca_const_string_scan_t;
|
|
518
606
|
|
|
607
|
+
/* Opens the scan's window; ca_const_string_scan_end closes it. What runs
|
|
608
|
+
between them in this file reads bytes and raises only after closing. */
|
|
519
609
|
static void
|
|
520
610
|
ca_const_string_scan_begin (VALUE self, ca_const_string_scan_t *s)
|
|
521
611
|
{
|
|
522
612
|
TypedData_Get_Struct(self, CAConstString, &catext_data_type, s->ca);
|
|
523
|
-
ca_attach((CArray *) s->ca);
|
|
524
613
|
ca_update_mask((CArray *) s->ca);
|
|
614
|
+
ca_attach((CArray *) s->ca); /* window: closed by ca_const_string_scan_end */
|
|
525
615
|
s->off = (int64_t *) s->ca->ptr;
|
|
526
616
|
s->m = s->ca->mask ? (boolean8_t *) s->ca->mask->ptr : NULL;
|
|
527
617
|
s->buf = RSTRING_PTR(s->ca->buffer);
|
|
@@ -535,12 +625,43 @@ ca_const_string_scan_end (ca_const_string_scan_t *s)
|
|
|
535
625
|
ca_detach((CArray *) s->ca);
|
|
536
626
|
}
|
|
537
627
|
|
|
628
|
+
typedef struct {
|
|
629
|
+
VALUE self;
|
|
630
|
+
ca_const_string_scan_t *s;
|
|
631
|
+
} ca_const_string_scan_arg_t;
|
|
632
|
+
|
|
633
|
+
static VALUE
|
|
634
|
+
ca_const_string_scan_begin_body (VALUE arg)
|
|
635
|
+
{
|
|
636
|
+
ca_const_string_scan_arg_t *x = (ca_const_string_scan_arg_t *) arg;
|
|
637
|
+
ca_const_string_scan_begin(x->self, x->s);
|
|
638
|
+
return Qnil;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/* Begins the scans of two arrays, both or neither: when the second one's
|
|
642
|
+
attach raises, the first is closed before the raise goes on. */
|
|
643
|
+
static void
|
|
644
|
+
ca_const_string_scan_begin_pair (VALUE va, ca_const_string_scan_t *a,
|
|
645
|
+
VALUE vb, ca_const_string_scan_t *b)
|
|
646
|
+
{
|
|
647
|
+
ca_const_string_scan_arg_t x;
|
|
648
|
+
int tag = 0;
|
|
649
|
+
ca_const_string_scan_begin(va, a);
|
|
650
|
+
x.self = vb;
|
|
651
|
+
x.s = b;
|
|
652
|
+
rb_protect(ca_const_string_scan_begin_body, (VALUE) &x, &tag);
|
|
653
|
+
if ( tag ) {
|
|
654
|
+
ca_const_string_scan_end(a);
|
|
655
|
+
rb_jump_tag(tag);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
538
659
|
/* Resolve element i to its record bytes; returns 0 if masked.
|
|
539
660
|
Storage is (start,end) int64 pairs: s->off holds 2 int64 per element,
|
|
540
661
|
so element i occupies s->off[2*i] (start) .. s->off[2*i+1] (end).
|
|
541
662
|
The buffer is a pure concatenation; length = end - start. */
|
|
542
663
|
static inline int
|
|
543
|
-
ca_const_string_record (ca_const_string_scan_t *s, ca_size_t i, const char **pp,
|
|
664
|
+
ca_const_string_record (ca_const_string_scan_t *s, ca_size_t i, const char **pp, int64_t *plen)
|
|
544
665
|
{
|
|
545
666
|
int64_t start, end;
|
|
546
667
|
if ( s->m && s->m[i] ) {
|
|
@@ -549,7 +670,7 @@ ca_const_string_record (ca_const_string_scan_t *s, ca_size_t i, const char **pp,
|
|
|
549
670
|
start = s->off[2 * i];
|
|
550
671
|
end = s->off[2 * i + 1];
|
|
551
672
|
*pp = s->buf + start;
|
|
552
|
-
*plen = (
|
|
673
|
+
*plen = (int64_t) (end - start);
|
|
553
674
|
return 1;
|
|
554
675
|
}
|
|
555
676
|
|
|
@@ -598,7 +719,7 @@ rb_ca_const_string_byte_length (VALUE self)
|
|
|
598
719
|
CArray *co;
|
|
599
720
|
int64_t *op;
|
|
600
721
|
const char *p;
|
|
601
|
-
|
|
722
|
+
int64_t len;
|
|
602
723
|
ca_size_t i;
|
|
603
724
|
|
|
604
725
|
ca_const_string_scan_begin(self, &s);
|
|
@@ -633,7 +754,7 @@ ca_const_string_predicate (VALUE self, VALUE query, int op)
|
|
|
633
754
|
boolean8_t *out;
|
|
634
755
|
const char *qp, *p;
|
|
635
756
|
long qlen;
|
|
636
|
-
|
|
757
|
+
int64_t len;
|
|
637
758
|
ca_size_t i;
|
|
638
759
|
|
|
639
760
|
if ( TYPE(query) != T_STRING ) {
|
|
@@ -686,11 +807,10 @@ rb_ca_const_string_eq (VALUE self, VALUE other)
|
|
|
686
807
|
they are read only when both records are valid, but GCC cannot prove
|
|
687
808
|
that -- initialize to keep -Wmaybe-uninitialized quiet and defensive. */
|
|
688
809
|
const char *pa = NULL, *pb = NULL;
|
|
689
|
-
|
|
810
|
+
int64_t la = 0, lb = 0;
|
|
690
811
|
ca_size_t i;
|
|
691
812
|
|
|
692
|
-
|
|
693
|
-
ca_const_string_scan_begin(other, &b);
|
|
813
|
+
ca_const_string_scan_begin_pair(self, &a, other, &b);
|
|
694
814
|
if ( a.n != b.n ) {
|
|
695
815
|
ca_const_string_scan_end(&a);
|
|
696
816
|
ca_const_string_scan_end(&b);
|
|
@@ -717,7 +837,7 @@ rb_ca_const_string_count (VALUE self, VALUE query)
|
|
|
717
837
|
ca_const_string_scan_t s;
|
|
718
838
|
const char *qp, *p;
|
|
719
839
|
long qlen;
|
|
720
|
-
|
|
840
|
+
int64_t len;
|
|
721
841
|
ca_size_t i, c = 0;
|
|
722
842
|
|
|
723
843
|
if ( TYPE(query) != T_STRING ) {
|
|
@@ -747,7 +867,7 @@ rb_ca_const_string_search (VALUE self, VALUE query)
|
|
|
747
867
|
ca_const_string_scan_t s;
|
|
748
868
|
const char *qp, *p;
|
|
749
869
|
long qlen;
|
|
750
|
-
|
|
870
|
+
int64_t len;
|
|
751
871
|
ca_size_t i;
|
|
752
872
|
VALUE result = Qnil;
|
|
753
873
|
|
|
@@ -786,7 +906,7 @@ ca_const_string_byte_cmp (const void *a, const void *b)
|
|
|
786
906
|
/* sort raises on masked input, so record() always sets these here; the
|
|
787
907
|
initializers keep -Wmaybe-uninitialized quiet and stay defensive. */
|
|
788
908
|
const char *pa = NULL, *pb = NULL;
|
|
789
|
-
|
|
909
|
+
int64_t la = 0, lb = 0;
|
|
790
910
|
int c;
|
|
791
911
|
ca_const_string_record(ca_const_string_sort_ctx, ia, &pa, &la);
|
|
792
912
|
ca_const_string_record(ca_const_string_sort_ctx, ib, &pb, &lb);
|
|
@@ -836,9 +956,15 @@ rb_ca_const_string_sort_index (VALUE self)
|
|
|
836
956
|
return vout;
|
|
837
957
|
}
|
|
838
958
|
|
|
839
|
-
/*
|
|
840
|
-
|
|
841
|
-
|
|
959
|
+
/* The ordering surface is defined in Ruby (lib/carray/const_string.rb) on
|
|
960
|
+
top of these three: a storage cell is a byte range, so storage order is
|
|
961
|
+
insertion order rather than string order, and every member has to read
|
|
962
|
+
the bytes. What is native here is the flat form, which is the common one
|
|
963
|
+
for a string column and which a byte scan does an order of magnitude
|
|
964
|
+
faster than decoding a Ruby String per cell; the per-axis forms go
|
|
965
|
+
through #to_string. These are spelled as internals because the public
|
|
966
|
+
names carry CArray's meanings: what the permutation below answers is
|
|
967
|
+
sort_addr (view-flat addresses in sorted order), not sort_index. */
|
|
842
968
|
|
|
843
969
|
/* CAConstString#min / #max → the byte-min / byte-max element as a frozen String,
|
|
844
970
|
skipping masked elements; nil if empty or all masked. */
|
|
@@ -847,7 +973,7 @@ ca_const_string_extremum (VALUE self, int want_max)
|
|
|
847
973
|
{
|
|
848
974
|
ca_const_string_scan_t s;
|
|
849
975
|
const char *p, *bestp = NULL;
|
|
850
|
-
|
|
976
|
+
int64_t len, bestlen = 0;
|
|
851
977
|
ca_size_t i;
|
|
852
978
|
int found = 0;
|
|
853
979
|
|
|
@@ -893,10 +1019,11 @@ rb_ca_const_string_initialize_copy (VALUE self, VALUE other)
|
|
|
893
1019
|
{
|
|
894
1020
|
CAConstString *ca, *cs;
|
|
895
1021
|
TypedData_Get_Struct(self, CAConstString, &catext_data_type, ca);
|
|
1022
|
+
ca_check_uninitialized(ca);
|
|
896
1023
|
TypedData_Get_Struct(other, CAConstString, &catext_data_type, cs);
|
|
897
|
-
/*
|
|
898
|
-
|
|
899
|
-
buffer
|
|
1024
|
+
/* Shallow re-setup: shares the buffer and the offset source, which is the
|
|
1025
|
+
documented `dup` semantics for a view. `copy` is the compacting deep
|
|
1026
|
+
copy (rebased offsets, compacted buffer, detached). */
|
|
900
1027
|
if ( ca_func[CA_OBJ_CONST_STRING].pool_init ) {
|
|
901
1028
|
ca_array_pool_alloc(ca, CA_OBJ_CONST_STRING, cs->parent->ndim);
|
|
902
1029
|
}
|
|
@@ -928,11 +1055,12 @@ Init_ca_obj_const_string (void)
|
|
|
928
1055
|
rb_define_singleton_method(rb_cCAConstString, "__build__", rb_ca_const_string_build, 2);
|
|
929
1056
|
rb_define_method(rb_cCAConstString, "encoding", rb_ca_const_string_encoding, 0);
|
|
930
1057
|
rb_define_method(rb_cCAConstString, "buffer", rb_ca_const_string_buffer, 0);
|
|
931
|
-
rb_define_method(rb_cCAConstString, "
|
|
932
|
-
|
|
1058
|
+
rb_define_method(rb_cCAConstString, "storage_to_element",
|
|
1059
|
+
rb_ca_const_string_storage_to_element, 1);
|
|
933
1060
|
|
|
934
1061
|
/* copy = compacting deep copy; to_ca is the same descent point. */
|
|
935
1062
|
rb_define_method(rb_cCAConstString, "copy", rb_ca_const_string_copy, 0);
|
|
1063
|
+
rb_define_method(rb_cCAConstString, "to_string", rb_ca_const_string_to_string, 0);
|
|
936
1064
|
rb_define_method(rb_cCAConstString, "to_ca", rb_ca_const_string_to_ca, -1);
|
|
937
1065
|
|
|
938
1066
|
/* native byte ops (§3.7) */
|
|
@@ -949,14 +1077,16 @@ Init_ca_obj_const_string (void)
|
|
|
949
1077
|
rb_define_method(rb_cCAConstString, "search", rb_ca_const_string_search, 1);
|
|
950
1078
|
rb_define_method(rb_cCAConstString, "find_value_index", rb_ca_const_string_search, 1);
|
|
951
1079
|
|
|
952
|
-
/*
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
rb_define_method(rb_cCAConstString, "
|
|
956
|
-
|
|
1080
|
+
/* Native flat sort permutation / min / max (§3.7), byte-memcmp
|
|
1081
|
+
comparator. The public ordering surface is built on these in
|
|
1082
|
+
lib/carray/const_string.rb; see the comment above their definitions. */
|
|
1083
|
+
rb_define_method(rb_cCAConstString, "__sort_addr_bytes__",
|
|
1084
|
+
rb_ca_const_string_sort_index, 0);
|
|
1085
|
+
rb_define_method(rb_cCAConstString, "__min_bytes__", rb_ca_const_string_min, 0);
|
|
1086
|
+
rb_define_method(rb_cCAConstString, "__max_bytes__", rb_ca_const_string_max, 0);
|
|
957
1087
|
|
|
958
1088
|
/* Y-pilot: Face-local C-level fast path for per-cell scalar fetch. */
|
|
959
|
-
|
|
1089
|
+
ca_face_register_storage_to_element(CA_OBJ_CONST_STRING, rb_ca_const_string_storage_to_element);
|
|
960
1090
|
|
|
961
1091
|
/* F.S1: CAConstString's `buffer` field is per-parent (= each CAConstString holds its
|
|
962
1092
|
own frozen byte String; cell offsets index into THIS instance's
|