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
@@ -1,14 +1,18 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- ca_obj_bitarray.c
3
+ CABitarray view: fan every parent cell out into 8 * parent->bytes
4
+ boolean cells, one per bit. The view adds a trailing bit axis of
5
+ length `bitlen = parent->bytes * 8` after the parent's own axes.
4
6
 
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
7
+ Big-endian hosts (non-fixlen parents only) walk parent bytes in
8
+ reverse within each element so the bit axis reflects network byte
9
+ order regardless of host endianness. Single-byte parents are
10
+ linear in either case.
8
11
 
9
12
  ---------------------------------------------------------------------------- */
10
13
 
11
14
  #include "carray.h"
15
+ #include "carray_internal.h" /* ca_bit_pack / ca_bit_unpack */
12
16
 
13
17
  typedef struct {
14
18
  int16_t obj_type;
@@ -20,6 +24,7 @@ typedef struct {
20
24
  ca_size_t *dim;
21
25
  char *ptr;
22
26
  CArray *mask;
27
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
23
28
  CArray *parent;
24
29
  uint32_t attach;
25
30
  uint8_t nosync;
@@ -28,13 +33,37 @@ typedef struct {
28
33
  ca_size_t bitlen;
29
34
  } CABitarray;
30
35
 
36
+ static size_t
37
+ ca_bitarray_dsize (const void *ap)
38
+ {
39
+ const CABitarray *ca = (const CABitarray *) ap;
40
+ return sizeof(CABitarray) + ca->ndim * sizeof(ca_size_t);
41
+ }
42
+
43
+ /* Pool framework hooks: single ndim-sized tail (dim) in the _pool
44
+ buffer. See ca_array_pool.c for the shared alloc/free discipline.
45
+ CABitarray's ndim is parent->ndim + 1 (the trailing bit axis). */
46
+ static size_t
47
+ ca_bitarray_pool_bytes (int8_t ndim)
48
+ {
49
+ ca_size_t n = (ndim > 0) ? ndim : 1;
50
+ return (size_t) n * sizeof(ca_size_t);
51
+ }
52
+
53
+ static void
54
+ ca_bitarray_pool_init (void *ap, int8_t ndim)
55
+ {
56
+ CABitarray *ca = (CABitarray *) ap;
57
+ ca->dim = (ca_size_t *) ca->_pool;
58
+ }
59
+
31
60
  const rb_data_type_t cabitarray_data_type = {
32
- .parent = &cavirtual_data_type,
61
+ .parent = &caview_data_type,
33
62
  .wrap_struct_name = "CABitarray",
34
63
  .function = {
35
64
  .dmark = ca_mark,
36
65
  .dfree = ca_free,
37
- .dsize = NULL,
66
+ .dsize = ca_bitarray_dsize,
38
67
  .dcompact = NULL
39
68
  },
40
69
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -44,11 +73,6 @@ static int8_t CA_OBJ_BITARRAY;
44
73
 
45
74
  static VALUE rb_cCABitarray;
46
75
 
47
- /* yard:
48
- class CABitArray < CAVirtual # :nodoc:
49
- end
50
- */
51
-
52
76
  static uint8_t bits[8] = {
53
77
  1,
54
78
  2,
@@ -68,8 +92,6 @@ ca_bitarray_setup (CABitarray *ca, CArray *parent)
68
92
  int8_t ndim;
69
93
  ca_size_t bitlen, elements;
70
94
 
71
- /* check arguments */
72
-
73
95
  if ( ca_is_complex_type(parent) || ( ca_is_object_type(parent) ) ) {
74
96
  rb_raise(rb_eCADataTypeError, "invalid data_type for bitarray");
75
97
  }
@@ -86,7 +108,9 @@ ca_bitarray_setup (CABitarray *ca, CArray *parent)
86
108
  ca->elements = elements;
87
109
  ca->ptr = NULL;
88
110
  ca->mask = NULL;
89
- ca->dim = ALLOC_N(ca_size_t, ndim);
111
+ if ( ! ca->_pool ) {
112
+ ca->dim = ALLOC_N(ca_size_t, ndim);
113
+ }
90
114
 
91
115
  ca->parent = parent;
92
116
  ca->attach = 0;
@@ -108,7 +132,7 @@ ca_bitarray_setup (CABitarray *ca, CArray *parent)
108
132
  CABitarray *
109
133
  ca_bitarray_new (CArray *parent)
110
134
  {
111
- CABitarray *ca = ALLOC(CABitarray);
135
+ CABitarray *ca = (CABitarray *) ca_array_alloc(CA_OBJ_BITARRAY, parent->ndim + 1);
112
136
  ca_bitarray_setup(ca, parent);
113
137
  return ca;
114
138
  }
@@ -119,8 +143,13 @@ free_ca_bitarray (void *ap)
119
143
  CABitarray *ca = (CABitarray *) ap;
120
144
  if ( ca != NULL ) {
121
145
  ca_free(ca->mask);
122
- xfree(ca->dim);
123
- xfree(ca);
146
+ if ( ca->_pool ) {
147
+ ca_array_free(ca); /* dim lives in _pool */
148
+ }
149
+ else {
150
+ xfree(ca->dim);
151
+ xfree(ca);
152
+ }
124
153
  }
125
154
  }
126
155
 
@@ -137,40 +166,21 @@ ca_bitarray_func_clone (void *ap)
137
166
  return ca_bitarray_new(ca->parent);
138
167
  }
139
168
 
140
- static char *
141
- ca_bitarray_func_ptr_at_addr (void *ap, ca_size_t addr)
142
- {
143
- CABitarray *ca = (CABitarray *) ap;
144
- if ( ! ca->ptr ) {
145
- rb_raise(rb_eRuntimeError, "[BUG] ");
146
- return NULL;
147
- }
148
- else {
149
- return ca->ptr + ca->bytes * addr;
150
- }
151
- }
152
-
153
- static char *
154
- ca_bitarray_func_ptr_at_index (void *ap, ca_size_t *idx)
155
- {
156
- CABitarray *ca = (CABitarray *) ap;
157
- if ( ! ca->ptr ) {
158
- rb_raise(rb_eRuntimeError, "[BUG]");
159
- return NULL;
160
- }
161
- else {
162
- return ca_func[CA_OBJ_ARRAY].ptr_at_index(ca, idx);
163
- }
164
- }
165
-
169
+ /* Per-cell get / put: fetch the parent cell into a scratch buffer,
170
+ locate the target byte + bit (major / minor), and either extract
171
+ the bit into the output or RMW the parent cell. Big-endian
172
+ non-fixlen parents flip the major-byte index so the bit axis
173
+ observes network byte order. */
166
174
  static void
167
- ca_bitarray_func_fetch_index (void *ap, ca_size_t *idx, void *ptr)
175
+ ca_bitarray_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
168
176
  {
169
177
  CABitarray *ca = (CABitarray *) ap;
170
178
  ca_size_t bytes = ca->parent->bytes;
171
179
  ca_size_t offset = idx[ca->ndim-1];
172
180
  ca_size_t major, minor;
173
-
181
+ uint8_t sbuf[32];
182
+ uint8_t *v;
183
+
174
184
  if ( ca_endian == CA_BIG_ENDIAN &&
175
185
  ca->parent->bytes != 1 &&
176
186
  ( ! ca_is_fixlen_type(ca->parent) ) ) {
@@ -179,65 +189,191 @@ ca_bitarray_func_fetch_index (void *ap, ca_size_t *idx, void *ptr)
179
189
  else {
180
190
  major = offset / 8;
181
191
  }
182
-
183
192
  minor = offset % 8;
184
193
 
185
- if ( ca->parent->bytes <= 32 ) {
186
- uint8_t v[32];
194
+ v = (ca->parent->bytes <= 32) ? sbuf : xmalloc(ca->parent->bytes);
195
+
196
+ if ( dir == CA_XFER_GET ) {
187
197
  ca_fetch_index(ca->parent, idx, v);
188
- *(char*) ptr = ( ( v[major] & bits[minor] ) != 0 );
198
+ *(char*) data = ( ( v[major] & bits[minor] ) != 0 );
189
199
  }
190
200
  else {
191
- uint8_t *v = malloc_with_check(ca->parent->bytes);
201
+ uint8_t test = *(uint8_t *) data;
192
202
  ca_fetch_index(ca->parent, idx, v);
193
- *(char*) ptr = ( ( v[major] & bits[minor] ) != 0 );
194
- free(v);
203
+ if ( test ) {
204
+ v[major] = ( v[major] & ~bits[minor] ) | bits[minor];
205
+ }
206
+ else {
207
+ v[major] = ( v[major] & ~bits[minor] );
208
+ }
209
+ ca_store_index(ca->parent, idx, v);
195
210
  }
211
+
212
+ if ( v != sbuf ) xfree(v);
196
213
  }
197
214
 
215
+ /* Batched gather / scatter.
216
+ *
217
+ * CAREFUL: the trailing bit axis means many view cells (different
218
+ * bits of one byte) map to the SAME parent cell. GET batches the
219
+ * parent gather freely — read-only sharing is harmless. Arbitrary
220
+ * PUT must stay per-cell (a batched scatter with duplicate parent
221
+ * addresses would drop earlier bit writes into the same byte).
222
+ *
223
+ * Fast path: when `addrs` covers the whole view sequentially and
224
+ * the effective attached parent (via identity compose-fold) is
225
+ * live, drive ca_bit_unpack / ca_bit_pack directly against
226
+ * parent->ptr. Whole-view PUT rewrites every bit of every parent
227
+ * byte, so no RMW is needed on that branch. */
198
228
  static void
199
- ca_bitarray_func_store_index (void *ap, ca_size_t *idx, void *ptr)
229
+ ca_bitarray_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
230
+ void *data, int dir)
200
231
  {
201
232
  CABitarray *ca = (CABitarray *) ap;
202
- uint8_t test = *(uint8_t *) ptr;
203
- ca_size_t offset = idx[ca->ndim-1];
204
- ca_size_t bytes = ca->parent->bytes;
205
- ca_size_t major, minor;
206
-
207
- if ( ca_endian == CA_BIG_ENDIAN &&
208
- ca->parent->bytes != 1 &&
209
- ( ! ca_is_fixlen_type(ca->parent) ) ) {
210
- major = bytes - 1 - offset / 8;
211
- }
212
- else {
213
- major = offset / 8;
233
+ char *d = (char *) data;
234
+ CArray *parent = ca->parent;
235
+ ca_size_t pbytes = parent->bytes;
236
+ ca_size_t i, base;
237
+ int8_t k;
238
+
239
+ if ( n == ca->elements
240
+ && ca_xfer_addrs_is_sequential_run(n, addrs, &base) && base == 0 ) {
241
+ CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
242
+ if ( eff_parent->ptr
243
+ && eff_parent->elements == parent->elements
244
+ && eff_parent->bytes == parent->bytes ) {
245
+ int multibyte_byteswap = ( ca_endian == CA_BIG_ENDIAN
246
+ && pbytes != 1
247
+ && ( ! ca_is_fixlen_type(parent) ) );
248
+ if ( dir == CA_XFER_GET ) {
249
+ ca_bit_unpack((const uint8_t *) eff_parent->ptr,
250
+ parent->elements, pbytes,
251
+ multibyte_byteswap, (boolean8_t *) d);
252
+ } else {
253
+ /* Whole-view PUT rewrites every bit, so ca_bit_pack replaces
254
+ the whole parent byte with no RMW. */
255
+ ca_bit_pack((const boolean8_t *) d,
256
+ parent->elements, pbytes,
257
+ multibyte_byteswap, (uint8_t *) eff_parent->ptr);
258
+ }
259
+ return;
260
+ }
214
261
  }
215
262
 
216
- minor = offset % 8;
263
+ if ( dir == CA_XFER_PUT ) {
264
+ for (i = 0; i < n; i++) {
265
+ ca_size_t idx[CA_RANK_MAX];
266
+ ca_addr2index((CArray *) ca, addrs[i], idx);
267
+ ca_bitarray_func_xfer_index(ca, idx, d + i * ca->bytes, CA_XFER_PUT);
268
+ }
269
+ return;
270
+ }
217
271
 
218
- if ( ca->parent->bytes <= 32 ) {
219
- uint8_t v[32];
220
- ca_fetch_index(ca->parent, idx, v);
221
- if ( test ) {
222
- v[major] = ( v[major] & ~bits[minor] ) | bits[minor];
272
+ {
273
+ ca_size_t *paddrs;
274
+ ca_size_t *offs;
275
+ char *v;
276
+ volatile VALUE h1, h2, h3;
277
+ paddrs = ALLOCV_N(ca_size_t, h1, n);
278
+ offs = ALLOCV_N(ca_size_t, h2, n);
279
+ v = ALLOCV_N(char, h3, n * pbytes);
280
+ for (i = 0; i < n; i++) {
281
+ ca_size_t idx[CA_RANK_MAX], pidx[CA_RANK_MAX];
282
+ ca_addr2index((CArray *) ca, addrs[i], idx);
283
+ for (k = 0; k < ca->parent->ndim; k++) pidx[k] = idx[k];
284
+ paddrs[i] = ca_index2addr(ca->parent, pidx);
285
+ offs[i] = idx[ca->ndim - 1];
223
286
  }
224
- else {
225
- v[major] = ( v[major] & ~bits[minor] );
287
+ ca_xfer_addrs(ca->parent, n, paddrs, v, CA_XFER_GET);
288
+ for (i = 0; i < n; i++) {
289
+ ca_size_t offset = offs[i];
290
+ ca_size_t major, minor;
291
+ if ( ca_endian == CA_BIG_ENDIAN && pbytes != 1 &&
292
+ ( ! ca_is_fixlen_type(ca->parent) ) ) {
293
+ major = pbytes - 1 - offset / 8;
294
+ }
295
+ else {
296
+ major = offset / 8;
297
+ }
298
+ minor = offset % 8;
299
+ *(char *)(d + i * ca->bytes) =
300
+ ( ( ((uint8_t *)(v + i * pbytes))[major] & bits[minor] ) != 0 );
226
301
  }
227
- ca_store_index(ca->parent, idx, v);
302
+ ALLOCV_END(h3);
303
+ ALLOCV_END(h2);
304
+ ALLOCV_END(h1);
228
305
  }
229
- else {
230
- char *v = malloc_with_check(ca->parent->bytes);
231
- ca_fetch_index(ca->parent, idx, v);
232
- if ( test ) {
233
- v[major] = ( v[major] & ~bits[minor] ) | bits[minor];
306
+ }
307
+
308
+ /* CABitarray is a per-cell bit transform with no STRIDE structure
309
+ to preserve, so a generic strided region reduces to the view's
310
+ own flat address list. Whole-view requests short-circuit
311
+ directly through ca_bit_unpack / ca_bit_pack (same fast path as
312
+ xfer_addrs); anything else materialises the address list and
313
+ delegates to the view's own xfer_addrs. */
314
+ static void
315
+ ca_bitarray_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
316
+ ca_size_t *strides, void *data, int dir)
317
+ {
318
+ CABitarray *ca = (CABitarray *) ap;
319
+ int8_t ndim = ca->ndim;
320
+ ca_size_t native[CA_RANK_MAX], idx[CA_RANK_MAX];
321
+ ca_size_t *vaddrs;
322
+ ca_size_t base = 0, n = 1, i, s;
323
+ int8_t k;
324
+ volatile VALUE holder;
325
+
326
+ s = ca->bytes;
327
+ for (k = ndim - 1; k >= 0; k--) { native[k] = s; s *= ca->dim[k]; }
328
+ for (k = 0; k < ndim; k++) { base += starts[k] * native[k]; n *= counts[k]; }
329
+
330
+ /* Whole-view fast path: starts == 0, counts == view.dim, strides
331
+ == native row-major. Skips the vaddrs[] odometer and delegates
332
+ straight to the bit primitive. */
333
+ {
334
+ int is_whole_view = (n == ca->elements);
335
+ if ( is_whole_view ) {
336
+ for ( k = 0; k < ndim; k++ ) {
337
+ if ( starts[k] != 0 || counts[k] != ca->dim[k] || strides[k] != native[k] ) {
338
+ is_whole_view = 0;
339
+ break;
340
+ }
341
+ }
234
342
  }
235
- else {
236
- v[major] = ( v[major] & ~bits[minor] );
343
+ if ( is_whole_view ) {
344
+ CArray *parent = ca->parent;
345
+ CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
346
+ if ( eff_parent->ptr
347
+ && eff_parent->elements == parent->elements
348
+ && eff_parent->bytes == parent->bytes ) {
349
+ int multibyte_byteswap = ( ca_endian == CA_BIG_ENDIAN
350
+ && parent->bytes != 1
351
+ && ( ! ca_is_fixlen_type(parent) ) );
352
+ if ( dir == CA_XFER_GET ) {
353
+ ca_bit_unpack((const uint8_t *) eff_parent->ptr,
354
+ parent->elements, parent->bytes,
355
+ multibyte_byteswap, (boolean8_t *) data);
356
+ } else {
357
+ ca_bit_pack((const boolean8_t *) data,
358
+ parent->elements, parent->bytes,
359
+ multibyte_byteswap, (uint8_t *) eff_parent->ptr);
360
+ }
361
+ return;
362
+ }
237
363
  }
238
- ca_store_index(ca->parent, idx, v);
239
- free(v);
240
364
  }
365
+
366
+ vaddrs = ALLOCV_N(ca_size_t, holder, n);
367
+ for (k = 0; k < ndim; k++) idx[k] = 0;
368
+ for (i = 0; i < n; i++) {
369
+ ca_size_t off = base;
370
+ for (k = 0; k < ndim; k++) off += idx[k] * strides[k];
371
+ vaddrs[i] = off / ca->bytes;
372
+ k = ndim - 1;
373
+ while (k >= 0) { if (++idx[k] < counts[k]) break; idx[k] = 0; k--; }
374
+ }
375
+ ca_xfer_addrs(ca, n, vaddrs, data, dir);
376
+ ALLOCV_END(holder);
241
377
  }
242
378
 
243
379
  static void
@@ -245,19 +381,15 @@ ca_bitarray_func_allocate (void *ap)
245
381
  {
246
382
  CABitarray *ca = (CABitarray *) ap;
247
383
  ca_attach(ca->parent);
248
- /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
249
- ca->ptr = malloc_with_check(ca_length(ca));
384
+ ca->ptr = xmalloc(ca_length(ca));
250
385
  }
251
386
 
252
387
  static void
253
388
  ca_bitarray_func_attach (void *ap)
254
389
  {
255
- void ca_bitarray_attach (CABitarray *cb);
256
-
257
390
  CABitarray *ca = (CABitarray *) ap;
258
391
  ca_attach(ca->parent);
259
- /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
260
- ca->ptr = malloc_with_check(ca_length(ca));
392
+ ca->ptr = xmalloc(ca_length(ca));
261
393
  ca_bitarray_attach(ca);
262
394
  }
263
395
 
@@ -273,34 +405,71 @@ static void
273
405
  ca_bitarray_func_detach (void *ap)
274
406
  {
275
407
  CABitarray *ca = (CABitarray *) ap;
276
- free(ca->ptr);
408
+ xfree(ca->ptr);
277
409
  ca->ptr = NULL;
278
410
  ca_detach(ca->parent);
279
411
  }
280
412
 
413
+ /* Whole-view transfer. Fast path: drive ca_bit_unpack /
414
+ ca_bit_pack directly against the effective attached parent (via
415
+ identity compose-fold), bypassing the addrs[] allocation the
416
+ xfer_addrs path would otherwise perform.
417
+
418
+ Cold parent (eff_parent without live ptr, e.g. CABitarray over a
419
+ CAFake chain) falls back to a scratch 2-pass: gather the parent
420
+ through xfer_stride into a byte buffer, apply the bit primitive,
421
+ and for PUT scatter the buffer back. Deliberately does not call
422
+ ca_attach(parent) — that would re-introduce the silent transitive
423
+ attach the fast path exists to avoid. */
281
424
  static void
282
- ca_bitarray_func_copy_data (void *ap, void *ptr)
425
+ ca_bitarray_func_xfer_all (void *ap, void *data, int dir)
283
426
  {
284
427
  CABitarray *ca = (CABitarray *) ap;
285
- char *ptr0 = ca->ptr;
286
- ca_attach(ca->parent);
287
- ca->ptr = ptr;
288
- ca_bitarray_attach(ca);
289
- ca->ptr = ptr0;
290
- ca_detach(ca->parent);
291
- }
428
+ CArray *parent = ca->parent;
429
+ ca_size_t pbytes = parent->bytes;
430
+ CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
431
+ int multibyte_byteswap = ( ca_endian == CA_BIG_ENDIAN
432
+ && pbytes != 1
433
+ && ( ! ca_is_fixlen_type(parent) ) );
434
+
435
+ if ( eff_parent->ptr
436
+ && eff_parent->elements == parent->elements
437
+ && eff_parent->bytes == parent->bytes ) {
438
+ if ( dir == CA_XFER_GET ) {
439
+ ca_bit_unpack((const uint8_t *) eff_parent->ptr,
440
+ parent->elements, pbytes,
441
+ multibyte_byteswap, (boolean8_t *) data);
442
+ } else {
443
+ ca_bit_pack((const boolean8_t *) data,
444
+ parent->elements, pbytes,
445
+ multibyte_byteswap, (uint8_t *) eff_parent->ptr);
446
+ }
447
+ return;
448
+ }
292
449
 
293
- static void
294
- ca_bitarray_func_sync_data (void *ap, void *ptr)
295
- {
296
- CABitarray *ca = (CABitarray *) ap;
297
- char *ptr0 = ca->ptr;
298
- ca_attach(ca->parent);
299
- ca->ptr = ptr;
300
- ca_bitarray_sync(ca);
301
- ca->ptr = ptr0;
302
- ca_sync(ca->parent);
303
- ca_detach(ca->parent);
450
+ /* Cold-parent fallback: materialise into scratch via xfer_stride
451
+ (no ca_attach(parent)), apply the bit primitive, and for PUT
452
+ scatter back. */
453
+ {
454
+ volatile VALUE holder;
455
+ char *scratch = ALLOCV_N(char, holder, parent->elements * pbytes);
456
+ ca_size_t pstarts[CA_RANK_MAX];
457
+ ca_size_t pnative[CA_RANK_MAX];
458
+ ca_size_t s = pbytes;
459
+ int8_t k;
460
+ for ( k = parent->ndim - 1; k >= 0; k-- ) { pnative[k] = s; s *= parent->dim[k]; }
461
+ for ( k = 0; k < parent->ndim; k++ ) pstarts[k] = 0;
462
+ if ( dir == CA_XFER_GET ) {
463
+ ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_GET);
464
+ ca_bit_unpack((const uint8_t *) scratch, parent->elements, pbytes,
465
+ multibyte_byteswap, (boolean8_t *) data);
466
+ } else {
467
+ ca_bit_pack((const boolean8_t *) data, parent->elements, pbytes,
468
+ multibyte_byteswap, (uint8_t *) scratch);
469
+ ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_PUT);
470
+ }
471
+ ALLOCV_END(holder);
472
+ }
304
473
  }
305
474
 
306
475
  static void
@@ -336,44 +505,47 @@ ca_bitarray_func_create_mask (void *ap)
336
505
 
337
506
  ca_operation_function_t ca_bitarray_func = {
338
507
  -1, /* CA_OBJ_BITARRAY */
339
- CA_VIRTUAL_ARRAY,
508
+ CA_VIEW_ARRAY,
340
509
  free_ca_bitarray,
341
510
  ca_bitarray_func_clone,
342
- ca_bitarray_func_ptr_at_addr,
343
- ca_bitarray_func_ptr_at_index,
344
- NULL,
345
- ca_bitarray_func_fetch_index,
346
- NULL,
347
- ca_bitarray_func_store_index,
348
511
  ca_bitarray_func_allocate,
349
512
  ca_bitarray_func_attach,
350
513
  ca_bitarray_func_sync,
351
514
  ca_bitarray_func_detach,
352
- ca_bitarray_func_copy_data,
353
- ca_bitarray_func_sync_data,
354
515
  ca_bitarray_func_fill_data,
355
516
  ca_bitarray_func_create_mask,
517
+ ca_bitarray_func_xfer_index,
518
+ ca_bitarray_func_xfer_addrs,
519
+ NULL, /* fold_stride: never fold — per-cell bit transform */
520
+ ca_bitarray_func_xfer_stride,
521
+ ca_bitarray_func_xfer_all,
356
522
  };
357
523
 
358
524
  /* ------------------------------------------------------------------- */
359
525
 
360
- static void
361
- ca_bitarray_attach (CABitarray *ca)
526
+ /* Bulk bit-unpack primitive: expand `elements * pbytes` parent
527
+ bytes into `elements * pbytes * 8` boolean cells via LSB-first
528
+ per-byte fan-out. With `multibyte_byteswap` set, walks bytes
529
+ within each parent element in reverse (network byte order);
530
+ otherwise linear. Single-byte parents ignore the flag.
531
+ *
532
+ * Called by ca_bitarray_attach and by the whole-view fast paths in
533
+ * ca_bitarray_func_xfer_addrs / _xfer_stride / _xfer_all. */
534
+ void
535
+ ca_bit_unpack (const uint8_t *src, ca_size_t elements, ca_size_t pbytes,
536
+ int multibyte_byteswap, boolean8_t *dst)
362
537
  {
363
- boolean8_t *p = (boolean8_t *)ca_ptr_at_addr(ca, 0);
364
- uint8_t *q = (uint8_t *)ca_ptr_at_addr(ca->parent, 0);
365
- uint8_t *r;
366
- uint8_t rr;
367
- ca_size_t elements = ca->parent->elements;
368
- ca_size_t bytes = ca->parent->bytes;
369
- ca_size_t n, m;
370
- if ( ca_endian == CA_BIG_ENDIAN &&
371
- ca->parent->bytes != 1 &&
372
- ( ! ca_is_fixlen_type(ca->parent) ) ) {
538
+ const uint8_t *q = src;
539
+ boolean8_t *p = dst;
540
+ ca_size_t n;
541
+ if ( multibyte_byteswap && pbytes != 1 ) {
542
+ const uint8_t *r;
543
+ uint8_t rr;
544
+ ca_size_t m;
373
545
  n = elements;
374
546
  while ( n-- ) {
375
- m = bytes;
376
- r = q + bytes - 1;
547
+ m = pbytes;
548
+ r = q + pbytes - 1;
377
549
  while ( m-- ) {
378
550
  rr = *r;
379
551
  *p++ = (rr & 1);
@@ -386,11 +558,12 @@ ca_bitarray_attach (CABitarray *ca)
386
558
  *p++ = (rr & 128) >> 7;
387
559
  r--;
388
560
  }
389
- q += bytes;
561
+ q += pbytes;
390
562
  }
391
563
  }
392
564
  else {
393
- n = elements * bytes;
565
+ uint8_t rr;
566
+ n = elements * pbytes;
394
567
  while ( n-- ) {
395
568
  rr = *q++;
396
569
  *p++ = (rr & 1);
@@ -406,37 +579,58 @@ ca_bitarray_attach (CABitarray *ca)
406
579
  }
407
580
 
408
581
  static void
409
- ca_bitarray_sync (CABitarray *ca)
582
+ ca_bitarray_attach (CABitarray *ca)
410
583
  {
411
- boolean8_t *p = (boolean8_t *)ca_ptr_at_addr(ca, 0);
412
- uint8_t *q = (uint8_t *)ca_ptr_at_addr(ca->parent, 0);
413
- uint8_t *r;
414
- ca_size_t elements = ca->parent->elements;
415
- ca_size_t bytes = ca->parent->bytes;
416
- ca_size_t n, m, i;
417
- if ( ca_endian == CA_BIG_ENDIAN &&
418
- ca->parent->bytes != 1 &&
419
- ( ! ca_is_fixlen_type(ca->parent) ) ) {
584
+ int multibyte_byteswap = ( ca_endian == CA_BIG_ENDIAN
585
+ && ca->parent->bytes != 1
586
+ && ( ! ca_is_fixlen_type(ca->parent) ) );
587
+ ca_bit_unpack((const uint8_t *) ca->parent->ptr,
588
+ ca->parent->elements, ca->parent->bytes,
589
+ multibyte_byteswap,
590
+ (boolean8_t *) ca->ptr);
591
+ }
592
+
593
+ /* Bulk bit-pack primitive (inverse of ca_bit_unpack): pack
594
+ `elements * pbytes * 8` boolean cells into `elements * pbytes`
595
+ bytes via LSB-first per-byte gather. multibyte_byteswap handling
596
+ mirrors ca_bit_unpack.
597
+ *
598
+ * CAREFUL: the caller must supply ALL 8 bits for every parent byte
599
+ * (whole-byte overwrite, no RMW). Partial-bit writes must go
600
+ * through the per-cell RMW path in ca_bitarray_func_xfer_index.
601
+ *
602
+ * Called by ca_bitarray_sync and by the whole-view PUT branches in
603
+ * ca_bitarray_func_xfer_addrs / _xfer_stride / _xfer_all. */
604
+ void
605
+ ca_bit_pack (const boolean8_t *src, ca_size_t elements, ca_size_t pbytes,
606
+ int multibyte_byteswap, uint8_t *dst)
607
+ {
608
+ const boolean8_t *p = src;
609
+ uint8_t *q = dst;
610
+ ca_size_t n, i;
611
+ if ( multibyte_byteswap && pbytes != 1 ) {
612
+ uint8_t *r;
613
+ ca_size_t m;
420
614
  n = elements;
421
615
  while ( n-- ) {
422
- m = bytes;
423
- r = q + bytes - 1;
616
+ m = pbytes;
617
+ r = q + pbytes - 1;
424
618
  while ( m-- ) {
425
619
  *r = 0;
426
- for (i=0; i<8; i++) {
620
+ for ( i = 0; i < 8; i++ ) {
427
621
  *r += (*p) * bits[i];
428
622
  p++;
429
623
  }
430
624
  r--;
431
625
  }
432
- q += bytes;
626
+ q += pbytes;
433
627
  }
434
628
  }
435
629
  else {
436
- n = elements * bytes;
630
+ n = elements * pbytes;
437
631
  while ( n-- ) {
438
632
  *q = 0;
439
- for (i=0; i<8; i++) {
633
+ for ( i = 0; i < 8; i++ ) {
440
634
  *q += (*p) * bits[i];
441
635
  p++;
442
636
  }
@@ -445,10 +639,22 @@ ca_bitarray_sync (CABitarray *ca)
445
639
  }
446
640
  }
447
641
 
642
+ static void
643
+ ca_bitarray_sync (CABitarray *ca)
644
+ {
645
+ int multibyte_byteswap = ( ca_endian == CA_BIG_ENDIAN
646
+ && ca->parent->bytes != 1
647
+ && ( ! ca_is_fixlen_type(ca->parent) ) );
648
+ ca_bit_pack((const boolean8_t *) ca->ptr,
649
+ ca->parent->elements, ca->parent->bytes,
650
+ multibyte_byteswap,
651
+ (uint8_t *) ca->parent->ptr);
652
+ }
653
+
448
654
  static void
449
655
  ca_bitarray_fill (CABitarray *ca, char *ptr)
450
656
  {
451
- uint8_t *q = (uint8_t *)ca_ptr_at_addr(ca->parent, 0);
657
+ uint8_t *q = (uint8_t *)ca->parent->ptr;
452
658
  uint8_t val = *(uint8_t *)ptr;
453
659
  if ( val ) {
454
660
  memset(q, 255, ca_length(ca->parent));
@@ -474,18 +680,10 @@ rb_ca_bitarray_new (VALUE cary)
474
680
  return obj;
475
681
  }
476
682
 
477
- /* @overload bitarray
478
-
479
- [TBD]
480
- */
481
-
482
683
  VALUE
483
684
  rb_ca_bitarray (VALUE self)
484
685
  {
485
686
  volatile VALUE obj;
486
- CArray *ca;
487
-
488
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
489
687
 
490
688
  obj = rb_ca_bitarray_new(self);
491
689
 
@@ -507,20 +705,27 @@ rb_ca_bitarray_initialize_copy (VALUE self, VALUE other)
507
705
  TypedData_Get_Struct(self, CABitarray, &cabitarray_data_type, ca);
508
706
  TypedData_Get_Struct(other, CABitarray, &cabitarray_data_type, cs);
509
707
 
708
+ if ( ca_func[CA_OBJ_BITARRAY].pool_init ) {
709
+ ca_array_pool_alloc(ca, CA_OBJ_BITARRAY, cs->parent->ndim + 1);
710
+ }
510
711
  ca_bitarray_setup(ca, cs->parent);
511
712
 
512
713
  return self;
513
714
  }
514
715
 
515
716
  void
516
- Init_ca_obj_bitarray ()
717
+ Init_ca_obj_bitarray (void)
517
718
  {
518
- rb_cCABitarray = rb_define_class("CABitarray", rb_cCAVirtual);
719
+ rb_cCABitarray = rb_define_class("CABitarray", rb_cCAView);
720
+
721
+ ca_bitarray_func.struct_size = sizeof(CABitarray);
722
+ ca_bitarray_func.pool_bytes = ca_bitarray_pool_bytes;
723
+ ca_bitarray_func.pool_init = ca_bitarray_pool_init;
519
724
 
520
- CA_OBJ_BITARRAY = ca_install_obj_type(rb_cCABitarray,
521
- &cabitarray_data_type,
725
+ CA_OBJ_BITARRAY = ca_install_obj_type(rb_cCABitarray,
726
+ &cabitarray_data_type,
522
727
  rb_cCArrayMask,
523
- &carray_data_type, ca_bitarray_func);
728
+ &carray_mask_data_type, &ca_bitarray_func, sizeof(ca_bitarray_func));
524
729
  rb_define_const(rb_cObject, "CA_OBJ_BITARRAY", INT2NUM(CA_OBJ_BITARRAY));
525
730
 
526
731
  rb_define_method(rb_cCArray, "bitarray", rb_ca_bitarray, 0);