carray 2.0.1 → 3.0.1

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 (386) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -25
  3. data/CHANGELOG.md +338 -0
  4. data/{NEWS.md → CHANGELOG.v1.md} +3 -0
  5. data/LICENSE +1 -1
  6. data/README.md +120 -36
  7. data/carray.gemspec +32 -30
  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 +1244 -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 +124 -0
  15. data/ext/ca_binop_dispatch.h +152 -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 +239 -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 +4367 -0
  26. data/ext/ca_kernel_iterator.h +2596 -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 +839 -0
  33. data/ext/ca_obj_binop.c +948 -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 +967 -0
  39. data/ext/ca_obj_face.c +750 -0
  40. data/ext/ca_obj_face.h +279 -0
  41. data/ext/ca_obj_fake.c +239 -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 +308 -0
  45. data/ext/ca_obj_grid.c +866 -440
  46. data/ext/ca_obj_meld.c +1039 -0
  47. data/ext/ca_obj_moncmp.c +588 -0
  48. data/ext/ca_obj_monop.c +1123 -0
  49. data/ext/ca_obj_object.c +866 -296
  50. data/ext/ca_obj_record.c +470 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +593 -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 +624 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1306 -0
  58. data/ext/ca_obj_shift.c +231 -793
  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 +2584 -0
  62. data/ext/ca_obj_string.c +270 -0
  63. data/ext/ca_obj_tile.c +622 -0
  64. data/ext/ca_obj_time.c +548 -0
  65. data/ext/ca_obj_timedelta.c +437 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +785 -0
  68. data/ext/ca_obj_window.c +1202 -565
  69. data/ext/ca_op_byte_swap.c +175 -0
  70. data/ext/ca_op_cmplx64.h +123 -0
  71. data/ext/ca_op_ipower.c +316 -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 +473 -0
  75. data/ext/ca_sweep_engine.h +166 -0
  76. data/ext/ca_transform_common.c +235 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +810 -420
  80. data/ext/carray_access.c +873 -731
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +376 -0
  84. data/ext/carray_build_flags.h +3 -0
  85. data/ext/carray_call_cfunc.c +2897 -874
  86. data/ext/carray_call_cfunc.h +313 -0
  87. data/ext/carray_cast.c +1264 -315
  88. data/ext/carray_cast_func.rb +81 -40
  89. data/ext/carray_class.c +53 -63
  90. data/ext/carray_config.h +28 -0
  91. data/ext/carray_conversion.c +350 -346
  92. data/ext/carray_copy.c +168 -270
  93. data/ext/carray_core.c +1396 -206
  94. data/ext/carray_count.c +312 -0
  95. data/ext/carray_data_type.c +43 -19
  96. data/ext/carray_element.c +585 -213
  97. data/ext/carray_factorize.c +2542 -0
  98. data/ext/carray_generate.c +230 -559
  99. data/ext/carray_histogram.c +490 -0
  100. data/ext/carray_hold.c +228 -0
  101. data/ext/carray_index_classifier.c +1021 -0
  102. data/ext/carray_index_classifier.h +27 -0
  103. data/ext/carray_internal.h +136 -0
  104. data/ext/carray_kernels_bincmp.c +4446 -0
  105. data/ext/carray_kernels_binop.c +11001 -0
  106. data/ext/carray_kernels_init.c +1131 -0
  107. data/ext/carray_kernels_map.c +3467 -0
  108. data/ext/carray_kernels_moncmp.c +2097 -0
  109. data/ext/carray_kernels_monop.c +18313 -0
  110. data/ext/carray_kernels_reduce_aggregate.c +25837 -0
  111. data/ext/carray_kernels_reduce_boolean.c +330 -0
  112. data/ext/carray_kernels_reduce_cumulative.c +14593 -0
  113. data/ext/carray_kernels_reduce_extreme.c +16948 -0
  114. data/ext/carray_kernels_reduce_variance.c +3910 -0
  115. data/ext/carray_kernels_scan.c +3693 -0
  116. data/ext/carray_kernels_search.c +32138 -0
  117. data/ext/carray_kernels_sort.c +10626 -0
  118. data/ext/carray_kernels_triop.c +1392 -0
  119. data/ext/carray_lazy.c +737 -0
  120. data/ext/carray_loop.c +88 -200
  121. data/ext/carray_mask.c +853 -158
  122. data/ext/carray_math_kernel.h +120 -0
  123. data/ext/carray_mathfunc.c +10 -241
  124. data/ext/carray_median_percentile.c +1257 -0
  125. data/ext/carray_memory_view.c +1650 -0
  126. data/ext/carray_operator.c +1525 -320
  127. data/ext/carray_order.c +664 -1394
  128. data/ext/carray_partition.c +416 -0
  129. data/ext/carray_random.c +518 -0
  130. data/ext/carray_scatter.c +357 -0
  131. data/ext/carray_slab.c +1219 -0
  132. data/ext/carray_slab.h +84 -0
  133. data/ext/carray_sort.c +829 -0
  134. data/ext/carray_sort_kernel.c +620 -0
  135. data/ext/carray_struct.c +695 -0
  136. data/ext/carray_test.c +343 -229
  137. data/ext/carray_undef.c +34 -17
  138. data/ext/carray_utils.c +175 -74
  139. data/ext/extconf.rb +234 -55
  140. data/ext/mk_call_cfunc.rb +671 -0
  141. data/ext/mkkernel.rb +9096 -0
  142. data/ext/ruby_carray.c +211 -108
  143. data/ext/version.h +4 -14
  144. data/ext/version.rb +5 -13
  145. data/lib/carray/arrow_tensor.rb +401 -0
  146. data/lib/carray/attribute.rb +166 -0
  147. data/lib/carray/autoload_carray.rb +239 -0
  148. data/lib/carray/autoload_method_extension.rb +45 -0
  149. data/lib/carray/axis_group.rb +711 -0
  150. data/lib/carray/basics.rb +481 -0
  151. data/lib/carray/bincount_nd.rb +358 -0
  152. data/lib/carray/block_iterator.rb +614 -0
  153. data/lib/carray/boolean_reduce.rb +109 -0
  154. data/lib/carray/categorical.rb +561 -0
  155. data/lib/carray/categorical_iterator.rb +1084 -0
  156. data/lib/carray/complex.rb +150 -0
  157. data/lib/carray/conditional.rb +216 -0
  158. data/lib/carray/const_string.rb +228 -0
  159. data/lib/carray/construct.rb +160 -328
  160. data/lib/carray/core_extensions.rb +297 -0
  161. data/lib/carray/data_type_extension.rb +250 -0
  162. data/lib/carray/fixlen_string.rb +95 -0
  163. data/lib/carray/frame/concat.rb +132 -0
  164. data/lib/carray/frame/convert.rb +95 -0
  165. data/lib/carray/frame/csv_parser.rb +211 -0
  166. data/lib/carray/frame/frame.rb +642 -0
  167. data/lib/carray/frame/group.rb +186 -0
  168. data/lib/carray/frame/io.rb +321 -0
  169. data/lib/carray/frame/join.rb +248 -0
  170. data/lib/carray/frame/records.rb +99 -0
  171. data/lib/carray/frame/sort.rb +113 -0
  172. data/lib/carray/frame/verbs.rb +316 -0
  173. data/lib/carray/frame.rb +16 -0
  174. data/lib/carray/fuse_source.rb +123 -0
  175. data/lib/carray/fusion.rb +218 -0
  176. data/lib/carray/histogram.rb +512 -0
  177. data/lib/carray/inspect.rb +37 -26
  178. data/lib/carray/iterator.rb +58 -349
  179. data/lib/carray/lazy.rb +941 -0
  180. data/lib/carray/mask_gap_fill.rb +200 -0
  181. data/lib/carray/math.rb +78 -342
  182. data/lib/carray/meld_reduce.rb +289 -0
  183. data/lib/carray/methods/align_addr.rb +116 -0
  184. data/lib/carray/methods/bin.rb +128 -0
  185. data/lib/carray/methods/bincount.rb +87 -0
  186. data/lib/carray/methods/bit_string.rb +92 -0
  187. data/lib/carray/methods/broadcast.rb +63 -0
  188. data/lib/carray/methods/choose.rb +39 -0
  189. data/lib/carray/methods/composition.rb +280 -0
  190. data/lib/carray/methods/gather_nd.rb +206 -0
  191. data/lib/carray/methods/index.rb +39 -0
  192. data/lib/carray/methods/insert_block.rb +99 -0
  193. data/lib/carray/methods/is_in.rb +141 -0
  194. data/lib/carray/methods/join.rb +90 -0
  195. data/lib/carray/methods/locate_addr.rb +52 -0
  196. data/lib/carray/methods/mask_duplicates.rb +41 -0
  197. data/lib/carray/methods/meshgrid.rb +90 -0
  198. data/lib/carray/methods/mode.rb +126 -0
  199. data/lib/carray/methods/nunique.rb +46 -0
  200. data/lib/carray/methods/resize.rb +56 -0
  201. data/lib/carray/methods/snap.rb +161 -0
  202. data/lib/carray/methods/string_format.rb +57 -0
  203. data/lib/carray/methods/unique.rb +47 -0
  204. data/lib/carray/methods/value_counts.rb +71 -0
  205. data/lib/carray/mkmf.rb +124 -101
  206. data/lib/carray/runtime.rb +89 -0
  207. data/lib/carray/serialize.rb +478 -167
  208. data/lib/carray/slab_iterator.rb +305 -0
  209. data/lib/carray/stack.rb +291 -0
  210. data/lib/carray/string.rb +56 -180
  211. data/lib/carray/string_operation_extension.rb +289 -0
  212. data/lib/carray/struct.rb +335 -323
  213. data/lib/carray/struct_builder.rb +697 -0
  214. data/lib/carray/table.rb +41 -2
  215. data/lib/carray/time.rb +2654 -38
  216. data/lib/carray/window_iterator.rb +927 -0
  217. data/lib/carray.rb +55 -57
  218. data/yard-stubs/ca_obj_array.rb +385 -0
  219. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  220. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  221. data/yard-stubs/ca_obj_block.rb +73 -0
  222. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  223. data/yard-stubs/ca_obj_fake.rb +31 -0
  224. data/yard-stubs/ca_obj_farray.rb +32 -0
  225. data/yard-stubs/ca_obj_field.rb +45 -0
  226. data/yard-stubs/ca_obj_grid.rb +35 -0
  227. data/yard-stubs/ca_obj_refer.rb +72 -0
  228. data/yard-stubs/ca_obj_roll.rb +45 -0
  229. data/yard-stubs/ca_obj_shift.rb +43 -0
  230. data/yard-stubs/ca_obj_stride.rb +181 -0
  231. data/yard-stubs/ca_obj_tile.rb +29 -0
  232. data/yard-stubs/ca_obj_transpose.rb +40 -0
  233. data/yard-stubs/ca_obj_window.rb +49 -0
  234. data/yard-stubs/carray_access.rb +131 -0
  235. data/yard-stubs/carray_attribute.rb +246 -0
  236. data/yard-stubs/carray_broadcast.rb +37 -0
  237. data/yard-stubs/carray_cast.rb +489 -0
  238. data/yard-stubs/carray_class.rb +65 -0
  239. data/yard-stubs/carray_conversion.rb +76 -0
  240. data/yard-stubs/carray_copy.rb +79 -0
  241. data/yard-stubs/carray_core.rb +114 -0
  242. data/yard-stubs/carray_count.rb +79 -0
  243. data/yard-stubs/carray_element.rb +108 -0
  244. data/yard-stubs/carray_generate.rb +66 -0
  245. data/yard-stubs/carray_lazy.rb +23 -0
  246. data/yard-stubs/carray_loop.rb +140 -0
  247. data/yard-stubs/carray_mask.rb +259 -0
  248. data/yard-stubs/carray_math.rb +132 -0
  249. data/yard-stubs/carray_mathfunc.rb +45 -0
  250. data/yard-stubs/carray_median_percentile.rb +89 -0
  251. data/yard-stubs/carray_memory_view.rb +163 -0
  252. data/yard-stubs/carray_order.rb +312 -0
  253. data/yard-stubs/carray_random.rb +89 -0
  254. data/yard-stubs/carray_scatter.rb +106 -0
  255. data/yard-stubs/carray_slab.rb +57 -0
  256. data/yard-stubs/carray_sort.rb +163 -0
  257. data/yard-stubs/carray_test.rb +85 -0
  258. data/yard-stubs/carray_undef.rb +64 -0
  259. data/yard-stubs/carray_utils.rb +97 -0
  260. data/yard-stubs/ruby_carray.rb +193 -0
  261. metadata +220 -138
  262. data/Rakefile +0 -51
  263. data/TODO.md +0 -18
  264. data/ext/ca_iter_block.c +0 -257
  265. data/ext/ca_iter_dimension.c +0 -299
  266. data/ext/ca_iter_window.c +0 -214
  267. data/ext/ca_obj_mapping.c +0 -644
  268. data/ext/ca_obj_unbound_repeat.c +0 -529
  269. data/ext/carray_iterator.c +0 -641
  270. data/ext/carray_math.rb +0 -850
  271. data/ext/carray_numeric.c +0 -259
  272. data/ext/carray_sort_addr.c +0 -254
  273. data/ext/carray_stat.c +0 -2100
  274. data/ext/carray_stat_proc.rb +0 -1999
  275. data/ext/mkmath.rb +0 -741
  276. data/ext/ruby_ccomplex.c +0 -509
  277. data/ext/ruby_float_func.c +0 -86
  278. data/lib/carray/array.rb +0 -8
  279. data/lib/carray/autoload/autoload_base.rb +0 -19
  280. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  281. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  282. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  283. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  284. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  285. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  286. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  287. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  288. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  289. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  290. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  291. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  292. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  293. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  294. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  295. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  296. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  297. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  298. data/lib/carray/autoload.rb +0 -141
  299. data/lib/carray/basic.rb +0 -191
  300. data/lib/carray/broadcast.rb +0 -101
  301. data/lib/carray/compose.rb +0 -315
  302. data/lib/carray/convert.rb +0 -115
  303. data/lib/carray/info.rb +0 -110
  304. data/lib/carray/io/imagemagick.rb +0 -235
  305. data/lib/carray/mask.rb +0 -102
  306. data/lib/carray/math/histogram.rb +0 -177
  307. data/lib/carray/math/recurrence.rb +0 -93
  308. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  309. data/lib/carray/object/ca_obj_link.rb +0 -50
  310. data/lib/carray/object/ca_obj_pack.rb +0 -99
  311. data/lib/carray/obsolete.rb +0 -256
  312. data/lib/carray/ordering.rb +0 -181
  313. data/lib/carray/testing.rb +0 -51
  314. data/lib/carray/transform.rb +0 -109
  315. data/mailmap +0 -1
  316. data/misc/Methods.ja.md +0 -182
  317. data/misc/NOTE +0 -51
  318. data/spec/Classes/CABitfield_spec.rb +0 -58
  319. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  320. data/spec/Classes/CABlock_spec.rb +0 -205
  321. data/spec/Classes/CAField_spec.rb +0 -39
  322. data/spec/Classes/CAGrid_spec.rb +0 -75
  323. data/spec/Classes/CAMap_spec.rb +0 -0
  324. data/spec/Classes/CAMapping_spec.rb +0 -105
  325. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  326. data/spec/Classes/CAObject_spec.rb +0 -33
  327. data/spec/Classes/CARefer_spec.rb +0 -93
  328. data/spec/Classes/CARepeat_spec.rb +0 -65
  329. data/spec/Classes/CASelect_spec.rb +0 -22
  330. data/spec/Classes/CAShift_spec.rb +0 -16
  331. data/spec/Classes/CAStruct_spec.rb +0 -71
  332. data/spec/Classes/CATranspose_spec.rb +0 -60
  333. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  334. data/spec/Classes/CAWindow_spec.rb +0 -54
  335. data/spec/Classes/CAWrap_spec.rb +0 -8
  336. data/spec/Classes/CArray_spec.rb +0 -184
  337. data/spec/Classes/CScalar_spec.rb +0 -55
  338. data/spec/Features/feature_130_spec.rb +0 -19
  339. data/spec/Features/feature_attributes_spec.rb +0 -280
  340. data/spec/Features/feature_boolean_spec.rb +0 -98
  341. data/spec/Features/feature_broadcast.rb +0 -116
  342. data/spec/Features/feature_cast_function.rb +0 -19
  343. data/spec/Features/feature_cast_spec.rb +0 -33
  344. data/spec/Features/feature_class_spec.rb +0 -84
  345. data/spec/Features/feature_complex_spec.rb +0 -42
  346. data/spec/Features/feature_composite_spec.rb +0 -124
  347. data/spec/Features/feature_convert_spec.rb +0 -46
  348. data/spec/Features/feature_copy_spec.rb +0 -123
  349. data/spec/Features/feature_creation_spec.rb +0 -84
  350. data/spec/Features/feature_element_spec.rb +0 -144
  351. data/spec/Features/feature_extream_spec.rb +0 -54
  352. data/spec/Features/feature_generate_spec.rb +0 -74
  353. data/spec/Features/feature_index_spec.rb +0 -69
  354. data/spec/Features/feature_mask_spec.rb +0 -580
  355. data/spec/Features/feature_math_spec.rb +0 -97
  356. data/spec/Features/feature_order_spec.rb +0 -146
  357. data/spec/Features/feature_ref_store_spec.rb +0 -209
  358. data/spec/Features/feature_serialization_spec.rb +0 -125
  359. data/spec/Features/feature_stat_spec.rb +0 -397
  360. data/spec/Features/feature_virtual_spec.rb +0 -48
  361. data/spec/Features/method_eq_spec.rb +0 -81
  362. data/spec/Features/method_is_nan_spec.rb +0 -12
  363. data/spec/Features/method_map_spec.rb +0 -54
  364. data/spec/Features/method_max_with.rb +0 -20
  365. data/spec/Features/method_min_with.rb +0 -19
  366. data/spec/Features/method_ne_spec.rb +0 -18
  367. data/spec/Features/method_project_spec.rb +0 -188
  368. data/spec/Features/method_ref_spec.rb +0 -27
  369. data/spec/Features/method_round_spec.rb +0 -11
  370. data/spec/Features/method_s_linspace_spec.rb +0 -48
  371. data/spec/Features/method_s_span_spec.rb +0 -14
  372. data/spec/Features/method_seq_spec.rb +0 -47
  373. data/spec/Features/method_sort_with.rb +0 -43
  374. data/spec/Features/method_sorted_with.rb +0 -29
  375. data/spec/Features/method_span_spec.rb +0 -42
  376. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  377. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  378. data/spec/spec_all.rb +0 -10
  379. data/utils/ca_ase.rb +0 -21
  380. data/utils/ca_methods.rb +0 -15
  381. data/utils/cast_checker.rb +0 -30
  382. data/utils/convert_test.rb +0 -73
  383. data/utils/extract_yard.rb +0 -22
  384. data/utils/guess_shape.rb +0 -76
  385. data/utils/monkey_patch_methods.rb +0 -62
  386. data/utils/remove_resource_fork.sh +0 -5
data/ext/ca_obj_time.c ADDED
@@ -0,0 +1,548 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_obj_time.c
4
+
5
+ CATime — semantic mask (Face) over int64 storage. Datetime
6
+ values represented as an int64 count in a chosen `unit`.
7
+
8
+ A Face is a mask of a semantic type (= same storage type, identifier +
9
+ unit layered on top); sibling to CAFake (= mask of data_type
10
+ conversion). Storage ops are thin-forwarded to the parent via the
11
+ ca_face_* helpers (ca_obj_face.h). The Ruby-side Comparable / to_time
12
+ / <=> surface lives in lib/carray/time.rb.
13
+
14
+ --------------------------------------------------------------------------- */
15
+
16
+ #include "carray.h"
17
+ #include "ca_obj_face.h"
18
+
19
+ /* unit enum (base epoch is 1970-01-01) */
20
+ enum {
21
+ CA_DATETIME_UNIT_Y = 0,
22
+ CA_DATETIME_UNIT_M = 1,
23
+ CA_DATETIME_UNIT_W = 2,
24
+ CA_DATETIME_UNIT_D = 3,
25
+ CA_DATETIME_UNIT_h = 4,
26
+ CA_DATETIME_UNIT_m = 5,
27
+ CA_DATETIME_UNIT_s = 6,
28
+ CA_DATETIME_UNIT_ms = 7,
29
+ CA_DATETIME_UNIT_us = 8,
30
+ CA_DATETIME_UNIT_ns = 9, /* pandas default */
31
+ CA_DATETIME_UNIT_ps = 10,
32
+ CA_DATETIME_UNIT_fs = 11,
33
+ CA_DATETIME_UNIT_as = 12
34
+ };
35
+
36
+ typedef struct {
37
+ /* === CAView prefix === */
38
+ int16_t obj_type;
39
+ int8_t data_type; /* fixed to CA_INT64 */
40
+ int8_t ndim;
41
+ int32_t flags; /* CA_FLAG_IS_FACE set */
42
+ ca_size_t bytes; /* fixed to sizeof(int64_t) */
43
+ ca_size_t elements;
44
+ ca_size_t *dim;
45
+ char *ptr;
46
+ CArray *mask;
47
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
48
+ CArray *parent;
49
+ uint32_t attach;
50
+ uint8_t nosync;
51
+ /* === Face tail === */
52
+ int8_t unit; /* CA_DATETIME_UNIT_* (the tick base) */
53
+ int64_t count; /* tick multiplier N (tick = count * base) */
54
+ } CATime;
55
+
56
+ static size_t
57
+ ca_time_dsize (const void *ap)
58
+ {
59
+ const CATime *ca = (const CATime *) ap;
60
+ return sizeof(CATime) + ca->ndim * sizeof(ca_size_t);
61
+ }
62
+
63
+ /* Pool framework hooks. CATime owns a single ndim-sized tail
64
+ (dim) in the _pool buffer. No alloc collapse (1 tail), but routes the
65
+ class onto the uniform pool alloc/free discipline (ca_array_alloc /
66
+ ca_array_free). */
67
+ static size_t
68
+ ca_time_pool_bytes (int8_t ndim)
69
+ {
70
+ ca_size_t n = (ndim > 0) ? ndim : 1;
71
+ return (size_t) n * sizeof(ca_size_t);
72
+ }
73
+
74
+ static void
75
+ ca_time_pool_init (void *ap, int8_t ndim)
76
+ {
77
+ CATime *ca = (CATime *) ap;
78
+ ca->dim = (ca_size_t *) ca->_pool;
79
+ }
80
+
81
+ const rb_data_type_t catime_data_type = {
82
+ .parent = &caface_data_type,
83
+ .wrap_struct_name = "CATime",
84
+ .function = {
85
+ .dmark = ca_mark,
86
+ .dfree = ca_free,
87
+ .dsize = ca_time_dsize,
88
+ .dcompact = NULL
89
+ },
90
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
91
+ };
92
+
93
+ static int8_t CA_OBJ_TIME;
94
+ static VALUE rb_cCATime;
95
+ static VALUE rb_cCATimeElement;
96
+
97
+ /* forward decls (defined later in the file) */
98
+ int8_t ca_time_unit_value (VALUE sym);
99
+ VALUE ca_time_unit_to_symbol (int8_t unit);
100
+ VALUE ca_time_resolution (int64_t count, int8_t unit);
101
+ void ca_time_extract_unit (VALUE unit, int8_t *base, int64_t *count);
102
+
103
+ /* CATime::Element as a C TypedData struct: storing value + unit in
104
+ the struct avoids per-cell Ruby Integer boxing and Ruby `initialize`
105
+ dispatch on the fetch hot path. value is the raw parent int64 (= the
106
+ tick index under self's resolution); unit is the CA_DATETIME_UNIT_*
107
+ base enum and count is the tick multiplier (tick = count * base). */
108
+ typedef struct {
109
+ int64_t value;
110
+ int8_t unit;
111
+ int64_t count;
112
+ } CATimeElement;
113
+
114
+ static size_t
115
+ ca_time_element_dsize (const void *ap)
116
+ {
117
+ (void) ap;
118
+ return sizeof(CATimeElement);
119
+ }
120
+
121
+ static void
122
+ ca_time_element_free (void *ap)
123
+ {
124
+ if (ap) xfree(ap);
125
+ }
126
+
127
+ const rb_data_type_t catime_element_data_type = {
128
+ .wrap_struct_name = "CATime::Element",
129
+ .function = {
130
+ .dmark = NULL,
131
+ .dfree = ca_time_element_free,
132
+ .dsize = ca_time_element_dsize,
133
+ },
134
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
135
+ };
136
+
137
+ static VALUE
138
+ rb_ca_time_element_s_allocate (VALUE klass)
139
+ {
140
+ CATimeElement *s;
141
+ return TypedData_Make_Struct(klass, CATimeElement,
142
+ &catime_element_data_type, s);
143
+ }
144
+
145
+ static VALUE
146
+ rb_ca_time_element_initialize (VALUE self, VALUE value, VALUE unit)
147
+ {
148
+ CATimeElement *s;
149
+ TypedData_Get_Struct(self, CATimeElement,
150
+ &catime_element_data_type, s);
151
+ s->value = NUM2LL(value);
152
+ ca_time_extract_unit(unit, &s->unit, &s->count);
153
+ return self;
154
+ }
155
+
156
+ static VALUE
157
+ rb_ca_time_element_value (VALUE self)
158
+ {
159
+ CATimeElement *s;
160
+ TypedData_Get_Struct(self, CATimeElement,
161
+ &catime_element_data_type, s);
162
+ return LL2NUM(s->value);
163
+ }
164
+
165
+ /* unit → CATime::Resolution(count, base) */
166
+ static VALUE
167
+ rb_ca_time_element_unit (VALUE self)
168
+ {
169
+ CATimeElement *s;
170
+ TypedData_Get_Struct(self, CATimeElement,
171
+ &catime_element_data_type, s);
172
+ return ca_time_resolution(s->count, s->unit);
173
+ }
174
+
175
+ /* ------------------------------------------------------------------- */
176
+
177
+ int
178
+ ca_time_setup (CATime *ca, CArray *parent, int8_t unit, int64_t count)
179
+ {
180
+ if ( parent->data_type != CA_INT64 ) {
181
+ rb_raise(rb_eTypeError,
182
+ "CATime requires int64 storage (parent.data_type != CA_INT64)");
183
+ }
184
+
185
+ ca->obj_type = CA_OBJ_TIME;
186
+ /* The surface data_type is CA_FIXLEN, not CA_INT64: this routes
187
+ mkkernel dispatch onto the ca_*_not_implement stubs so numeric
188
+ kernels are gated off automatically. bytes stays at 8 to match the
189
+ parent int64 storage. */
190
+ ca->data_type = CA_FIXLEN;
191
+ /* ORDERABLE: int64 storage order == datetime <=> order, so sort family may
192
+ descend to storage. NOT COMPARABLE: an external query may carry a
193
+ different unit, so raw storage compare against a query is unsafe. */
194
+ ca->flags = CA_FLAG_IS_FACE | CA_FLAG_FACE_ORDERABLE_STORAGE;
195
+ ca->ndim = parent->ndim;
196
+ ca->bytes = sizeof(int64_t);
197
+ ca->elements = parent->elements;
198
+ ca->ptr = NULL;
199
+ ca->mask = NULL;
200
+ if ( ! ca->_pool ) {
201
+ ca->dim = ALLOC_N(ca_size_t, parent->ndim);
202
+ }
203
+ memcpy(ca->dim, parent->dim, sizeof(ca_size_t) * parent->ndim);
204
+
205
+ ca->parent = parent;
206
+ ca->attach = 0;
207
+ ca->nosync = 0;
208
+
209
+ ca->unit = unit;
210
+ ca->count = count;
211
+
212
+ if ( ca_has_mask(parent) ) {
213
+ ca_create_mask((CArray *) ca);
214
+ }
215
+
216
+ if ( ca_is_scalar(parent) ) {
217
+ ca_set_flag(ca, CA_FLAG_SCALAR);
218
+ }
219
+
220
+ if ( ca_test_flag(parent, CA_FLAG_READ_ONLY) ) {
221
+ ca_set_flag(ca, CA_FLAG_READ_ONLY);
222
+ }
223
+
224
+ return 0;
225
+ }
226
+
227
+ CATime *
228
+ ca_time_new (CArray *parent, int8_t unit, int64_t count)
229
+ {
230
+ CATime *ca = (CATime *) ca_array_alloc(CA_OBJ_TIME, parent->ndim);
231
+ ca_time_setup(ca, parent, unit, count);
232
+ return ca;
233
+ }
234
+
235
+ static void
236
+ free_ca_time (void *ap)
237
+ {
238
+ CATime *ca = (CATime *) ap;
239
+ if ( ca != NULL ) {
240
+ ca_free(ca->mask);
241
+ if ( ca->_pool ) {
242
+ ca_array_free(ca); /* dim lives in _pool */
243
+ }
244
+ else {
245
+ xfree(ca->dim);
246
+ xfree(ca);
247
+ }
248
+ }
249
+ }
250
+
251
+ /* ------------------------------------------------------------------- */
252
+
253
+ static void *
254
+ ca_time_func_clone (void *ap)
255
+ {
256
+ CATime *ca = (CATime *) ap;
257
+ return ca_time_new(ca->parent, ca->unit, ca->count);
258
+ }
259
+
260
+ static void
261
+ ca_time_func_allocate (void *ap)
262
+ {
263
+ CATime *ca = (CATime *) ap;
264
+ /* alias: parent attach + alias parent->ptr (= no malloc; Face has identical data) */
265
+ ca_attach(ca->parent);
266
+ ca->ptr = ca->parent->ptr;
267
+ }
268
+
269
+ static void
270
+ ca_time_func_create_mask (void *ap)
271
+ {
272
+ CATime *ca = (CATime *) ap;
273
+ ca_update_mask(ca->parent);
274
+ if ( ! ca->parent->mask ) {
275
+ ca_create_mask(ca->parent);
276
+ }
277
+ ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
278
+ CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
279
+ }
280
+
281
+ ca_operation_function_t ca_time_func = {
282
+ -1, /* CA_OBJ_TIME — filled by ca_install_obj_type */
283
+ CA_VIEW_ARRAY,
284
+ free_ca_time,
285
+ ca_time_func_clone,
286
+ ca_time_func_allocate,
287
+ ca_face_attach,
288
+ ca_face_sync,
289
+ ca_face_detach,
290
+ ca_face_fill_data,
291
+ ca_time_func_create_mask,
292
+ ca_face_xfer_index,
293
+ ca_face_xfer_addrs,
294
+ NULL, /* fold_stride: identity Face is not foldable */
295
+ ca_face_xfer_stride,
296
+ ca_face_xfer_all,
297
+ .fill_addrs = ca_face_fill_addrs,
298
+ .fill_stride = ca_face_fill_stride,
299
+ };
300
+
301
+ /* ------------------------------------------------------------------- */
302
+
303
+ /* parse unit symbol → enum (also referenced by CATimedelta) */
304
+ int8_t
305
+ ca_time_unit_value (VALUE sym)
306
+ {
307
+ if ( NIL_P(sym) ) return CA_DATETIME_UNIT_ns; /* default: pandas-style */
308
+ if ( TYPE(sym) != T_SYMBOL ) {
309
+ rb_raise(rb_eArgError, "unit must be a Symbol (e.g. :ns, :us, :s, :D)");
310
+ }
311
+ ID id = SYM2ID(sym);
312
+ if ( id == rb_intern("Y") ) return CA_DATETIME_UNIT_Y;
313
+ if ( id == rb_intern("M") ) return CA_DATETIME_UNIT_M;
314
+ if ( id == rb_intern("W") ) return CA_DATETIME_UNIT_W;
315
+ if ( id == rb_intern("D") ) return CA_DATETIME_UNIT_D;
316
+ if ( id == rb_intern("h") ) return CA_DATETIME_UNIT_h;
317
+ if ( id == rb_intern("m") ) return CA_DATETIME_UNIT_m;
318
+ if ( id == rb_intern("s") ) return CA_DATETIME_UNIT_s;
319
+ if ( id == rb_intern("ms") ) return CA_DATETIME_UNIT_ms;
320
+ if ( id == rb_intern("us") ) return CA_DATETIME_UNIT_us;
321
+ if ( id == rb_intern("ns") ) return CA_DATETIME_UNIT_ns;
322
+ if ( id == rb_intern("ps") ) return CA_DATETIME_UNIT_ps;
323
+ if ( id == rb_intern("fs") ) return CA_DATETIME_UNIT_fs;
324
+ if ( id == rb_intern("as") ) return CA_DATETIME_UNIT_as;
325
+ rb_raise(rb_eArgError, "unknown datetime unit: %"PRIsVALUE, sym);
326
+ return 0; /* unreachable */
327
+ }
328
+
329
+ VALUE
330
+ ca_time_unit_to_symbol (int8_t unit)
331
+ {
332
+ switch (unit) {
333
+ case CA_DATETIME_UNIT_Y: return ID2SYM(rb_intern("Y"));
334
+ case CA_DATETIME_UNIT_M: return ID2SYM(rb_intern("M"));
335
+ case CA_DATETIME_UNIT_W: return ID2SYM(rb_intern("W"));
336
+ case CA_DATETIME_UNIT_D: return ID2SYM(rb_intern("D"));
337
+ case CA_DATETIME_UNIT_h: return ID2SYM(rb_intern("h"));
338
+ case CA_DATETIME_UNIT_m: return ID2SYM(rb_intern("m"));
339
+ case CA_DATETIME_UNIT_s: return ID2SYM(rb_intern("s"));
340
+ case CA_DATETIME_UNIT_ms: return ID2SYM(rb_intern("ms"));
341
+ case CA_DATETIME_UNIT_us: return ID2SYM(rb_intern("us"));
342
+ case CA_DATETIME_UNIT_ns: return ID2SYM(rb_intern("ns"));
343
+ case CA_DATETIME_UNIT_ps: return ID2SYM(rb_intern("ps"));
344
+ case CA_DATETIME_UNIT_fs: return ID2SYM(rb_intern("fs"));
345
+ case CA_DATETIME_UNIT_as: return ID2SYM(rb_intern("as"));
346
+ }
347
+ return Qnil;
348
+ }
349
+
350
+ /* Build a CATime::Resolution(count, base) descriptor. Shared by
351
+ CATime and CATimedelta (the descriptor type is nested under
352
+ CATime and carries no group-specific state). */
353
+ VALUE
354
+ ca_time_resolution (int64_t count, int8_t unit)
355
+ {
356
+ VALUE rescls = rb_const_get(rb_cCATime, rb_intern("Resolution"));
357
+ return rb_funcall(rescls, rb_intern("new"), 2,
358
+ LL2NUM(count), ca_time_unit_to_symbol(unit));
359
+ }
360
+
361
+ /* Normalize a unit spec (Symbol / String / Resolution / nil) into a base
362
+ enum + count multiplier. nil defaults to (1, :ns); a bare Symbol is the
363
+ count-1 shorthand; a String / Resolution routes through Resolution.parse. */
364
+ void
365
+ ca_time_extract_unit (VALUE unit, int8_t *base, int64_t *count)
366
+ {
367
+ if ( NIL_P(unit) ) {
368
+ *base = CA_DATETIME_UNIT_ns;
369
+ *count = 1;
370
+ return;
371
+ }
372
+ if ( TYPE(unit) == T_SYMBOL ) {
373
+ *base = ca_time_unit_value(unit);
374
+ *count = 1;
375
+ return;
376
+ }
377
+ VALUE rescls = rb_const_get(rb_cCATime, rb_intern("Resolution"));
378
+ VALUE res = RTEST(rb_obj_is_kind_of(unit, rescls))
379
+ ? unit
380
+ : rb_funcall(rescls, rb_intern("parse"), 1, unit);
381
+ *base = ca_time_unit_value(rb_funcall(res, rb_intern("base"), 0));
382
+ *count = NUM2LL(rb_funcall(res, rb_intern("count"), 0));
383
+ }
384
+
385
+ /* CATime.wrap(int64_array, base_enum, count) — zero-copy Face wrap.
386
+ The public unit-spec normalization (Symbol / String / Resolution) is done
387
+ on the Ruby side; this primitive takes the resolved base enum + count. */
388
+ VALUE
389
+ rb_ca_time_wrap (VALUE parent_val, int8_t unit, int64_t count)
390
+ {
391
+ volatile VALUE obj;
392
+ CArray *parent;
393
+ CATime *ca;
394
+
395
+ rb_check_carray_object(parent_val);
396
+ TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
397
+
398
+ ca = ca_time_new(parent, unit, count);
399
+ obj = ca_wrap_struct(ca);
400
+ rb_ca_set_parent(obj, parent_val);
401
+ return obj;
402
+ }
403
+
404
+ /* __wrap__(raw, unit_spec) — primitive; unit_spec is Symbol / String /
405
+ Resolution / nil (normalized here). */
406
+ static VALUE
407
+ rb_ca_time_wrap_method (VALUE klass, VALUE raw, VALUE unit_spec)
408
+ {
409
+ int8_t base;
410
+ int64_t count;
411
+ (void) klass;
412
+ ca_time_extract_unit(unit_spec, &base, &count);
413
+ return rb_ca_time_wrap(raw, base, count);
414
+ }
415
+
416
+ /* CATime#unit → CATime::Resolution(count, base) */
417
+ static VALUE
418
+ rb_ca_time_unit (VALUE self)
419
+ {
420
+ CATime *ca;
421
+ TypedData_Get_Struct(self, CATime, &catime_data_type, ca);
422
+ return ca_time_resolution(ca->count, ca->unit);
423
+ }
424
+
425
+ /* storage_to_scalar implemented in C to avoid per-cell Ruby method dispatch
426
+ on the fetch hot path. CAREFUL: there must be no Ruby `storage_to_scalar`
427
+ def in lib/carray/time.rb — require order would let a Ruby version
428
+ shadow this C method (the Ruby `scalar_to_storage` write hook is a
429
+ distinct method and does not collide).
430
+ Since the Face surface is CA_FIXLEN, fetch delivers an 8-byte raw
431
+ String. Decode it as the parent int64 (= storage), then construct
432
+ CATime::Element(epoch, unit). */
433
+ static VALUE
434
+ rb_ca_time_storage_to_scalar (VALUE self, VALUE raw)
435
+ {
436
+ CATime *ca;
437
+ CATimeElement *s;
438
+ VALUE scalar_obj;
439
+ int64_t epoch;
440
+
441
+ TypedData_Get_Struct(self, CATime, &catime_data_type, ca);
442
+
443
+ if ( TYPE(raw) == T_STRING ) {
444
+ if ( RSTRING_LEN(raw) != (long) sizeof(int64_t) ) {
445
+ rb_raise(rb_eArgError,
446
+ "CATime#storage_to_scalar: expected %lu bytes, got %ld",
447
+ (unsigned long) sizeof(int64_t), RSTRING_LEN(raw));
448
+ }
449
+ memcpy(&epoch, RSTRING_PTR(raw), sizeof(int64_t));
450
+ }
451
+ else {
452
+ epoch = NUM2LL(raw);
453
+ }
454
+
455
+ /* Direct alloc + struct field write — no LL2NUM, no rb_class_new_instance,
456
+ no Ruby initialize dispatch. */
457
+ scalar_obj = TypedData_Make_Struct(rb_cCATimeElement,
458
+ CATimeElement,
459
+ &catime_element_data_type, s);
460
+ s->value = epoch;
461
+ s->unit = ca->unit;
462
+ s->count = ca->count;
463
+ return scalar_obj;
464
+ }
465
+
466
+ static VALUE
467
+ rb_ca_time_s_allocate (VALUE klass)
468
+ {
469
+ CATime *ca;
470
+ return TypedData_Make_Struct(klass, CATime,
471
+ &catime_data_type, ca);
472
+ }
473
+
474
+ static VALUE
475
+ rb_ca_time_initialize_copy (VALUE self, VALUE other)
476
+ {
477
+ CATime *ca, *cs;
478
+ TypedData_Get_Struct(self, CATime, &catime_data_type, ca);
479
+ TypedData_Get_Struct(other, CATime, &catime_data_type, cs);
480
+ if ( ca_func[CA_OBJ_TIME].pool_init ) {
481
+ ca_array_pool_alloc(ca, CA_OBJ_TIME, cs->parent->ndim);
482
+ }
483
+ ca_time_setup(ca, cs->parent, cs->unit, cs->count);
484
+ return self;
485
+ }
486
+
487
+ /* Face state homogeneity check — two CATime instances are
488
+ compatible iff their resolution (base + count) matches. */
489
+ static int
490
+ ca_time_state_compatible (CArray *a, CArray *b)
491
+ {
492
+ CATime *da = (CATime *) a;
493
+ CATime *db = (CATime *) b;
494
+ return ( da->unit == db->unit && da->count == db->count ) ? 1 : 0;
495
+ }
496
+
497
+ void
498
+ Init_ca_obj_time (void)
499
+ {
500
+ rb_cCATime = rb_define_class("CATime", rb_cCAFace);
501
+
502
+ ca_time_func.struct_size = sizeof(CATime);
503
+ ca_time_func.pool_bytes = ca_time_pool_bytes;
504
+ ca_time_func.pool_init = ca_time_pool_init;
505
+
506
+ CA_OBJ_TIME = ca_install_obj_type(rb_cCATime,
507
+ &catime_data_type,
508
+ rb_cCArrayMask,
509
+ &carray_mask_data_type,
510
+ &ca_time_func, sizeof(ca_time_func));
511
+ rb_define_const(rb_cObject, "CA_OBJ_TIME", INT2NUM(CA_OBJ_TIME));
512
+
513
+ rb_define_alloc_func(rb_cCATime, rb_ca_time_s_allocate);
514
+ rb_define_method(rb_cCATime, "initialize_copy",
515
+ rb_ca_time_initialize_copy, 1);
516
+
517
+ rb_define_singleton_method(rb_cCATime, "__wrap__",
518
+ rb_ca_time_wrap_method, 2);
519
+ rb_define_method(rb_cCATime, "unit", rb_ca_time_unit, 0);
520
+ rb_define_method(rb_cCATime, "storage_to_scalar",
521
+ rb_ca_time_storage_to_scalar, 1);
522
+ /* Registers the C-level fast path so CA_FACE_STORAGE_TO_SCALAR_IF_FACE can
523
+ skip rb_funcall on the hot path. */
524
+ ca_face_register_storage_to_scalar(CA_OBJ_TIME,
525
+ rb_ca_time_storage_to_scalar);
526
+ ca_face_register_state_compatible(CA_OBJ_TIME,
527
+ ca_time_state_compatible);
528
+ /* unit is pure metadata (= no per-parent buffer), so the Face wrap can
529
+ be carried across multi-parent constructions like CAStack
530
+ (portable = 1). */
531
+ ca_face_register_state_portable(CA_OBJ_TIME, 1);
532
+
533
+ /* CATime::Element as a C-backed TypedData class. The Ruby-side
534
+ definition in lib/carray/time.rb keeps the Comparable include +
535
+ to_time / to_s / inspect / <=> / == methods; the C side owns the
536
+ storage (int64 value + int8 unit) and the allocator + initialize +
537
+ value + unit accessors. */
538
+ rb_cCATimeElement = rb_define_class_under(rb_cCATime,
539
+ "Element", rb_cObject);
540
+ rb_define_alloc_func(rb_cCATimeElement,
541
+ rb_ca_time_element_s_allocate);
542
+ rb_define_method(rb_cCATimeElement, "initialize",
543
+ rb_ca_time_element_initialize, 2);
544
+ rb_define_method(rb_cCATimeElement, "value",
545
+ rb_ca_time_element_value, 0);
546
+ rb_define_method(rb_cCATimeElement, "unit",
547
+ rb_ca_time_element_unit, 0);
548
+ }