@loaders.gl/parquet 5.0.0-alpha.2 → 5.0.0-alpha.4

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 (336) hide show
  1. package/LICENSE +1 -1
  2. package/dist/bundled.d.ts +1 -1
  3. package/dist/bundled.d.ts.map +1 -1
  4. package/dist/bundled.js.map +1 -1
  5. package/dist/delta-format.d.ts +9 -0
  6. package/dist/delta-format.d.ts.map +1 -0
  7. package/dist/delta-format.js +12 -0
  8. package/dist/delta-format.js.map +1 -0
  9. package/dist/delta-source-loader-types.d.ts +27 -0
  10. package/dist/delta-source-loader-types.d.ts.map +1 -0
  11. package/dist/delta-source-loader-types.js +28 -0
  12. package/dist/delta-source-loader-types.js.map +1 -0
  13. package/dist/delta-source.d.ts +48 -0
  14. package/dist/delta-source.d.ts.map +1 -0
  15. package/dist/delta-source.js +222 -0
  16. package/dist/delta-source.js.map +1 -0
  17. package/dist/delta-types.d.ts +38 -0
  18. package/dist/delta-types.d.ts.map +1 -0
  19. package/dist/delta-types.js +5 -0
  20. package/dist/delta-types.js.map +1 -0
  21. package/dist/geoparquet-loader.js +1 -1
  22. package/dist/iceberg-rest-catalog.d.ts +49 -0
  23. package/dist/iceberg-rest-catalog.d.ts.map +1 -0
  24. package/dist/iceberg-rest-catalog.js +78 -0
  25. package/dist/iceberg-rest-catalog.js.map +1 -0
  26. package/dist/iceberg-table-source.d.ts +63 -0
  27. package/dist/iceberg-table-source.d.ts.map +1 -0
  28. package/dist/iceberg-table-source.js +797 -0
  29. package/dist/iceberg-table-source.js.map +1 -0
  30. package/dist/iceberg-types.d.ts +150 -0
  31. package/dist/iceberg-types.d.ts.map +1 -0
  32. package/dist/iceberg-types.js +5 -0
  33. package/dist/iceberg-types.js.map +1 -0
  34. package/dist/index.cjs +15841 -3306
  35. package/dist/index.cjs.map +3 -3
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +5 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/arrow/convert-schema-from-parquet.d.ts +3 -1
  41. package/dist/lib/arrow/convert-schema-from-parquet.d.ts.map +1 -1
  42. package/dist/lib/arrow/convert-schema-from-parquet.js +94 -19
  43. package/dist/lib/arrow/convert-schema-from-parquet.js.map +1 -1
  44. package/dist/lib/arrow/create-nested-arrow-vector.js +89 -0
  45. package/dist/lib/arrow/create-nested-arrow-vector.js.map +1 -1
  46. package/dist/lib/constants.js +1 -1
  47. package/dist/lib/encoders/encode-table-to-parquet-js.d.ts.map +1 -1
  48. package/dist/lib/encoders/encode-table-to-parquet-js.js +202 -7
  49. package/dist/lib/encoders/encode-table-to-parquet-js.js.map +1 -1
  50. package/dist/lib/geo/geoparquet-covering.d.ts +19 -0
  51. package/dist/lib/geo/geoparquet-covering.d.ts.map +1 -0
  52. package/dist/lib/geo/geoparquet-covering.js +137 -0
  53. package/dist/lib/geo/geoparquet-covering.js.map +1 -0
  54. package/dist/lib/geo/geospatial-metadata.d.ts.map +1 -1
  55. package/dist/lib/geo/geospatial-metadata.js +39 -13
  56. package/dist/lib/geo/geospatial-metadata.js.map +1 -1
  57. package/dist/lib/parquet-bloom-filter-planner.d.ts +16 -0
  58. package/dist/lib/parquet-bloom-filter-planner.d.ts.map +1 -0
  59. package/dist/lib/parquet-bloom-filter-planner.js +57 -0
  60. package/dist/lib/parquet-bloom-filter-planner.js.map +1 -0
  61. package/dist/lib/parquet-bloom-filter.d.ts +30 -0
  62. package/dist/lib/parquet-bloom-filter.d.ts.map +1 -0
  63. package/dist/lib/parquet-bloom-filter.js +289 -0
  64. package/dist/lib/parquet-bloom-filter.js.map +1 -0
  65. package/dist/lib/parquet-encryption.d.ts +80 -0
  66. package/dist/lib/parquet-encryption.d.ts.map +1 -0
  67. package/dist/lib/parquet-encryption.js +190 -0
  68. package/dist/lib/parquet-encryption.js.map +1 -0
  69. package/dist/lib/parquet-page-index.d.ts +34 -5
  70. package/dist/lib/parquet-page-index.d.ts.map +1 -1
  71. package/dist/lib/parquet-page-index.js +114 -28
  72. package/dist/lib/parquet-page-index.js.map +1 -1
  73. package/dist/lib/parquet-predicate.d.ts +5 -1
  74. package/dist/lib/parquet-predicate.d.ts.map +1 -1
  75. package/dist/lib/parquet-predicate.js +42 -14
  76. package/dist/lib/parquet-predicate.js.map +1 -1
  77. package/dist/lib/parquet-source-worker-decoder.d.ts +4 -1
  78. package/dist/lib/parquet-source-worker-decoder.d.ts.map +1 -1
  79. package/dist/lib/parquet-source-worker-decoder.js +83 -17
  80. package/dist/lib/parquet-source-worker-decoder.js.map +1 -1
  81. package/dist/lib/parquet-source-worker-types.d.ts +24 -0
  82. package/dist/lib/parquet-source-worker-types.d.ts.map +1 -1
  83. package/dist/lib/parsers/get-parquet-schema.d.ts.map +1 -1
  84. package/dist/lib/parsers/get-parquet-schema.js +3 -1
  85. package/dist/lib/parsers/get-parquet-schema.js.map +1 -1
  86. package/dist/lib/parsers/parse-parquet-to-arrow-js.d.ts.map +1 -1
  87. package/dist/lib/parsers/parse-parquet-to-arrow-js.js +327 -18
  88. package/dist/lib/parsers/parse-parquet-to-arrow-js.js.map +1 -1
  89. package/dist/lib/parsers/parse-parquet-to-arrow.d.ts.map +1 -1
  90. package/dist/lib/parsers/parse-parquet-to-arrow.js +5 -5
  91. package/dist/lib/parsers/parse-parquet-to-arrow.js.map +1 -1
  92. package/dist/lib/parsers/parse-parquet-to-columns.d.ts.map +1 -1
  93. package/dist/lib/parsers/parse-parquet-to-columns.js +3 -1
  94. package/dist/lib/parsers/parse-parquet-to-columns.js.map +1 -1
  95. package/dist/lib/parsers/parse-parquet-to-json.d.ts.map +1 -1
  96. package/dist/lib/parsers/parse-parquet-to-json.js +18 -2
  97. package/dist/lib/parsers/parse-parquet-to-json.js.map +1 -1
  98. package/dist/lib/slice-parquet-batch.d.ts +9 -0
  99. package/dist/lib/slice-parquet-batch.d.ts.map +1 -0
  100. package/dist/lib/slice-parquet-batch.js +28 -0
  101. package/dist/lib/slice-parquet-batch.js.map +1 -0
  102. package/dist/lib/sources/parquet-range-file.d.ts +1 -1
  103. package/dist/lib/sources/parquet-range-file.d.ts.map +1 -1
  104. package/dist/lib/sources/parquet-range-file.js +28 -22
  105. package/dist/lib/sources/parquet-range-file.js.map +1 -1
  106. package/dist/lib/utils/normalize-parquet-options.d.ts.map +1 -1
  107. package/dist/lib/utils/normalize-parquet-options.js +15 -1
  108. package/dist/lib/utils/normalize-parquet-options.js.map +1 -1
  109. package/dist/parquet-dataset-source.cjs +16528 -4928
  110. package/dist/parquet-dataset-source.cjs.map +3 -3
  111. package/dist/parquet-dataset-source.d.ts +31 -4
  112. package/dist/parquet-dataset-source.d.ts.map +1 -1
  113. package/dist/parquet-dataset-source.js +296 -74
  114. package/dist/parquet-dataset-source.js.map +1 -1
  115. package/dist/parquet-encoded-page-types.d.ts +108 -0
  116. package/dist/parquet-encoded-page-types.d.ts.map +1 -0
  117. package/dist/parquet-encoded-page-types.js +5 -0
  118. package/dist/parquet-encoded-page-types.js.map +1 -0
  119. package/dist/parquet-js-loader-types.d.ts +2 -0
  120. package/dist/parquet-js-loader-types.d.ts.map +1 -1
  121. package/dist/parquet-js-loader-types.js +2 -1
  122. package/dist/parquet-js-loader-types.js.map +1 -1
  123. package/dist/parquet-js-loader.d.ts +1 -0
  124. package/dist/parquet-js-loader.d.ts.map +1 -1
  125. package/dist/parquet-js-loader.js +2 -1
  126. package/dist/parquet-js-loader.js.map +1 -1
  127. package/dist/parquet-js-writer.d.ts +23 -2
  128. package/dist/parquet-js-writer.d.ts.map +1 -1
  129. package/dist/parquet-js-writer.js +1 -1
  130. package/dist/parquet-js-writer.js.map +1 -1
  131. package/dist/parquet-loader-base.js +1 -1
  132. package/dist/parquet-loader-options.d.ts +11 -0
  133. package/dist/parquet-loader-options.d.ts.map +1 -1
  134. package/dist/parquet-loader-options.js.map +1 -1
  135. package/dist/parquet-source-capabilities.d.ts +8 -1
  136. package/dist/parquet-source-capabilities.d.ts.map +1 -1
  137. package/dist/parquet-source-capabilities.js +10 -0
  138. package/dist/parquet-source-capabilities.js.map +1 -1
  139. package/dist/parquet-source-loader-types.d.ts +10 -0
  140. package/dist/parquet-source-loader-types.d.ts.map +1 -1
  141. package/dist/parquet-source-loader-types.js +11 -1
  142. package/dist/parquet-source-loader-types.js.map +1 -1
  143. package/dist/parquet-source-loader.cjs +14121 -2796
  144. package/dist/parquet-source-loader.cjs.map +3 -3
  145. package/dist/parquet-source-loader.d.ts +51 -4
  146. package/dist/parquet-source-loader.d.ts.map +1 -1
  147. package/dist/parquet-source-loader.js +651 -38
  148. package/dist/parquet-source-loader.js.map +1 -1
  149. package/dist/parquet-source-types.d.ts +180 -30
  150. package/dist/parquet-source-types.d.ts.map +1 -1
  151. package/dist/parquet-source-worker.js +7378 -6989
  152. package/dist/parquet-source-worker.js.map +4 -4
  153. package/dist/parquet-worker-node.cjs +8501 -1045
  154. package/dist/parquet-worker-node.cjs.map +4 -4
  155. package/dist/parquet-worker-url.js +5 -1
  156. package/dist/parquet-worker-url.js.map +1 -1
  157. package/dist/parquet-worker.js +289 -218
  158. package/dist/parquet-worker.js.map +4 -4
  159. package/dist/parquetjs/codecs/declare.d.ts +15 -0
  160. package/dist/parquetjs/codecs/declare.d.ts.map +1 -1
  161. package/dist/parquetjs/codecs/declare.js +10 -0
  162. package/dist/parquetjs/codecs/declare.js.map +1 -1
  163. package/dist/parquetjs/codecs/delta.d.ts.map +1 -1
  164. package/dist/parquetjs/codecs/delta.js +356 -7
  165. package/dist/parquetjs/codecs/delta.js.map +1 -1
  166. package/dist/parquetjs/codecs/index.d.ts.map +1 -1
  167. package/dist/parquetjs/codecs/index.js +4 -0
  168. package/dist/parquetjs/codecs/index.js.map +1 -1
  169. package/dist/parquetjs/codecs/plain.d.ts +1 -1
  170. package/dist/parquetjs/codecs/plain.d.ts.map +1 -1
  171. package/dist/parquetjs/codecs/plain.js +153 -12
  172. package/dist/parquetjs/codecs/plain.js.map +1 -1
  173. package/dist/parquetjs/codecs/rle.d.ts +4 -0
  174. package/dist/parquetjs/codecs/rle.d.ts.map +1 -1
  175. package/dist/parquetjs/codecs/rle.js +406 -3
  176. package/dist/parquetjs/codecs/rle.js.map +1 -1
  177. package/dist/parquetjs/compression.d.ts +9 -0
  178. package/dist/parquetjs/compression.d.ts.map +1 -1
  179. package/dist/parquetjs/compression.js +86 -67
  180. package/dist/parquetjs/compression.js.map +1 -1
  181. package/dist/parquetjs/encoder/dictionary-planner.d.ts.map +1 -1
  182. package/dist/parquetjs/encoder/dictionary-planner.js +5 -2
  183. package/dist/parquetjs/encoder/dictionary-planner.js.map +1 -1
  184. package/dist/parquetjs/encoder/parquet-encoder.d.ts +43 -1
  185. package/dist/parquetjs/encoder/parquet-encoder.d.ts.map +1 -1
  186. package/dist/parquetjs/encoder/parquet-encoder.js +691 -34
  187. package/dist/parquetjs/encoder/parquet-encoder.js.map +1 -1
  188. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts +29 -0
  189. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts.map +1 -0
  190. package/dist/parquetjs/parquet-thrift/BoundingBox.js +85 -0
  191. package/dist/parquetjs/parquet-thrift/BoundingBox.js.map +1 -0
  192. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts +5 -0
  193. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts.map +1 -1
  194. package/dist/parquetjs/parquet-thrift/ColumnChunk.js +35 -0
  195. package/dist/parquetjs/parquet-thrift/ColumnChunk.js.map +1 -1
  196. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts +35 -0
  197. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts.map +1 -0
  198. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js +135 -0
  199. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js.map +1 -0
  200. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts +10 -0
  201. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts.map +1 -1
  202. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js +73 -0
  203. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js.map +1 -1
  204. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts +22 -0
  205. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts.map +1 -0
  206. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js +111 -0
  207. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js.map +1 -0
  208. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts +16 -0
  209. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts.map +1 -0
  210. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js +57 -0
  211. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js.map +1 -0
  212. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts +5 -0
  213. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts.map +1 -1
  214. package/dist/parquetjs/parquet-thrift/FileMetaData.js +35 -0
  215. package/dist/parquetjs/parquet-thrift/FileMetaData.js.map +1 -1
  216. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts +18 -0
  217. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts.map +1 -0
  218. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js +62 -0
  219. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js.map +1 -0
  220. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts +26 -0
  221. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts.map +1 -0
  222. package/dist/parquetjs/parquet-thrift/SizeStatistics.js +85 -0
  223. package/dist/parquetjs/parquet-thrift/SizeStatistics.js.map +1 -0
  224. package/dist/parquetjs/parquet-thrift/index.d.ts +6 -0
  225. package/dist/parquetjs/parquet-thrift/index.d.ts.map +1 -1
  226. package/dist/parquetjs/parquet-thrift/index.js +6 -0
  227. package/dist/parquetjs/parquet-thrift/index.js.map +1 -1
  228. package/dist/parquetjs/parser/decoders.d.ts +10 -1
  229. package/dist/parquetjs/parser/decoders.d.ts.map +1 -1
  230. package/dist/parquetjs/parser/decoders.js +318 -14
  231. package/dist/parquetjs/parser/decoders.js.map +1 -1
  232. package/dist/parquetjs/parser/encoded-pages.d.ts +24 -0
  233. package/dist/parquetjs/parser/encoded-pages.d.ts.map +1 -0
  234. package/dist/parquetjs/parser/encoded-pages.js +206 -0
  235. package/dist/parquetjs/parser/encoded-pages.js.map +1 -0
  236. package/dist/parquetjs/parser/parquet-reader.d.ts +88 -12
  237. package/dist/parquetjs/parser/parquet-reader.d.ts.map +1 -1
  238. package/dist/parquetjs/parser/parquet-reader.js +713 -66
  239. package/dist/parquetjs/parser/parquet-reader.js.map +1 -1
  240. package/dist/parquetjs/schema/declare.d.ts +22 -3
  241. package/dist/parquetjs/schema/declare.d.ts.map +1 -1
  242. package/dist/parquetjs/schema/declare.js.map +1 -1
  243. package/dist/parquetjs/schema/schema.d.ts.map +1 -1
  244. package/dist/parquetjs/schema/schema.js +10 -0
  245. package/dist/parquetjs/schema/schema.js.map +1 -1
  246. package/dist/parquetjs/schema/shred.d.ts.map +1 -1
  247. package/dist/parquetjs/schema/shred.js +219 -11
  248. package/dist/parquetjs/schema/shred.js.map +1 -1
  249. package/dist/parquetjs/schema/types.js +19 -21
  250. package/dist/parquetjs/schema/types.js.map +1 -1
  251. package/dist/parquetjs/schema/variant.d.ts +3 -0
  252. package/dist/parquetjs/schema/variant.d.ts.map +1 -0
  253. package/dist/parquetjs/schema/variant.js +248 -0
  254. package/dist/parquetjs/schema/variant.js.map +1 -0
  255. package/dist/parquetjs/utils/crc32.d.ts +3 -0
  256. package/dist/parquetjs/utils/crc32.d.ts.map +1 -0
  257. package/dist/parquetjs/utils/crc32.js +15 -0
  258. package/dist/parquetjs/utils/crc32.js.map +1 -0
  259. package/dist/parquetjs/utils/read-utils.d.ts +11 -1
  260. package/dist/parquetjs/utils/read-utils.d.ts.map +1 -1
  261. package/dist/parquetjs/utils/read-utils.js +21 -1
  262. package/dist/parquetjs/utils/read-utils.js.map +1 -1
  263. package/dist/unbundled.d.ts +2 -1
  264. package/dist/unbundled.d.ts.map +1 -1
  265. package/dist/unbundled.js +1 -0
  266. package/dist/unbundled.js.map +1 -1
  267. package/package.json +36 -13
  268. package/src/bundled.ts +10 -0
  269. package/src/delta-format.ts +12 -0
  270. package/src/delta-source-loader-types.ts +40 -0
  271. package/src/delta-source.ts +305 -0
  272. package/src/delta-types.ts +40 -0
  273. package/src/iceberg-rest-catalog.ts +122 -0
  274. package/src/iceberg-table-source.ts +1037 -0
  275. package/src/iceberg-types.ts +165 -0
  276. package/src/index.ts +59 -1
  277. package/src/lib/arrow/convert-schema-from-parquet.ts +113 -19
  278. package/src/lib/arrow/create-nested-arrow-vector.ts +116 -0
  279. package/src/lib/encoders/encode-table-to-parquet-js.ts +268 -7
  280. package/src/lib/geo/geoparquet-covering.ts +201 -0
  281. package/src/lib/geo/geospatial-metadata.ts +42 -15
  282. package/src/lib/parquet-bloom-filter-planner.ts +86 -0
  283. package/src/lib/parquet-bloom-filter.ts +345 -0
  284. package/src/lib/parquet-encryption.ts +344 -0
  285. package/src/lib/parquet-page-index.ts +180 -34
  286. package/src/lib/parquet-predicate.ts +52 -16
  287. package/src/lib/parquet-source-worker-decoder.ts +116 -20
  288. package/src/lib/parquet-source-worker-types.ts +25 -0
  289. package/src/lib/parsers/get-parquet-schema.ts +3 -1
  290. package/src/lib/parsers/parse-parquet-to-arrow-js.ts +397 -17
  291. package/src/lib/parsers/parse-parquet-to-arrow.ts +4 -5
  292. package/src/lib/parsers/parse-parquet-to-columns.ts +3 -1
  293. package/src/lib/parsers/parse-parquet-to-json.ts +18 -2
  294. package/src/lib/slice-parquet-batch.ts +32 -0
  295. package/src/lib/sources/parquet-range-file.ts +35 -29
  296. package/src/lib/utils/normalize-parquet-options.ts +17 -1
  297. package/src/parquet-dataset-source.ts +397 -85
  298. package/src/parquet-encoded-page-types.ts +122 -0
  299. package/src/parquet-js-loader-types.ts +1 -0
  300. package/src/parquet-js-loader.ts +2 -1
  301. package/src/parquet-js-writer.ts +30 -0
  302. package/src/parquet-loader-options.ts +11 -0
  303. package/src/parquet-source-capabilities.ts +18 -1
  304. package/src/parquet-source-loader-types.ts +10 -0
  305. package/src/parquet-source-loader.ts +1024 -52
  306. package/src/parquet-source-types.ts +197 -28
  307. package/src/parquet-worker-url.ts +6 -1
  308. package/src/parquetjs/codecs/declare.ts +27 -0
  309. package/src/parquetjs/codecs/delta.ts +466 -6
  310. package/src/parquetjs/codecs/index.ts +4 -0
  311. package/src/parquetjs/codecs/plain.ts +177 -11
  312. package/src/parquetjs/codecs/rle.ts +573 -3
  313. package/src/parquetjs/compression.ts +102 -76
  314. package/src/parquetjs/encoder/dictionary-planner.ts +7 -2
  315. package/src/parquetjs/encoder/parquet-encoder.ts +1016 -38
  316. package/src/parquetjs/parquet-thrift/BoundingBox.ts +108 -0
  317. package/src/parquetjs/parquet-thrift/ColumnChunk.ts +35 -0
  318. package/src/parquetjs/parquet-thrift/ColumnCryptoMetaData.ts +139 -0
  319. package/src/parquetjs/parquet-thrift/ColumnMetaData.ts +73 -0
  320. package/src/parquetjs/parquet-thrift/EncryptionAlgorithm.ts +127 -0
  321. package/src/parquetjs/parquet-thrift/FileCryptoMetaData.ts +60 -0
  322. package/src/parquetjs/parquet-thrift/FileMetaData.ts +35 -0
  323. package/src/parquetjs/parquet-thrift/GeospatialStatistics.ts +68 -0
  324. package/src/parquetjs/parquet-thrift/SizeStatistics.ts +98 -0
  325. package/src/parquetjs/parquet-thrift/index.ts +6 -0
  326. package/src/parquetjs/parser/decoders.ts +451 -26
  327. package/src/parquetjs/parser/encoded-pages.ts +278 -0
  328. package/src/parquetjs/parser/parquet-reader.ts +1112 -87
  329. package/src/parquetjs/schema/declare.ts +22 -2
  330. package/src/parquetjs/schema/schema.ts +10 -0
  331. package/src/parquetjs/schema/shred.ts +238 -11
  332. package/src/parquetjs/schema/types.ts +16 -25
  333. package/src/parquetjs/schema/variant.ts +313 -0
  334. package/src/parquetjs/utils/crc32.ts +15 -0
  335. package/src/parquetjs/utils/read-utils.ts +26 -1
  336. package/src/unbundled.ts +14 -0
@@ -7,6 +7,7 @@ import type {PrimitiveType} from '../schema/declare';
7
7
  import {concatUint8Arrays, copyUint8Array, toUint8Array} from '../utils/binary-utils';
8
8
  import {
9
9
  getParquetValueOutput,
10
+ reserveParquetByteArrayOutput,
10
11
  type CursorBuffer,
11
12
  type ParquetCodecOptions,
12
13
  type ParquetValueBuffer
@@ -15,6 +16,8 @@ import {
15
16
  const DELTA_BLOCK_SIZE = 128;
16
17
  const DELTA_MINI_BLOCK_COUNT = 4;
17
18
  const DELTA_VALUES_PER_MINI_BLOCK = DELTA_BLOCK_SIZE / DELTA_MINI_BLOCK_COUNT;
19
+ const UINT32_BASE = 0x1_0000_0000;
20
+ const IS_LITTLE_ENDIAN = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
18
21
 
19
22
  /** Encodes INT32 or INT64 values using Parquet DELTA_BINARY_PACKED. */
20
23
  export function encodeDeltaBinaryPackedValues(
@@ -264,6 +267,31 @@ function decodeDeltaBinaryPackedInt32Values(
264
267
  while (outputIndex < count) {
265
268
  const minimumDelta = readZigZagVarInt32(cursor);
266
269
  const bitWidths = readBitWidths(cursor, miniBlockCount, 32);
270
+ const activeMiniBlockCount = Math.min(
271
+ miniBlockCount,
272
+ Math.ceil((count - outputIndex) / valuesPerMiniBlock)
273
+ );
274
+ // Writers commonly select one width for every mini-block in a block. Fuse that contiguous
275
+ // bitstream so the decoder pays call/state setup once instead of once per 32 values.
276
+ if (haveEqualBitWidths(bitWidths, activeMiniBlockCount)) {
277
+ const bitWidth = bitWidths[0];
278
+ const valueCount = Math.min(valuesPerMiniBlock * activeMiniBlockCount, count - outputIndex);
279
+ const packedByteLength = (valuesPerMiniBlock * activeMiniBlockCount * bitWidth) / 8;
280
+ assertReadable(cursor, packedByteLength);
281
+ value = decodeInt32MiniBlock(
282
+ cursor.buffer,
283
+ cursor.offset,
284
+ bitWidth,
285
+ valueCount,
286
+ minimumDelta,
287
+ value,
288
+ output,
289
+ outputOffset + outputIndex
290
+ );
291
+ outputIndex += valueCount;
292
+ cursor.offset += packedByteLength;
293
+ continue;
294
+ }
267
295
  for (const bitWidth of bitWidths) {
268
296
  const packedOffset = cursor.offset;
269
297
  const packedByteLength = (valuesPerMiniBlock * bitWidth) / 8;
@@ -310,6 +338,26 @@ function decodeInt32MiniBlock(
310
338
  return value;
311
339
  }
312
340
 
341
+ if (bitWidth <= 24) {
342
+ // Bitwise reservoirs stay exact through 24 bits and are substantially cheaper than the
343
+ // division-based reservoir required for wider INT32 deltas.
344
+ const mask = 2 ** bitWidth - 1;
345
+ let packedBits = 0;
346
+ let packedBitCount = 0;
347
+ let byteOffset = packedOffset;
348
+ for (let index = 0; index < count; index++) {
349
+ while (packedBitCount < bitWidth) {
350
+ packedBits |= buffer[byteOffset++] << packedBitCount;
351
+ packedBitCount += 8;
352
+ }
353
+ value = (value + minimumDelta + (packedBits & mask)) | 0;
354
+ output[outputOffset + index] = value;
355
+ packedBits >>>= bitWidth;
356
+ packedBitCount -= bitWidth;
357
+ }
358
+ return value;
359
+ }
360
+
313
361
  const divisor = 2 ** bitWidth;
314
362
  let packedBits = 0;
315
363
  let packedBitCount = 0;
@@ -337,6 +385,21 @@ function decodeDeltaBinaryPackedInt64Values(
337
385
  options: ParquetCodecOptions
338
386
  ): ParquetValueBuffer {
339
387
  const {output, outputOffset} = getParquetValueOutput(options, count);
388
+ if (options.int64AsBigInt && output instanceof BigInt64Array) {
389
+ // BigInt arithmetic per value is expensive in V8. Decode into the two uint32 words backing
390
+ // Arrow Int64 instead; modulo-64 addition preserves every signed INT64 bit pattern exactly.
391
+ const state = new Uint32Array(2);
392
+ readZigZagVarIntWords(cursor, state);
393
+ return decodeDeltaBinaryPackedInt64ArrowValues(
394
+ cursor,
395
+ count,
396
+ miniBlockCount,
397
+ valuesPerMiniBlock,
398
+ output,
399
+ outputOffset,
400
+ state
401
+ );
402
+ }
340
403
  let value = readZigZagVarInt(cursor);
341
404
  let outputIndex = 0;
342
405
  writeInt64Output(output, outputOffset + outputIndex++, value, options.int64AsBigInt);
@@ -371,6 +434,254 @@ function decodeDeltaBinaryPackedInt64Values(
371
434
  return output;
372
435
  }
373
436
 
437
+ /** Decodes INT64 directly into Arrow storage with modulo-64 two-word arithmetic. */
438
+ function decodeDeltaBinaryPackedInt64ArrowValues(
439
+ cursor: CursorBuffer,
440
+ count: number,
441
+ miniBlockCount: number,
442
+ valuesPerMiniBlock: number,
443
+ output: BigInt64Array,
444
+ outputOffset: number,
445
+ state: Uint32Array
446
+ ): BigInt64Array {
447
+ const outputWords = new Uint32Array(output.buffer, output.byteOffset, output.length * 2);
448
+ const minimumDeltaWords = new Uint32Array(2);
449
+ let outputIndex = 0;
450
+ writeInt64Words(outputWords, outputOffset + outputIndex++, state[0], state[1]);
451
+
452
+ while (outputIndex < count) {
453
+ readZigZagVarIntWords(cursor, minimumDeltaWords);
454
+ const bitWidths = readBitWidths(cursor, miniBlockCount, 64);
455
+ const activeMiniBlockCount = Math.min(
456
+ miniBlockCount,
457
+ Math.ceil((count - outputIndex) / valuesPerMiniBlock)
458
+ );
459
+ // Preserve the equal-width fusion used by the wide-column benchmark. Splitting this back into
460
+ // four mini-block calls repeats state loads/stores and loses measurable throughput.
461
+ if (haveEqualBitWidths(bitWidths, activeMiniBlockCount)) {
462
+ const bitWidth = bitWidths[0];
463
+ const valueCount = Math.min(valuesPerMiniBlock * activeMiniBlockCount, count - outputIndex);
464
+ const packedByteLength = (valuesPerMiniBlock * activeMiniBlockCount * bitWidth) / 8;
465
+ assertReadable(cursor, packedByteLength);
466
+ decodeInt64ArrowMiniBlock(
467
+ cursor.buffer,
468
+ cursor.offset,
469
+ bitWidth,
470
+ valueCount,
471
+ minimumDeltaWords[0],
472
+ minimumDeltaWords[1],
473
+ state,
474
+ outputWords,
475
+ outputOffset + outputIndex
476
+ );
477
+ outputIndex += valueCount;
478
+ cursor.offset += packedByteLength;
479
+ continue;
480
+ }
481
+ for (const bitWidth of bitWidths) {
482
+ const packedOffset = cursor.offset;
483
+ const packedByteLength = (valuesPerMiniBlock * bitWidth) / 8;
484
+ assertReadable(cursor, packedByteLength);
485
+ const valueCount = Math.min(valuesPerMiniBlock, count - outputIndex);
486
+ decodeInt64ArrowMiniBlock(
487
+ cursor.buffer,
488
+ packedOffset,
489
+ bitWidth,
490
+ valueCount,
491
+ minimumDeltaWords[0],
492
+ minimumDeltaWords[1],
493
+ state,
494
+ outputWords,
495
+ outputOffset + outputIndex
496
+ );
497
+ outputIndex += valueCount;
498
+ cursor.offset += packedByteLength;
499
+ if (outputIndex === count) break;
500
+ }
501
+ }
502
+ return output;
503
+ }
504
+
505
+ /** Returns whether all mini-blocks in one DELTA_BINARY_PACKED block use one bit width. */
506
+ function haveEqualBitWidths(bitWidths: Uint8Array, count: number): boolean {
507
+ const firstBitWidth = bitWidths[0];
508
+ for (let index = 1; index < count; index++) {
509
+ if (bitWidths[index] !== firstBitWidth) return false;
510
+ }
511
+ return true;
512
+ }
513
+
514
+ /** Decodes one INT64 mini-block directly into the two 32-bit words backing Arrow Int64. */
515
+ function decodeInt64ArrowMiniBlock(
516
+ buffer: Uint8Array,
517
+ packedOffset: number,
518
+ bitWidth: number,
519
+ count: number,
520
+ minimumDeltaLow: number,
521
+ minimumDeltaHigh: number,
522
+ state: Uint32Array,
523
+ outputWords: Uint32Array,
524
+ outputOffset: number
525
+ ): void {
526
+ let stateLow = state[0];
527
+ let stateHigh = state[1];
528
+ const lowWordOffset = IS_LITTLE_ENDIAN ? 0 : 1;
529
+ const highWordOffset = IS_LITTLE_ENDIAN ? 1 : 0;
530
+
531
+ if (bitWidth === 0) {
532
+ for (let index = 0; index < count; index++) {
533
+ const lowSum = stateLow + minimumDeltaLow;
534
+ stateLow = lowSum >>> 0;
535
+ // V8 strength-reduces division by this constant; explicit carry branches benchmark slower.
536
+ stateHigh = (stateHigh + minimumDeltaHigh + Math.floor(lowSum / UINT32_BASE)) >>> 0;
537
+ const wordOffset = (outputOffset + index) * 2;
538
+ outputWords[wordOffset + lowWordOffset] = stateLow;
539
+ outputWords[wordOffset + highWordOffset] = stateHigh;
540
+ }
541
+ state[0] = stateLow;
542
+ state[1] = stateHigh;
543
+ return;
544
+ }
545
+
546
+ if (bitWidth <= 24) {
547
+ decodeNarrowInt64ArrowMiniBlock(
548
+ buffer,
549
+ packedOffset,
550
+ bitWidth,
551
+ count,
552
+ minimumDeltaLow,
553
+ minimumDeltaHigh,
554
+ state,
555
+ outputWords,
556
+ outputOffset
557
+ );
558
+ return;
559
+ }
560
+
561
+ if (bitWidth <= 45) {
562
+ const divisor = 2 ** bitWidth;
563
+ let packedBits = 0;
564
+ let packedBitCount = 0;
565
+ let byteOffset = packedOffset;
566
+ for (let index = 0; index < count; index++) {
567
+ while (packedBitCount < bitWidth) {
568
+ packedBits += buffer[byteOffset++] * 2 ** packedBitCount;
569
+ packedBitCount += 8;
570
+ }
571
+ const packedDelta = packedBits % divisor;
572
+ packedBits = Math.floor(packedBits / divisor);
573
+ packedBitCount -= bitWidth;
574
+ const packedDeltaLow = packedDelta >>> 0;
575
+ const packedDeltaHigh = Math.floor(packedDelta / UINT32_BASE);
576
+ const lowSum = stateLow + minimumDeltaLow + packedDeltaLow;
577
+ stateLow = lowSum >>> 0;
578
+ // V8 strength-reduces division by this constant; explicit carry branches benchmark slower.
579
+ stateHigh =
580
+ (stateHigh + minimumDeltaHigh + packedDeltaHigh + Math.floor(lowSum / UINT32_BASE)) >>> 0;
581
+ const wordOffset = (outputOffset + index) * 2;
582
+ outputWords[wordOffset + lowWordOffset] = stateLow;
583
+ outputWords[wordOffset + highWordOffset] = stateHigh;
584
+ }
585
+ state[0] = stateLow;
586
+ state[1] = stateHigh;
587
+ return;
588
+ }
589
+
590
+ const highBitWidth = bitWidth - 32;
591
+ const highMask = highBitWidth === 32 ? 0xffff_ffff : 2 ** highBitWidth - 1;
592
+ for (let index = 0; index < count; index++) {
593
+ const packedBitOffset = index * bitWidth;
594
+ const byteOffset = packedOffset + Math.floor(packedBitOffset / 8);
595
+ const shift = packedBitOffset & 7;
596
+ const lowerWord = readUint32LELoose(buffer, byteOffset);
597
+ const middleWord = readUint32LELoose(buffer, byteOffset + 4);
598
+ let packedDeltaLow: number;
599
+ let packedDeltaHigh: number;
600
+ if (shift === 0) {
601
+ packedDeltaLow = lowerWord;
602
+ packedDeltaHigh = middleWord & highMask;
603
+ } else {
604
+ const upperByte = buffer[byteOffset + 8] ?? 0;
605
+ packedDeltaLow = ((lowerWord >>> shift) | (middleWord << (32 - shift))) >>> 0;
606
+ packedDeltaHigh = ((middleWord >>> shift) | (upperByte << (32 - shift))) & highMask;
607
+ }
608
+ const lowSum = stateLow + minimumDeltaLow + packedDeltaLow;
609
+ stateLow = lowSum >>> 0;
610
+ // V8 strength-reduces division by this constant; explicit carry branches benchmark slower.
611
+ stateHigh =
612
+ (stateHigh + minimumDeltaHigh + packedDeltaHigh + Math.floor(lowSum / UINT32_BASE)) >>> 0;
613
+ const wordOffset = (outputOffset + index) * 2;
614
+ outputWords[wordOffset + lowWordOffset] = stateLow;
615
+ outputWords[wordOffset + highWordOffset] = stateHigh;
616
+ }
617
+ state[0] = stateLow;
618
+ state[1] = stateHigh;
619
+ }
620
+
621
+ /** Decodes an INT64 mini-block whose packed deltas fit a 32-bit bit reservoir. */
622
+ function decodeNarrowInt64ArrowMiniBlock(
623
+ buffer: Uint8Array,
624
+ packedOffset: number,
625
+ bitWidth: number,
626
+ count: number,
627
+ minimumDeltaLow: number,
628
+ minimumDeltaHigh: number,
629
+ state: Uint32Array,
630
+ outputWords: Uint32Array,
631
+ outputOffset: number
632
+ ): void {
633
+ const mask = 2 ** bitWidth - 1;
634
+ const lowWordOffset = IS_LITTLE_ENDIAN ? 0 : 1;
635
+ const highWordOffset = IS_LITTLE_ENDIAN ? 1 : 0;
636
+ let stateLow = state[0];
637
+ let stateHigh = state[1];
638
+ let packedBits = 0;
639
+ let packedBitCount = 0;
640
+ let byteOffset = packedOffset;
641
+
642
+ for (let index = 0; index < count; index++) {
643
+ while (packedBitCount < bitWidth) {
644
+ packedBits |= buffer[byteOffset++] << packedBitCount;
645
+ packedBitCount += 8;
646
+ }
647
+ const packedDelta = packedBits & mask;
648
+ packedBits >>>= bitWidth;
649
+ packedBitCount -= bitWidth;
650
+ const lowSum = stateLow + minimumDeltaLow + packedDelta;
651
+ stateLow = lowSum >>> 0;
652
+ // V8 strength-reduces division by this constant; explicit carry branches benchmark slower.
653
+ stateHigh = (stateHigh + minimumDeltaHigh + Math.floor(lowSum / UINT32_BASE)) >>> 0;
654
+ const wordOffset = (outputOffset + index) * 2;
655
+ outputWords[wordOffset + lowWordOffset] = stateLow;
656
+ outputWords[wordOffset + highWordOffset] = stateHigh;
657
+ }
658
+ state[0] = stateLow;
659
+ state[1] = stateHigh;
660
+ }
661
+
662
+ /** Reads an unaligned little-endian word, treating bytes beyond a mini-block as zero. */
663
+ function readUint32LELoose(buffer: Uint8Array, offset: number): number {
664
+ return (
665
+ ((buffer[offset] ?? 0) |
666
+ ((buffer[offset + 1] ?? 0) << 8) |
667
+ ((buffer[offset + 2] ?? 0) << 16) |
668
+ ((buffer[offset + 3] ?? 0) << 24)) >>>
669
+ 0
670
+ );
671
+ }
672
+
673
+ /** Writes one pair of 32-bit words into a platform-endian BigInt64Array backing buffer. */
674
+ function writeInt64Words(
675
+ outputWords: Uint32Array,
676
+ outputIndex: number,
677
+ low: number,
678
+ high: number
679
+ ): void {
680
+ const wordOffset = outputIndex * 2;
681
+ outputWords[wordOffset + (IS_LITTLE_ENDIAN ? 0 : 1)] = low;
682
+ outputWords[wordOffset + (IS_LITTLE_ENDIAN ? 1 : 0)] = high;
683
+ }
684
+
374
685
  /** Decodes one INT64 mini-block, using numbers whenever the packed value remains exact. */
375
686
  function decodeInt64MiniBlock(
376
687
  buffer: Uint8Array,
@@ -457,14 +768,49 @@ export function decodeDeltaLengthByteArrayValues(
457
768
  options: ParquetCodecOptions
458
769
  ): ParquetValueBuffer {
459
770
  assertByteArrayType(type, 'DELTA_LENGTH_BYTE_ARRAY');
460
- const lengths = decodeDeltaBinaryPackedValues('INT32', cursor, count, {});
771
+ const lengths = new Int32Array(count);
772
+ decodeDeltaBinaryPackedValues('INT32', cursor, count, {output: lengths});
773
+ if (options.byteArrayOutput) {
774
+ return decodeDeltaLengthByteArraysToContiguousOutput(cursor, lengths, options);
775
+ }
461
776
  const {output, outputOffset} = getParquetValueOutput(options, count);
462
777
  for (let index = 0; index < count; index++) {
463
- output[outputOffset + index] = readByteArray(cursor, Number(lengths[index]));
778
+ output[outputOffset + index] = readByteArray(cursor, lengths[index]);
464
779
  }
465
780
  return output;
466
781
  }
467
782
 
783
+ /** Copies DELTA_LENGTH_BYTE_ARRAY's contiguous payload directly into an Arrow byte buffer. */
784
+ function decodeDeltaLengthByteArraysToContiguousOutput(
785
+ cursor: CursorBuffer,
786
+ lengths: Int32Array,
787
+ options: ParquetCodecOptions
788
+ ): ParquetValueBuffer {
789
+ const byteArrayOutput = options.byteArrayOutput!;
790
+ const outputOffset = options.outputOffset || 0;
791
+ let payloadByteLength = 0;
792
+ for (const length of lengths) {
793
+ if (length < 0) {
794
+ throw new Error(`Invalid delta byte-array length ${length}`);
795
+ }
796
+ payloadByteLength += length;
797
+ }
798
+ assertReadable(cursor, payloadByteLength);
799
+ reserveParquetByteArrayOutput(byteArrayOutput, payloadByteLength);
800
+
801
+ let byteOffset = byteArrayOutput.byteLength;
802
+ byteArrayOutput.valueOffsets[outputOffset] = byteOffset;
803
+ const payloadEnd = cursor.offset + payloadByteLength;
804
+ byteArrayOutput.data.set(cursor.buffer.subarray(cursor.offset, payloadEnd), byteOffset);
805
+ cursor.offset = payloadEnd;
806
+ for (let valueIndex = 0; valueIndex < lengths.length; valueIndex++) {
807
+ byteOffset += lengths[valueIndex];
808
+ byteArrayOutput.valueOffsets[outputOffset + valueIndex + 1] = byteOffset;
809
+ }
810
+ byteArrayOutput.byteLength = byteOffset;
811
+ return options.output || [];
812
+ }
813
+
468
814
  /** Decodes prefix lengths and delta-length suffixes into complete byte-array values. */
469
815
  export function decodeDeltaByteArrayValues(
470
816
  type: PrimitiveType,
@@ -473,17 +819,25 @@ export function decodeDeltaByteArrayValues(
473
819
  options: ParquetCodecOptions
474
820
  ): ParquetValueBuffer {
475
821
  assertByteArrayType(type, 'DELTA_BYTE_ARRAY');
476
- const prefixLengths = decodeDeltaBinaryPackedValues('INT32', cursor, count, {});
477
- const suffixes = decodeDeltaLengthByteArrayValues(type, cursor, count, {});
822
+ // One combined allocation is faster than separate prefix/suffix buffers in V8. Keep the two
823
+ // subarray views: reusing Arrow offsets as scratch storage deoptimizes reconstruction.
824
+ const lengths = new Int32Array(count * 2);
825
+ const prefixLengths = lengths.subarray(0, count);
826
+ const suffixLengths = lengths.subarray(count);
827
+ decodeDeltaBinaryPackedValues('INT32', cursor, count, {output: prefixLengths});
828
+ decodeDeltaBinaryPackedValues('INT32', cursor, count, {output: suffixLengths});
829
+ if (options.byteArrayOutput) {
830
+ return decodeDeltaByteArraysToContiguousOutput(cursor, prefixLengths, suffixLengths, options);
831
+ }
478
832
  const {output, outputOffset} = getParquetValueOutput(options, count);
479
833
  let previousValue: Uint8Array | undefined;
480
834
 
481
835
  for (let index = 0; index < count; index++) {
482
- const prefixLength = Number(prefixLengths[index]);
483
- const suffix = suffixes[index] as Uint8Array;
836
+ const prefixLength = prefixLengths[index];
484
837
  if (prefixLength < 0 || (prefixLength > 0 && prefixLength > (previousValue?.length || 0))) {
485
838
  throw new Error(`Invalid DELTA_BYTE_ARRAY prefix length ${prefixLength}`);
486
839
  }
840
+ const suffix = readByteArray(cursor, suffixLengths[index]);
487
841
  if (prefixLength === 0) {
488
842
  output[outputOffset + index] = suffix;
489
843
  previousValue = suffix;
@@ -499,6 +853,76 @@ export function decodeDeltaByteArrayValues(
499
853
  return output;
500
854
  }
501
855
 
856
+ /** Reconstructs DELTA_BYTE_ARRAY values directly in one Arrow-compatible byte buffer. */
857
+ function decodeDeltaByteArraysToContiguousOutput(
858
+ cursor: CursorBuffer,
859
+ prefixLengths: Int32Array,
860
+ suffixLengths: Int32Array,
861
+ options: ParquetCodecOptions
862
+ ): ParquetValueBuffer {
863
+ const byteArrayOutput = options.byteArrayOutput!;
864
+ const outputOffset = options.outputOffset || 0;
865
+ let byteOffset = byteArrayOutput.byteLength;
866
+ let previousValueOffset = byteOffset;
867
+ let previousValueLength = 0;
868
+ byteArrayOutput.valueOffsets[outputOffset] = byteOffset;
869
+
870
+ let requiredByteLength = 0;
871
+ let requiredSuffixByteLength = 0;
872
+ for (let valueIndex = 0; valueIndex < prefixLengths.length; valueIndex++) {
873
+ const prefixLength = prefixLengths[valueIndex];
874
+ const suffixLength = suffixLengths[valueIndex];
875
+ if (prefixLength < 0 || prefixLength > previousValueLength) {
876
+ throw new Error(`Invalid DELTA_BYTE_ARRAY prefix length ${prefixLength}`);
877
+ }
878
+ if (suffixLength < 0) {
879
+ throw new Error(`Invalid delta byte-array length ${suffixLength}`);
880
+ }
881
+ previousValueLength = prefixLength + suffixLength;
882
+ requiredByteLength += previousValueLength;
883
+ requiredSuffixByteLength += suffixLength;
884
+ }
885
+ assertReadable(cursor, requiredSuffixByteLength);
886
+ reserveParquetByteArrayOutput(byteArrayOutput, requiredByteLength);
887
+
888
+ const data = byteArrayOutput.data;
889
+ const valueOffsets = byteArrayOutput.valueOffsets;
890
+ const inputBuffer = cursor.buffer;
891
+ let inputOffset = cursor.offset;
892
+ previousValueLength = 0;
893
+ for (let valueIndex = 0; valueIndex < prefixLengths.length; valueIndex++) {
894
+ const prefixLength = prefixLengths[valueIndex];
895
+ const suffixLength = suffixLengths[valueIndex];
896
+ const valueLength = prefixLength + suffixLength;
897
+ if (prefixLength > 0) {
898
+ if (prefixLength <= 15) {
899
+ for (let byteIndex = 0; byteIndex < prefixLength; byteIndex++) {
900
+ data[byteOffset + byteIndex] = data[previousValueOffset + byteIndex];
901
+ }
902
+ } else {
903
+ data.copyWithin(byteOffset, previousValueOffset, previousValueOffset + prefixLength);
904
+ }
905
+ }
906
+ const suffixEnd = inputOffset + suffixLength;
907
+ if (suffixLength <= 15) {
908
+ let suffixOutputOffset = byteOffset + prefixLength;
909
+ while (inputOffset < suffixEnd) {
910
+ data[suffixOutputOffset++] = inputBuffer[inputOffset++];
911
+ }
912
+ } else {
913
+ data.set(inputBuffer.subarray(inputOffset, suffixEnd), byteOffset + prefixLength);
914
+ inputOffset = suffixEnd;
915
+ }
916
+ previousValueOffset = byteOffset;
917
+ previousValueLength = valueLength;
918
+ byteOffset += valueLength;
919
+ valueOffsets[outputOffset + valueIndex + 1] = byteOffset;
920
+ }
921
+ cursor.offset = inputOffset;
922
+ byteArrayOutput.byteLength = byteOffset;
923
+ return options.output || [];
924
+ }
925
+
502
926
  /** Reads and validates a sequence of one-byte mini-block bit widths. */
503
927
  function readBitWidths(cursor: CursorBuffer, count: number, maximumBitWidth: number): Uint8Array {
504
928
  assertReadable(cursor, count);
@@ -512,6 +936,42 @@ function readBitWidths(cursor: CursorBuffer, count: number, maximumBitWidth: num
512
936
  return bitWidths;
513
937
  }
514
938
 
939
+ /** Reads one signed zig-zag INT64 directly into its low and high two's-complement words. */
940
+ function readZigZagVarIntWords(cursor: CursorBuffer, words: Uint32Array): void {
941
+ let low = 0;
942
+ let high = 0;
943
+ for (let byteIndex = 0; byteIndex < 10; byteIndex++) {
944
+ assertReadable(cursor, 1);
945
+ const byte = cursor.buffer[cursor.offset++];
946
+ const payload = byte & 0x7f;
947
+ const bitOffset = byteIndex * 7;
948
+ if (byteIndex === 9 && payload > 1) {
949
+ throw new Error('Invalid Parquet variable-length integer');
950
+ }
951
+ if (bitOffset < 32) {
952
+ low |= payload << bitOffset;
953
+ if (bitOffset > 25) {
954
+ high |= payload >>> (32 - bitOffset);
955
+ }
956
+ } else {
957
+ high |= payload << (bitOffset - 32);
958
+ }
959
+ if ((byte & 0x80) === 0) {
960
+ const negative = low & 1;
961
+ let decodedLow = ((low >>> 1) | ((high & 1) << 31)) >>> 0;
962
+ let decodedHigh = high >>> 1;
963
+ if (negative) {
964
+ decodedLow = ~decodedLow >>> 0;
965
+ decodedHigh = ~decodedHigh >>> 0;
966
+ }
967
+ words[0] = decodedLow;
968
+ words[1] = decodedHigh;
969
+ return;
970
+ }
971
+ }
972
+ throw new Error('Invalid Parquet variable-length integer');
973
+ }
974
+
515
975
  /** Reads an unsigned base-128 variable-length integer. */
516
976
  function readUnsignedVarInt(cursor: CursorBuffer): bigint {
517
977
  let value = 0n;
@@ -23,6 +23,10 @@ export const PARQUET_CODECS: Record<ParquetCodec, ParquetCodecKit> = {
23
23
  encodeValues: RLE.encodeValues,
24
24
  decodeValues: RLE.decodeValues
25
25
  },
26
+ BIT_PACKED: {
27
+ encodeValues: RLE.encodeBitPackedValues,
28
+ decodeValues: RLE.decodeBitPackedValues
29
+ },
26
30
  // Using the PLAIN_DICTIONARY enum value is deprecated in the Parquet 2.0 specification.
27
31
  PLAIN_DICTIONARY: {
28
32
  // @ts-ignore