carray 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -0,0 +1,435 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_obj_timedelta.c
4
+
5
+ CATimedelta — semantic mask (Face) over int64 storage; sibling of
6
+ CATime. A time duration represented as an int64 count in a
7
+ chosen `unit`.
8
+
9
+ Structurally identical to CATime (= only the semantic identifier
10
+ differs); storage ops go via ca_face_* thin-forwards (ca_obj_face.h).
11
+ The Ruby-side Comparable / to_s / <=> surface lives in
12
+ lib/carray/time.rb.
13
+
14
+ --------------------------------------------------------------------------- */
15
+
16
+ #include "carray.h"
17
+ #include "ca_obj_face.h"
18
+
19
+ /* The unit enum is shared with CATime (= same unit system).
20
+ No CA_TIMEDELTA_UNIT_* aliases; use the same values as CATime. */
21
+ extern int8_t ca_time_unit_value (VALUE sym);
22
+ extern VALUE ca_time_unit_to_symbol (int8_t unit);
23
+ extern VALUE ca_time_resolution (int64_t count, int8_t unit);
24
+ extern void ca_time_extract_unit (VALUE unit, int8_t *base, int64_t *count);
25
+
26
+ typedef struct {
27
+ /* === CAView prefix === */
28
+ int16_t obj_type;
29
+ int8_t data_type; /* fixed to CA_INT64 */
30
+ int8_t ndim;
31
+ int32_t flags; /* CA_FLAG_IS_FACE set */
32
+ ca_size_t bytes; /* fixed to sizeof(int64_t) */
33
+ ca_size_t elements;
34
+ ca_size_t *dim;
35
+ char *ptr;
36
+ CArray *mask;
37
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
38
+ CArray *parent;
39
+ uint32_t attach;
40
+ uint8_t nosync;
41
+ /* === Face tail === */
42
+ int8_t unit; /* CA_DATETIME_UNIT_* (the tick base) */
43
+ int64_t count; /* tick multiplier N (tick = count * base) */
44
+ } CATimedelta;
45
+
46
+ static size_t
47
+ ca_timedelta_dsize (const void *ap)
48
+ {
49
+ const CATimedelta *ca = (const CATimedelta *) ap;
50
+ return sizeof(CATimedelta) + ca->ndim * sizeof(ca_size_t);
51
+ }
52
+
53
+ /* Pool framework hooks: single ndim-sized tail (dim) in the _pool buffer. */
54
+ static size_t
55
+ ca_timedelta_pool_bytes (int8_t ndim)
56
+ {
57
+ ca_size_t n = (ndim > 0) ? ndim : 1;
58
+ return (size_t) n * sizeof(ca_size_t);
59
+ }
60
+
61
+ static void
62
+ ca_timedelta_pool_init (void *ap, int8_t ndim)
63
+ {
64
+ CATimedelta *ca = (CATimedelta *) ap;
65
+ ca->dim = (ca_size_t *) ca->_pool;
66
+ }
67
+
68
+ const rb_data_type_t catimedelta_data_type = {
69
+ .parent = &caface_data_type,
70
+ .wrap_struct_name = "CATimedelta",
71
+ .function = {
72
+ .dmark = ca_mark,
73
+ .dfree = ca_free,
74
+ .dsize = ca_timedelta_dsize,
75
+ .dcompact = NULL
76
+ },
77
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
78
+ };
79
+
80
+ static int8_t CA_OBJ_TIMEDELTA;
81
+ static VALUE rb_cCATimedelta;
82
+ static VALUE rb_cCATimedeltaElement;
83
+
84
+ /* CATimedelta::Element as a C TypedData struct (= same shape as
85
+ CATimeElement). Storing value + unit in the struct lets
86
+ Scalar.new / value / unit skip Ruby method dispatch. */
87
+ typedef struct {
88
+ int64_t value;
89
+ int8_t unit;
90
+ int64_t count;
91
+ } CATimedeltaElement;
92
+
93
+ static size_t
94
+ ca_timedelta_element_dsize (const void *ap)
95
+ {
96
+ (void) ap;
97
+ return sizeof(CATimedeltaElement);
98
+ }
99
+
100
+ static void
101
+ ca_timedelta_element_free (void *ap)
102
+ {
103
+ if (ap) xfree(ap);
104
+ }
105
+
106
+ const rb_data_type_t catimedelta_element_data_type = {
107
+ .wrap_struct_name = "CATimedelta::Element",
108
+ .function = {
109
+ .dmark = NULL,
110
+ .dfree = ca_timedelta_element_free,
111
+ .dsize = ca_timedelta_element_dsize,
112
+ },
113
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
114
+ };
115
+
116
+ static VALUE
117
+ rb_ca_timedelta_element_s_allocate (VALUE klass)
118
+ {
119
+ CATimedeltaElement *s;
120
+ return TypedData_Make_Struct(klass, CATimedeltaElement,
121
+ &catimedelta_element_data_type, s);
122
+ }
123
+
124
+ static VALUE
125
+ rb_ca_timedelta_element_initialize (VALUE self, VALUE value, VALUE unit)
126
+ {
127
+ CATimedeltaElement *s;
128
+ TypedData_Get_Struct(self, CATimedeltaElement,
129
+ &catimedelta_element_data_type, s);
130
+ s->value = NUM2LL(value);
131
+ ca_time_extract_unit(unit, &s->unit, &s->count);
132
+ return self;
133
+ }
134
+
135
+ static VALUE
136
+ rb_ca_timedelta_element_value (VALUE self)
137
+ {
138
+ CATimedeltaElement *s;
139
+ TypedData_Get_Struct(self, CATimedeltaElement,
140
+ &catimedelta_element_data_type, s);
141
+ return LL2NUM(s->value);
142
+ }
143
+
144
+ /* unit → CATime::Resolution(count, base) */
145
+ static VALUE
146
+ rb_ca_timedelta_element_unit (VALUE self)
147
+ {
148
+ CATimedeltaElement *s;
149
+ TypedData_Get_Struct(self, CATimedeltaElement,
150
+ &catimedelta_element_data_type, s);
151
+ return ca_time_resolution(s->count, s->unit);
152
+ }
153
+
154
+ /* ------------------------------------------------------------------- */
155
+
156
+ int
157
+ ca_timedelta_setup (CATimedelta *ca, CArray *parent, int8_t unit, int64_t count)
158
+ {
159
+ if ( parent->data_type != CA_INT64 ) {
160
+ rb_raise(rb_eTypeError,
161
+ "CATimedelta requires int64 storage (parent.data_type != CA_INT64)");
162
+ }
163
+
164
+ ca->obj_type = CA_OBJ_TIMEDELTA;
165
+ /* NonNumeric surface (the FIXLEN gate), like CATime: the storage is a
166
+ count of `count x unit` ticks, and letting the numeric kernels read it
167
+ means sqrt / exp / sin / variance of a duration, and an `abs` that drops
168
+ the Face. Arithmetic and reductions that *are* meaningful on a duration
169
+ are Ruby overrides in lib/carray/time.rb, so they do not depend on the
170
+ numeric dispatch. Turning a duration into a number is #to_numeric. */
171
+ ca->data_type = CA_FIXLEN;
172
+ /* ORDERABLE: int64 storage order == timedelta <=> order, so sort family may
173
+ descend to storage. NOT COMPARABLE: an external query may carry a
174
+ different unit, so raw storage compare against a query is unsafe. */
175
+ ca->flags = CA_FLAG_IS_FACE | CA_FLAG_FACE_ORDERABLE_STORAGE;
176
+ ca->ndim = parent->ndim;
177
+ ca->bytes = sizeof(int64_t);
178
+ ca->elements = parent->elements;
179
+ ca->ptr = NULL;
180
+ ca->mask = NULL;
181
+ if ( ! ca->_pool ) {
182
+ ca->dim = ALLOC_N(ca_size_t, parent->ndim);
183
+ }
184
+ memcpy(ca->dim, parent->dim, sizeof(ca_size_t) * parent->ndim);
185
+
186
+ ca->parent = parent;
187
+ ca->attach = 0;
188
+ ca->nosync = 0;
189
+
190
+ ca->unit = unit;
191
+ ca->count = count;
192
+
193
+ if ( ca_has_mask(parent) ) {
194
+ ca_create_mask((CArray *) ca);
195
+ }
196
+
197
+ if ( ca_is_scalar(parent) ) {
198
+ ca_set_flag(ca, CA_FLAG_SCALAR);
199
+ }
200
+
201
+ if ( ca_test_flag(parent, CA_FLAG_READ_ONLY) ) {
202
+ ca_set_flag(ca, CA_FLAG_READ_ONLY);
203
+ }
204
+
205
+ return 0;
206
+ }
207
+
208
+ CATimedelta *
209
+ ca_timedelta_new (CArray *parent, int8_t unit, int64_t count)
210
+ {
211
+ CATimedelta *ca = (CATimedelta *) ca_array_alloc(CA_OBJ_TIMEDELTA, parent->ndim);
212
+ ca_timedelta_setup(ca, parent, unit, count);
213
+ return ca;
214
+ }
215
+
216
+ static void
217
+ free_ca_timedelta (void *ap)
218
+ {
219
+ CATimedelta *ca = (CATimedelta *) ap;
220
+ if ( ca != NULL ) {
221
+ ca_free(ca->mask);
222
+ if ( ca->_pool ) {
223
+ ca_array_free(ca); /* dim lives in _pool */
224
+ }
225
+ else {
226
+ xfree(ca->dim);
227
+ xfree(ca);
228
+ }
229
+ }
230
+ }
231
+
232
+ /* ------------------------------------------------------------------- */
233
+
234
+ static void *
235
+ ca_timedelta_func_clone (void *ap)
236
+ {
237
+ CATimedelta *ca = (CATimedelta *) ap;
238
+ return ca_timedelta_new(ca->parent, ca->unit, ca->count);
239
+ }
240
+
241
+ static void
242
+ ca_timedelta_func_allocate (void *ap)
243
+ {
244
+ CATimedelta *ca = (CATimedelta *) ap;
245
+ ca_attach(ca->parent);
246
+ ca->ptr = ca->parent->ptr;
247
+ }
248
+
249
+ static void
250
+ ca_timedelta_func_create_mask (void *ap)
251
+ {
252
+ CATimedelta *ca = (CATimedelta *) ap;
253
+ ca_update_mask(ca->parent);
254
+ if ( ! ca->parent->mask ) {
255
+ ca_create_mask(ca->parent);
256
+ }
257
+ ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
258
+ CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
259
+ }
260
+
261
+ ca_operation_function_t ca_timedelta_func = {
262
+ -1, /* CA_OBJ_TIMEDELTA — filled by ca_install_obj_type */
263
+ CA_VIEW_ARRAY,
264
+ free_ca_timedelta,
265
+ ca_timedelta_func_clone,
266
+ ca_timedelta_func_allocate,
267
+ ca_face_attach,
268
+ ca_face_sync,
269
+ ca_face_detach,
270
+ ca_face_fill_data,
271
+ ca_timedelta_func_create_mask,
272
+ ca_face_xfer_index,
273
+ ca_face_xfer_addrs,
274
+ NULL, /* fold_stride */
275
+ ca_face_xfer_stride,
276
+ ca_face_xfer_all
277
+ };
278
+
279
+ /* ------------------------------------------------------------------- */
280
+
281
+ VALUE
282
+ rb_ca_timedelta_wrap (VALUE parent_val, int8_t unit, int64_t count)
283
+ {
284
+ volatile VALUE obj;
285
+ CArray *parent;
286
+ CATimedelta *ca;
287
+
288
+ rb_check_carray_object(parent_val);
289
+ TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
290
+
291
+ ca = ca_timedelta_new(parent, unit, count);
292
+ obj = ca_wrap_struct(ca);
293
+ rb_ca_set_parent(obj, parent_val);
294
+ return obj;
295
+ }
296
+
297
+ /* __wrap__(raw, unit_spec) — primitive; unit_spec is Symbol / String /
298
+ Resolution / nil (normalized here). */
299
+ static VALUE
300
+ rb_ca_timedelta_wrap_method (VALUE klass, VALUE raw, VALUE unit_spec)
301
+ {
302
+ int8_t base;
303
+ int64_t count;
304
+ (void) klass;
305
+ ca_time_extract_unit(unit_spec, &base, &count);
306
+ return rb_ca_timedelta_wrap(raw, base, count);
307
+ }
308
+
309
+ /* CATimedelta#unit → CATime::Resolution(count, base) */
310
+ static VALUE
311
+ rb_ca_timedelta_unit (VALUE self)
312
+ {
313
+ CATimedelta *ca;
314
+ TypedData_Get_Struct(self, CATimedelta, &catimedelta_data_type, ca);
315
+ return ca_time_resolution(ca->count, ca->unit);
316
+ }
317
+
318
+ static VALUE
319
+ rb_ca_timedelta_s_allocate (VALUE klass)
320
+ {
321
+ CATimedelta *ca;
322
+ return TypedData_Make_Struct(klass, CATimedelta,
323
+ &catimedelta_data_type, ca);
324
+ }
325
+
326
+ static VALUE
327
+ rb_ca_timedelta_initialize_copy (VALUE self, VALUE other)
328
+ {
329
+ CATimedelta *ca, *cs;
330
+ TypedData_Get_Struct(self, CATimedelta, &catimedelta_data_type, ca);
331
+ TypedData_Get_Struct(other, CATimedelta, &catimedelta_data_type, cs);
332
+ if ( ca_func[CA_OBJ_TIMEDELTA].pool_init ) {
333
+ ca_array_pool_alloc(ca, CA_OBJ_TIMEDELTA, cs->parent->ndim);
334
+ }
335
+ ca_timedelta_setup(ca, cs->parent, cs->unit, cs->count);
336
+ return self;
337
+ }
338
+
339
+ /* storage_to_scalar implemented in C to avoid per-cell Ruby method dispatch
340
+ on the fetch hot path. Accepts either an Integer (INT64 surface fetch)
341
+ or an 8-byte String (FIXLEN surface fetch); decodes the parent int64
342
+ and constructs CATimedelta::Element(value, unit). */
343
+ static VALUE
344
+ rb_ca_timedelta_storage_to_scalar (VALUE self, VALUE raw)
345
+ {
346
+ CATimedelta *ca;
347
+ CATimedeltaElement *s;
348
+ VALUE scalar_obj;
349
+ int64_t value;
350
+
351
+ TypedData_Get_Struct(self, CATimedelta, &catimedelta_data_type, ca);
352
+
353
+ if ( TYPE(raw) == T_STRING ) {
354
+ if ( RSTRING_LEN(raw) != (long) sizeof(int64_t) ) {
355
+ rb_raise(rb_eArgError,
356
+ "CATimedelta#storage_to_scalar: expected %lu bytes, got %ld",
357
+ (unsigned long) sizeof(int64_t), RSTRING_LEN(raw));
358
+ }
359
+ memcpy(&value, RSTRING_PTR(raw), sizeof(int64_t));
360
+ }
361
+ else {
362
+ value = NUM2LL(raw);
363
+ }
364
+
365
+ /* Direct alloc + struct field write — no LL2NUM, no rb_class_new_instance,
366
+ no Ruby initialize dispatch (= mirror CATime fast path). */
367
+ scalar_obj = TypedData_Make_Struct(rb_cCATimedeltaElement,
368
+ CATimedeltaElement,
369
+ &catimedelta_element_data_type, s);
370
+ s->value = value;
371
+ s->unit = ca->unit;
372
+ s->count = ca->count;
373
+ return scalar_obj;
374
+ }
375
+
376
+ /* Face state homogeneity check — two CATimedelta instances are
377
+ compatible iff their resolution (base + count) matches. */
378
+ static int
379
+ ca_timedelta_state_compatible (CArray *a, CArray *b)
380
+ {
381
+ CATimedelta *da = (CATimedelta *) a;
382
+ CATimedelta *db = (CATimedelta *) b;
383
+ return ( da->unit == db->unit && da->count == db->count ) ? 1 : 0;
384
+ }
385
+
386
+ void
387
+ Init_ca_obj_timedelta (void)
388
+ {
389
+ rb_cCATimedelta = rb_define_class("CATimedelta", rb_cCAFace);
390
+
391
+ ca_timedelta_func.struct_size = sizeof(CATimedelta);
392
+ ca_timedelta_func.pool_bytes = ca_timedelta_pool_bytes;
393
+ ca_timedelta_func.pool_init = ca_timedelta_pool_init;
394
+
395
+ CA_OBJ_TIMEDELTA = ca_install_obj_type(rb_cCATimedelta,
396
+ &catimedelta_data_type,
397
+ rb_cCArrayMask,
398
+ &carray_mask_data_type,
399
+ &ca_timedelta_func, sizeof(ca_timedelta_func));
400
+ rb_define_const(rb_cObject, "CA_OBJ_TIMEDELTA", INT2NUM(CA_OBJ_TIMEDELTA));
401
+
402
+ rb_define_alloc_func(rb_cCATimedelta, rb_ca_timedelta_s_allocate);
403
+ rb_define_method(rb_cCATimedelta, "initialize_copy",
404
+ rb_ca_timedelta_initialize_copy, 1);
405
+
406
+ rb_define_singleton_method(rb_cCATimedelta, "__wrap__",
407
+ rb_ca_timedelta_wrap_method, 2);
408
+ rb_define_method(rb_cCATimedelta, "unit", rb_ca_timedelta_unit, 0);
409
+ rb_define_method(rb_cCATimedelta, "storage_to_scalar",
410
+ rb_ca_timedelta_storage_to_scalar, 1);
411
+ /* Registers the state-compatibility predicate so CA_FACE_STORAGE_TO_SCALAR_IF_FACE
412
+ can skip rb_funcall on the hot path. */
413
+ ca_face_register_state_compatible(CA_OBJ_TIMEDELTA,
414
+ ca_timedelta_state_compatible);
415
+ /* unit is pure metadata, no per-parent buffer; multi-parent Face lift
416
+ is safe (portable = 1). */
417
+ ca_face_register_state_portable(CA_OBJ_TIMEDELTA, 1);
418
+ ca_face_register_storage_to_scalar(CA_OBJ_TIMEDELTA,
419
+ rb_ca_timedelta_storage_to_scalar);
420
+
421
+ /* CATimedelta::Element as a C-backed TypedData class. The Ruby-side
422
+ definition in lib/carray/time.rb keeps Comparable + to_seconds /
423
+ to_s / inspect / <=> / == ; the C side owns the storage (int64 value
424
+ + int8 unit) and the allocator + initialize + value + unit accessors. */
425
+ rb_cCATimedeltaElement = rb_define_class_under(rb_cCATimedelta,
426
+ "Element", rb_cObject);
427
+ rb_define_alloc_func(rb_cCATimedeltaElement,
428
+ rb_ca_timedelta_element_s_allocate);
429
+ rb_define_method(rb_cCATimedeltaElement, "initialize",
430
+ rb_ca_timedelta_element_initialize, 2);
431
+ rb_define_method(rb_cCATimedeltaElement, "value",
432
+ rb_ca_timedelta_element_value, 0);
433
+ rb_define_method(rb_cCATimedeltaElement, "unit",
434
+ rb_ca_timedelta_element_unit, 0);
435
+ }