automerge-rb 0.1.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 (481) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +175 -0
  4. data/ext/automerge_ext/automerge_ext.c +1805 -0
  5. data/ext/automerge_ext/extconf.rb +132 -0
  6. data/lib/automerge/version.rb +6 -0
  7. data/lib/automerge.rb +110 -0
  8. data/rust-toolchain.toml +4 -0
  9. data/vendor/automerge-rust/Cargo.lock +1909 -0
  10. data/vendor/automerge-rust/Cargo.toml +15 -0
  11. data/vendor/automerge-rust/automerge/Cargo.toml +78 -0
  12. data/vendor/automerge-rust/automerge/README.md +5 -0
  13. data/vendor/automerge-rust/automerge/benches/load_save.rs +102 -0
  14. data/vendor/automerge-rust/automerge/benches/map.rs +260 -0
  15. data/vendor/automerge-rust/automerge/benches/range.rs +37 -0
  16. data/vendor/automerge-rust/automerge/benches/sync.rs +95 -0
  17. data/vendor/automerge-rust/automerge/examples/README.md +7 -0
  18. data/vendor/automerge-rust/automerge/examples/quickstart.rs +57 -0
  19. data/vendor/automerge-rust/automerge/examples/watch.rs +94 -0
  20. data/vendor/automerge-rust/automerge/fuzz/Cargo.toml +29 -0
  21. data/vendor/automerge-rust/automerge/fuzz/fuzz_targets/load.rs +37 -0
  22. data/vendor/automerge-rust/automerge/src/autocommit.rs +1286 -0
  23. data/vendor/automerge-rust/automerge/src/automerge/current_state.rs +546 -0
  24. data/vendor/automerge-rust/automerge/src/automerge/tests.rs +2023 -0
  25. data/vendor/automerge-rust/automerge/src/automerge.rs +2071 -0
  26. data/vendor/automerge-rust/automerge/src/autoserde.rs +128 -0
  27. data/vendor/automerge-rust/automerge/src/change.rs +357 -0
  28. data/vendor/automerge-rust/automerge/src/change_graph.rs +1215 -0
  29. data/vendor/automerge-rust/automerge/src/change_queue.rs +46 -0
  30. data/vendor/automerge-rust/automerge/src/clock.rs +206 -0
  31. data/vendor/automerge-rust/automerge/src/columnar/column_range/boolean.rs +83 -0
  32. data/vendor/automerge-rust/automerge/src/columnar/column_range/delta.rs +148 -0
  33. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/group.rs +138 -0
  34. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic/simple.rs +76 -0
  35. data/vendor/automerge-rust/automerge/src/columnar/column_range/generic.rs +93 -0
  36. data/vendor/automerge-rust/automerge/src/columnar/column_range/key.rs +272 -0
  37. data/vendor/automerge-rust/automerge/src/columnar/column_range/obj_id.rs +202 -0
  38. data/vendor/automerge-rust/automerge/src/columnar/column_range/opid_list.rs +329 -0
  39. data/vendor/automerge-rust/automerge/src/columnar/column_range/raw.rs +38 -0
  40. data/vendor/automerge-rust/automerge/src/columnar/column_range/rle.rs +216 -0
  41. data/vendor/automerge-rust/automerge/src/columnar/column_range/value.rs +547 -0
  42. data/vendor/automerge-rust/automerge/src/columnar/column_range.rs +17 -0
  43. data/vendor/automerge-rust/automerge/src/columnar/encoding/boolean.rs +197 -0
  44. data/vendor/automerge-rust/automerge/src/columnar/encoding/col_error.rs +88 -0
  45. data/vendor/automerge-rust/automerge/src/columnar/encoding/column_decoder.rs +133 -0
  46. data/vendor/automerge-rust/automerge/src/columnar/encoding/decodable_impls.rs +175 -0
  47. data/vendor/automerge-rust/automerge/src/columnar/encoding/delta.rs +96 -0
  48. data/vendor/automerge-rust/automerge/src/columnar/encoding/encodable_impls.rs +200 -0
  49. data/vendor/automerge-rust/automerge/src/columnar/encoding/leb128.rs +82 -0
  50. data/vendor/automerge-rust/automerge/src/columnar/encoding/properties.rs +178 -0
  51. data/vendor/automerge-rust/automerge/src/columnar/encoding/raw.rs +101 -0
  52. data/vendor/automerge-rust/automerge/src/columnar/encoding/rle.rs +239 -0
  53. data/vendor/automerge-rust/automerge/src/columnar/encoding.rs +67 -0
  54. data/vendor/automerge-rust/automerge/src/columnar/splice_error.rs +47 -0
  55. data/vendor/automerge-rust/automerge/src/columnar.rs +14 -0
  56. data/vendor/automerge-rust/automerge/src/convert.rs +112 -0
  57. data/vendor/automerge-rust/automerge/src/cursor.rs +296 -0
  58. data/vendor/automerge-rust/automerge/src/decoding.rs +475 -0
  59. data/vendor/automerge-rust/automerge/src/error.rs +159 -0
  60. data/vendor/automerge-rust/automerge/src/exid.rs +238 -0
  61. data/vendor/automerge-rust/automerge/src/hydrate/list.rs +140 -0
  62. data/vendor/automerge-rust/automerge/src/hydrate/map.rs +132 -0
  63. data/vendor/automerge-rust/automerge/src/hydrate/tests.rs +40 -0
  64. data/vendor/automerge-rust/automerge/src/hydrate/text.rs +89 -0
  65. data/vendor/automerge-rust/automerge/src/hydrate.rs +368 -0
  66. data/vendor/automerge-rust/automerge/src/indexed_cache.rs +113 -0
  67. data/vendor/automerge-rust/automerge/src/iter/doc.rs +603 -0
  68. data/vendor/automerge-rust/automerge/src/iter/keys.rs +93 -0
  69. data/vendor/automerge-rust/automerge/src/iter/list_range.rs +433 -0
  70. data/vendor/automerge-rust/automerge/src/iter/map_range.rs +316 -0
  71. data/vendor/automerge-rust/automerge/src/iter/spans.rs +601 -0
  72. data/vendor/automerge-rust/automerge/src/iter/tools.rs +427 -0
  73. data/vendor/automerge-rust/automerge/src/iter/values.rs +36 -0
  74. data/vendor/automerge-rust/automerge/src/iter.rs +25 -0
  75. data/vendor/automerge-rust/automerge/src/legacy/mod.rs +364 -0
  76. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/actor_id.rs +25 -0
  77. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/change_hash.rs +29 -0
  78. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/element_id.rs +27 -0
  79. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/mod.rs +31 -0
  80. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/object_id.rs +36 -0
  81. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op.rs +668 -0
  82. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/op_type.rs +26 -0
  83. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/opid.rs +25 -0
  84. data/vendor/automerge-rust/automerge/src/legacy/serde_impls/scalar_value.rs +63 -0
  85. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/element_id.rs +66 -0
  86. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/key.rs +49 -0
  87. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/mod.rs +4 -0
  88. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/object_id.rs +74 -0
  89. data/vendor/automerge-rust/automerge/src/legacy/utility_impls/opid.rs +68 -0
  90. data/vendor/automerge-rust/automerge/src/lib.rs +315 -0
  91. data/vendor/automerge-rust/automerge/src/marks.rs +478 -0
  92. data/vendor/automerge-rust/automerge/src/op_set2/change/batch.rs +2002 -0
  93. data/vendor/automerge-rust/automerge/src/op_set2/change/collector.rs +974 -0
  94. data/vendor/automerge-rust/automerge/src/op_set2/change.rs +332 -0
  95. data/vendor/automerge-rust/automerge/src/op_set2/columns.rs +714 -0
  96. data/vendor/automerge-rust/automerge/src/op_set2/meta.rs +174 -0
  97. data/vendor/automerge-rust/automerge/src/op_set2/op.rs +1363 -0
  98. data/vendor/automerge-rust/automerge/src/op_set2/op_set/elems.rs +43 -0
  99. data/vendor/automerge-rust/automerge/src/op_set2/op_set/found_op.rs +60 -0
  100. data/vendor/automerge-rust/automerge/src/op_set2/op_set/index.rs +197 -0
  101. data/vendor/automerge-rust/automerge/src/op_set2/op_set/insert.rs +179 -0
  102. data/vendor/automerge-rust/automerge/src/op_set2/op_set/mark_index.rs +292 -0
  103. data/vendor/automerge-rust/automerge/src/op_set2/op_set/marks.rs +86 -0
  104. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_iter.rs +1295 -0
  105. data/vendor/automerge-rust/automerge/src/op_set2/op_set/op_query.rs +82 -0
  106. data/vendor/automerge-rust/automerge/src/op_set2/op_set/top_op.rs +50 -0
  107. data/vendor/automerge-rust/automerge/src/op_set2/op_set/visible.rs +290 -0
  108. data/vendor/automerge-rust/automerge/src/op_set2/op_set.rs +1793 -0
  109. data/vendor/automerge-rust/automerge/src/op_set2/parents.rs +133 -0
  110. data/vendor/automerge-rust/automerge/src/op_set2/skip_list.rs +714 -0
  111. data/vendor/automerge-rust/automerge/src/op_set2/types.rs +769 -0
  112. data/vendor/automerge-rust/automerge/src/op_set2.rs +18 -0
  113. data/vendor/automerge-rust/automerge/src/patches/patch.rs +95 -0
  114. data/vendor/automerge-rust/automerge/src/patches/patch_builder.rs +382 -0
  115. data/vendor/automerge-rust/automerge/src/patches/patch_log.rs +584 -0
  116. data/vendor/automerge-rust/automerge/src/patches.rs +7 -0
  117. data/vendor/automerge-rust/automerge/src/query/list_state.rs +230 -0
  118. data/vendor/automerge-rust/automerge/src/query/seek_mark.rs +142 -0
  119. data/vendor/automerge-rust/automerge/src/read.rs +326 -0
  120. data/vendor/automerge-rust/automerge/src/sequence_tree.rs +662 -0
  121. data/vendor/automerge-rust/automerge/src/storage/bundle/builder.rs +942 -0
  122. data/vendor/automerge-rust/automerge/src/storage/bundle/error.rs +42 -0
  123. data/vendor/automerge-rust/automerge/src/storage/bundle/meta.rs +23 -0
  124. data/vendor/automerge-rust/automerge/src/storage/bundle/storage.rs +146 -0
  125. data/vendor/automerge-rust/automerge/src/storage/bundle.rs +210 -0
  126. data/vendor/automerge-rust/automerge/src/storage/change/change_actors.rs +311 -0
  127. data/vendor/automerge-rust/automerge/src/storage/change/change_op_columns.rs +621 -0
  128. data/vendor/automerge-rust/automerge/src/storage/change/compressed.rs +51 -0
  129. data/vendor/automerge-rust/automerge/src/storage/change/op_with_change_actors.rs +1 -0
  130. data/vendor/automerge-rust/automerge/src/storage/change.rs +523 -0
  131. data/vendor/automerge-rust/automerge/src/storage/chunk.rs +312 -0
  132. data/vendor/automerge-rust/automerge/src/storage/columns/column.rs +42 -0
  133. data/vendor/automerge-rust/automerge/src/storage/columns/column_builder.rs +199 -0
  134. data/vendor/automerge-rust/automerge/src/storage/columns/column_specification.rs +340 -0
  135. data/vendor/automerge-rust/automerge/src/storage/columns/raw_column.rs +286 -0
  136. data/vendor/automerge-rust/automerge/src/storage/columns.rs +355 -0
  137. data/vendor/automerge-rust/automerge/src/storage/document/compression.rs +362 -0
  138. data/vendor/automerge-rust/automerge/src/storage/document.rs +411 -0
  139. data/vendor/automerge-rust/automerge/src/storage/load/change_collector.rs +15 -0
  140. data/vendor/automerge-rust/automerge/src/storage/load.rs +136 -0
  141. data/vendor/automerge-rust/automerge/src/storage/parse/leb128.rs +302 -0
  142. data/vendor/automerge-rust/automerge/src/storage/parse.rs +619 -0
  143. data/vendor/automerge-rust/automerge/src/storage/save/document.rs +27 -0
  144. data/vendor/automerge-rust/automerge/src/storage.rs +26 -0
  145. data/vendor/automerge-rust/automerge/src/sync/bloom.rs +161 -0
  146. data/vendor/automerge-rust/automerge/src/sync/message_builder.rs +118 -0
  147. data/vendor/automerge-rust/automerge/src/sync/state.rs +214 -0
  148. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/bloom.rs +162 -0
  149. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/mod.rs +625 -0
  150. data/vendor/automerge-rust/automerge/src/sync/v1_compat_test/state.rs +120 -0
  151. data/vendor/automerge-rust/automerge/src/sync.rs +2482 -0
  152. data/vendor/automerge-rust/automerge/src/text_diff/LICENSE +201 -0
  153. data/vendor/automerge-rust/automerge/src/text_diff/myers.rs +332 -0
  154. data/vendor/automerge-rust/automerge/src/text_diff/replace.rs +139 -0
  155. data/vendor/automerge-rust/automerge/src/text_diff/utils.rs +119 -0
  156. data/vendor/automerge-rust/automerge/src/text_diff.rs +515 -0
  157. data/vendor/automerge-rust/automerge/src/text_value.rs +276 -0
  158. data/vendor/automerge-rust/automerge/src/transaction/commit.rs +34 -0
  159. data/vendor/automerge-rust/automerge/src/transaction/inner.rs +1403 -0
  160. data/vendor/automerge-rust/automerge/src/transaction/manual_transaction.rs +147 -0
  161. data/vendor/automerge-rust/automerge/src/transaction/owned_transaction.rs +266 -0
  162. data/vendor/automerge-rust/automerge/src/transaction/result.rs +21 -0
  163. data/vendor/automerge-rust/automerge/src/transaction/transactable.rs +203 -0
  164. data/vendor/automerge-rust/automerge/src/transaction.rs +513 -0
  165. data/vendor/automerge-rust/automerge/src/types.rs +749 -0
  166. data/vendor/automerge-rust/automerge/src/validation.rs +29 -0
  167. data/vendor/automerge-rust/automerge/src/value.rs +763 -0
  168. data/vendor/automerge-rust/automerge/tests/batch_insert.rs +1034 -0
  169. data/vendor/automerge-rust/automerge/tests/block_tests.rs +887 -0
  170. data/vendor/automerge-rust/automerge/tests/convert_string_to_text.rs +72 -0
  171. data/vendor/automerge-rust/automerge/tests/diff_marks.rs +1508 -0
  172. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_change.automerge +0 -0
  173. data/vendor/automerge-rust/automerge/tests/fixtures/64bit_obj_id_doc.automerge +0 -0
  174. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_has_incorrect_meta.automerge +0 -0
  175. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_ok.automerge +0 -0
  176. data/vendor/automerge-rust/automerge/tests/fixtures/counter_value_is_overlong.automerge +0 -0
  177. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks.automerge +0 -0
  178. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_compressed.automerge +0 -0
  179. data/vendor/automerge-rust/automerge/tests/fixtures/two_change_chunks_out_of_order.automerge +0 -0
  180. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/action-is-48.automerge +0 -0
  181. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/crash-da39a3ee5e6b4b0d3255bfef95601890afd80709 +0 -0
  182. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/incorrect_max_op.automerge +0 -0
  183. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/invalid_deflate_stream.automerge +0 -0
  184. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/missing_actor.automerge +0 -0
  185. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/overflow_in_length.automerge +0 -0
  186. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_deps.automerge +0 -0
  187. data/vendor/automerge-rust/automerge/tests/fuzz-crashers/too_many_ops.automerge +0 -0
  188. data/vendor/automerge-rust/automerge/tests/test.rs +2668 -0
  189. data/vendor/automerge-rust/automerge/tests/test_mark_patches.rs +41 -0
  190. data/vendor/automerge-rust/automerge/tests/test_save_load_orphans.rs +84 -0
  191. data/vendor/automerge-rust/automerge/tests/text.rs +1098 -0
  192. data/vendor/automerge-rust/automerge/tests/text_encoding.rs +640 -0
  193. data/vendor/automerge-rust/automerge-c/CMakeLists.txt +439 -0
  194. data/vendor/automerge-rust/automerge-c/Cargo.toml +22 -0
  195. data/vendor/automerge-rust/automerge-c/README.md +233 -0
  196. data/vendor/automerge-rust/automerge-c/build.rs +21 -0
  197. data/vendor/automerge-rust/automerge-c/cbindgen.toml +48 -0
  198. data/vendor/automerge-rust/automerge-c/cmake/Cargo.toml.in +22 -0
  199. data/vendor/automerge-rust/automerge-c/cmake/automerge-c-config.cmake.in +99 -0
  200. data/vendor/automerge-rust/automerge-c/cmake/cbindgen.toml.in +48 -0
  201. data/vendor/automerge-rust/automerge-c/cmake/config.h.in +58 -0
  202. data/vendor/automerge-rust/automerge-c/cmake/enum-string-functions-gen.cmake +183 -0
  203. data/vendor/automerge-rust/automerge-c/cmake/file-regex-replace.cmake +33 -0
  204. data/vendor/automerge-rust/automerge-c/cmake/file-touch.cmake +35 -0
  205. data/vendor/automerge-rust/automerge-c/docs/CMakeLists.txt +39 -0
  206. data/vendor/automerge-rust/automerge-c/docs/img/brandmark.png +0 -0
  207. data/vendor/automerge-rust/automerge-c/examples/CMakeLists.txt +42 -0
  208. data/vendor/automerge-rust/automerge-c/examples/README.md +9 -0
  209. data/vendor/automerge-rust/automerge-c/examples/quickstart.c +131 -0
  210. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/result.h +30 -0
  211. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack.h +130 -0
  212. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/stack_callback_data.h +53 -0
  213. data/vendor/automerge-rust/automerge-c/include/automerge-c/utils/string.h +29 -0
  214. data/vendor/automerge-rust/automerge-c/src/actor_id.rs +193 -0
  215. data/vendor/automerge-rust/automerge-c/src/byte_span.rs +227 -0
  216. data/vendor/automerge-rust/automerge-c/src/change.rs +356 -0
  217. data/vendor/automerge-rust/automerge-c/src/cursor.rs +168 -0
  218. data/vendor/automerge-rust/automerge-c/src/doc/list.rs +636 -0
  219. data/vendor/automerge-rust/automerge-c/src/doc/map.rs +556 -0
  220. data/vendor/automerge-rust/automerge-c/src/doc/mark.rs +296 -0
  221. data/vendor/automerge-rust/automerge-c/src/doc/utils.rs +46 -0
  222. data/vendor/automerge-rust/automerge-c/src/doc.rs +1009 -0
  223. data/vendor/automerge-rust/automerge-c/src/index.rs +84 -0
  224. data/vendor/automerge-rust/automerge-c/src/item.rs +2177 -0
  225. data/vendor/automerge-rust/automerge-c/src/items.rs +401 -0
  226. data/vendor/automerge-rust/automerge-c/src/lib.rs +11 -0
  227. data/vendor/automerge-rust/automerge-c/src/obj.rs +216 -0
  228. data/vendor/automerge-rust/automerge-c/src/result.rs +653 -0
  229. data/vendor/automerge-rust/automerge-c/src/sync/have.rs +42 -0
  230. data/vendor/automerge-rust/automerge-c/src/sync/message.rs +146 -0
  231. data/vendor/automerge-rust/automerge-c/src/sync/state.rs +262 -0
  232. data/vendor/automerge-rust/automerge-c/src/sync.rs +7 -0
  233. data/vendor/automerge-rust/automerge-c/src/utils/result.c +33 -0
  234. data/vendor/automerge-rust/automerge-c/src/utils/stack.c +106 -0
  235. data/vendor/automerge-rust/automerge-c/src/utils/stack_callback_data.c +9 -0
  236. data/vendor/automerge-rust/automerge-c/src/utils/string.c +46 -0
  237. data/vendor/automerge-rust/automerge-c/test/CMakeLists.txt +67 -0
  238. data/vendor/automerge-rust/automerge-c/test/actor_id_tests.c +140 -0
  239. data/vendor/automerge-rust/automerge-c/test/base_state.c +17 -0
  240. data/vendor/automerge-rust/automerge-c/test/base_state.h +39 -0
  241. data/vendor/automerge-rust/automerge-c/test/byte_span_tests.c +119 -0
  242. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.c +91 -0
  243. data/vendor/automerge-rust/automerge-c/test/cmocka_utils.h +42 -0
  244. data/vendor/automerge-rust/automerge-c/test/cursor_tests.c +263 -0
  245. data/vendor/automerge-rust/automerge-c/test/doc_state.c +27 -0
  246. data/vendor/automerge-rust/automerge-c/test/doc_state.h +17 -0
  247. data/vendor/automerge-rust/automerge-c/test/doc_tests.c +335 -0
  248. data/vendor/automerge-rust/automerge-c/test/enum_string_tests.c +148 -0
  249. data/vendor/automerge-rust/automerge-c/test/files/brave-ape-49.automerge +0 -0
  250. data/vendor/automerge-rust/automerge-c/test/item_tests.c +313 -0
  251. data/vendor/automerge-rust/automerge-c/test/list_tests.c +544 -0
  252. data/vendor/automerge-rust/automerge-c/test/macro_utils.c +38 -0
  253. data/vendor/automerge-rust/automerge-c/test/macro_utils.h +23 -0
  254. data/vendor/automerge-rust/automerge-c/test/main.c +33 -0
  255. data/vendor/automerge-rust/automerge-c/test/map_tests.c +1610 -0
  256. data/vendor/automerge-rust/automerge-c/test/mark_tests.c +124 -0
  257. data/vendor/automerge-rust/automerge-c/test/ported_wasm/basic_tests.c +1642 -0
  258. data/vendor/automerge-rust/automerge-c/test/ported_wasm/cursor_tests.c +108 -0
  259. data/vendor/automerge-rust/automerge-c/test/ported_wasm/suite.c +17 -0
  260. data/vendor/automerge-rust/automerge-c/test/ported_wasm/sync_tests.c +1280 -0
  261. data/vendor/automerge-rust/automerge-c/test/str_utils.c +15 -0
  262. data/vendor/automerge-rust/automerge-c/test/str_utils.h +17 -0
  263. data/vendor/automerge-rust/automerge-test/Cargo.toml +17 -0
  264. data/vendor/automerge-rust/automerge-test/README.md +3 -0
  265. data/vendor/automerge-rust/automerge-test/src/lib.rs +487 -0
  266. data/vendor/automerge-rust/hexane/CHANGELOG.md +34 -0
  267. data/vendor/automerge-rust/hexane/Cargo.toml +47 -0
  268. data/vendor/automerge-rust/hexane/README.md +292 -0
  269. data/vendor/automerge-rust/hexane/RESULTS.txt +20 -0
  270. data/vendor/automerge-rust/hexane/TODO +18 -0
  271. data/vendor/automerge-rust/hexane/benches/insert.rs +82 -0
  272. data/vendor/automerge-rust/hexane/benches/seek.rs +77 -0
  273. data/vendor/automerge-rust/hexane/benches/splice.rs +82 -0
  274. data/vendor/automerge-rust/hexane/src/aggregate.rs +288 -0
  275. data/vendor/automerge-rust/hexane/src/boolean.rs +478 -0
  276. data/vendor/automerge-rust/hexane/src/columndata.rs +2540 -0
  277. data/vendor/automerge-rust/hexane/src/cursor.rs +756 -0
  278. data/vendor/automerge-rust/hexane/src/delta.rs +793 -0
  279. data/vendor/automerge-rust/hexane/src/encoder.rs +639 -0
  280. data/vendor/automerge-rust/hexane/src/leb128.rs +82 -0
  281. data/vendor/automerge-rust/hexane/src/lib.rs +95 -0
  282. data/vendor/automerge-rust/hexane/src/pack.rs +325 -0
  283. data/vendor/automerge-rust/hexane/src/raw.rs +314 -0
  284. data/vendor/automerge-rust/hexane/src/rle.rs +928 -0
  285. data/vendor/automerge-rust/hexane/src/slab/tree.rs +1373 -0
  286. data/vendor/automerge-rust/hexane/src/slab/writer.rs +535 -0
  287. data/vendor/automerge-rust/hexane/src/slab.rs +224 -0
  288. data/vendor/automerge-rust/hexane/src/test.rs +108 -0
  289. data/vendor/bundle/ruby/3.3.0/bin/rake +29 -0
  290. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler +29 -0
  291. data/vendor/bundle/ruby/3.3.0/bin/rake-compiler-dock +29 -0
  292. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/History.rdoc +1732 -0
  293. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Manifest.txt +32 -0
  294. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/README.rdoc +845 -0
  295. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/Rakefile +97 -0
  296. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/design_rationale.rb +54 -0
  297. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/hoe/minitest.rb +30 -0
  298. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/assertions.rb +850 -0
  299. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/autorun.rb +6 -0
  300. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/benchmark.rb +452 -0
  301. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/compress.rb +94 -0
  302. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/error_on_warning.rb +11 -0
  303. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/expectations.rb +321 -0
  304. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/hell.rb +11 -0
  305. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/manual_plugins.rb +16 -0
  306. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/mock.rb +327 -0
  307. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/parallel.rb +72 -0
  308. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride.rb +4 -0
  309. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/pride_plugin.rb +135 -0
  310. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/spec.rb +353 -0
  311. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test.rb +238 -0
  312. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/test_task.rb +324 -0
  313. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest/unit.rb +42 -0
  314. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/lib/minitest.rb +1250 -0
  315. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/metametameta.rb +150 -0
  316. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_assertions.rb +1677 -0
  317. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_benchmark.rb +137 -0
  318. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_mock.rb +1213 -0
  319. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_reporter.rb +437 -0
  320. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_spec.rb +1159 -0
  321. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test.rb +1374 -0
  322. data/vendor/bundle/ruby/3.3.0/gems/minitest-5.27.0/test/minitest/test_minitest_test_task.rb +57 -0
  323. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/History.rdoc +2454 -0
  324. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
  325. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/README.rdoc +155 -0
  326. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/command_line_usage.rdoc +171 -0
  327. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile1 +38 -0
  328. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/Rakefile2 +35 -0
  329. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/a.c +6 -0
  330. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/b.c +6 -0
  331. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/example/main.c +11 -0
  332. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/glossary.rdoc +42 -0
  333. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/jamis.rb +592 -0
  334. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/proto_rake.rdoc +127 -0
  335. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rake.1 +156 -0
  336. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rakefile.rdoc +635 -0
  337. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/doc/rational.rdoc +151 -0
  338. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/exe/rake +27 -0
  339. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/application.rb +847 -0
  340. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/backtrace.rb +25 -0
  341. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/clean.rb +78 -0
  342. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cloneable.rb +17 -0
  343. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb +122 -0
  344. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/default_loader.rb +15 -0
  345. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb +196 -0
  346. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/early_time.rb +22 -0
  347. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/core.rb +26 -0
  348. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/ext/string.rb +176 -0
  349. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb +25 -0
  350. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_list.rb +435 -0
  351. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_task.rb +58 -0
  352. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils.rb +137 -0
  353. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb +135 -0
  354. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb +57 -0
  355. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb +17 -0
  356. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/late_time.rb +18 -0
  357. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/linked_list.rb +112 -0
  358. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb +54 -0
  359. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/multi_task.rb +14 -0
  360. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/name_space.rb +38 -0
  361. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/options.rb +31 -0
  362. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/packagetask.rb +222 -0
  363. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/phony.rb +16 -0
  364. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/private_reader.rb +21 -0
  365. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/promise.rb +100 -0
  366. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb +30 -0
  367. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_module.rb +67 -0
  368. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb +27 -0
  369. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  370. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/scope.rb +43 -0
  371. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task.rb +434 -0
  372. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb +8 -0
  373. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_arguments.rb +113 -0
  374. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/task_manager.rb +333 -0
  375. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/tasklib.rb +12 -0
  376. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/testtask.rb +192 -0
  377. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb +49 -0
  378. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/thread_pool.rb +157 -0
  379. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/trace_output.rb +23 -0
  380. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/version.rb +10 -0
  381. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake/win32.rb +17 -0
  382. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/lib/rake.rb +69 -0
  383. data/vendor/bundle/ruby/3.3.0/gems/rake-13.4.2/rake.gemspec +102 -0
  384. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Gemfile +8 -0
  385. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/History.md +695 -0
  386. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/LICENSE.txt +20 -0
  387. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/README.md +476 -0
  388. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/Rakefile +15 -0
  389. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/appveyor.yml +22 -0
  390. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/bin/rake-compiler +24 -0
  391. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/cucumber.yml +4 -0
  392. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/compile.feature +79 -0
  393. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-compile.feature +23 -0
  394. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package-multi.feature +15 -0
  395. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/cross-package.feature +14 -0
  396. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-compile.feature +22 -0
  397. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-no-native-compile.feature +33 -0
  398. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/java-package.feature +24 -0
  399. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/package.feature +40 -0
  400. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/compilation.rb +70 -0
  401. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/cross_compilation.rb +27 -0
  402. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/execution.rb +52 -0
  403. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/folders.rb +32 -0
  404. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/gem.rb +46 -0
  405. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/step_definitions/java_compilation.rb +7 -0
  406. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/env.rb +10 -0
  407. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/file_template_helpers.rb +137 -0
  408. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/generator_helpers.rb +123 -0
  409. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/features/support/platform_extension_helpers.rb +27 -0
  410. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/baseextensiontask.rb +90 -0
  411. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/compiler_config.rb +38 -0
  412. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensioncompiler.rb +51 -0
  413. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/extensiontask.rb +589 -0
  414. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/lib/rake/javaextensiontask.rb +321 -0
  415. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bin/cross-ruby.rake +189 -0
  416. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/bootstrap.rake +11 -0
  417. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/common.rake +10 -0
  418. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/cucumber.rake +23 -0
  419. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/gem.rake +15 -0
  420. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-1.3.1/tasks/rspec.rake +9 -0
  421. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CHANGELOG.md +446 -0
  422. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/CONTRIBUTING.md +109 -0
  423. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.jruby +79 -0
  424. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Dockerfile.mri.erb +282 -0
  425. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Gemfile +8 -0
  426. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/LICENSE.txt +22 -0
  427. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/README.md +447 -0
  428. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/Rakefile +246 -0
  429. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/bin/rake-compiler-dock +18 -0
  430. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/buildkitd.toml +2 -0
  431. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/gem_helper.rb +54 -0
  432. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_i686.rb +18 -0
  433. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_musl_cross.sh +37 -0
  434. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_osxcross.sh +45 -0
  435. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/mk_pkg_config.sh +24 -0
  436. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/parallel_docker_build.rb +169 -0
  437. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0004-Enable-build-of-static-libruby.patch +38 -0
  438. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0005-build-miniruby-first.patch +16 -0
  439. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0006-ruby-4-rubyspec-capiext.patch +16 -0
  440. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/rcd-env.sh +6 -0
  441. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/runas +7 -0
  442. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sigfw.c +45 -0
  443. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_codesign +17 -0
  444. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_vbox +30 -0
  445. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/build/sudoers +1 -0
  446. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/colors.rb +43 -0
  447. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/docker_check.rb +356 -0
  448. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
  449. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/starter.rb +206 -0
  450. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/version.rb +4 -0
  451. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock.rb +151 -0
  452. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/Dockerfile +66 -0
  453. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/README.md +14 -0
  454. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/binutils-mingw-w64-ignore-check-errors.patch +13 -0
  455. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/gcc-mingw-w64-only-c-c++.patch +13 -0
  456. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/mingw-w64-enable-ucrt.patch +22 -0
  457. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/rake-compiler-dock.gemspec +34 -0
  458. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.alpine +17 -0
  459. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.debian +24 -0
  460. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/fixtures/mig_test_rpc.defs +8 -0
  461. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Gemfile +11 -0
  462. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Rakefile +97 -0
  463. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RcdTestExtService.java +19 -0
  464. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RubyRcdTest.java +16 -0
  465. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/extconf.rb +111 -0
  466. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.c +65 -0
  467. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.h +11 -0
  468. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/lib/rcd_test.rb +6 -0
  469. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/rcd_test.gemspec +28 -0
  470. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/test/test_basic.rb +49 -0
  471. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_environment_variables.rb +108 -0
  472. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_mig.rb +18 -0
  473. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_parallel_docker_build.rb +95 -0
  474. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_rubygems_plugins.rb +12 -0
  475. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_starter.rb +158 -0
  476. data/vendor/bundle/ruby/3.3.0/gems/rake-compiler-dock-1.12.0/test/test_versions.rb +82 -0
  477. data/vendor/bundle/ruby/3.3.0/specifications/minitest-5.27.0.gemspec +32 -0
  478. data/vendor/bundle/ruby/3.3.0/specifications/rake-13.4.2.gemspec +26 -0
  479. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-1.3.1.gemspec +33 -0
  480. data/vendor/bundle/ruby/3.3.0/specifications/rake-compiler-dock-1.12.0.gemspec +28 -0
  481. metadata +584 -0
@@ -0,0 +1,2540 @@
1
+ use super::aggregate::Acc;
2
+ use super::aggregate::Agg;
3
+ use super::cursor::{ColumnCursor, HasAcc, HasMinMax, HasPos, Run, RunIter, RunIterState};
4
+ use super::encoder::Encoder;
5
+ use super::pack::{MaybePackable, PackError, Packable};
6
+ use super::raw::RawReader;
7
+ use super::slab;
8
+ use super::slab::{Slab, SlabTree, SpanTree, SpanTreeIterState};
9
+ use super::Cow;
10
+
11
+ use std::borrow::Borrow;
12
+ use std::cmp::Ordering;
13
+ use std::fmt::Debug;
14
+ use std::marker::PhantomData;
15
+ use std::ops::{Bound, Range, RangeBounds};
16
+
17
+ /// A compressed, mutable column of optional typed values.
18
+ ///
19
+ /// `ColumnData<C>` stores a sequence of `Option<C::Item>` values using the encoding
20
+ /// determined by cursor type `C`. Data is held internally in a `SpanTree` of [`Slab`]s;
21
+ /// modifications replace individual slabs, leaving the rest untouched.
22
+ ///
23
+ /// # Common cursor types
24
+ ///
25
+ /// [`UIntCursor`](crate::UIntCursor), [`IntCursor`](crate::IntCursor),
26
+ /// [`StrCursor`](crate::StrCursor), [`ByteCursor`](crate::ByteCursor),
27
+ /// [`BooleanCursor`](crate::BooleanCursor), [`DeltaCursor`](crate::DeltaCursor),
28
+ /// [`RawCursor`](crate::RawCursor).
29
+ ///
30
+ /// # Example
31
+ ///
32
+ /// ```rust
33
+ /// use hexane::{ColumnData, UIntCursor};
34
+ /// use std::borrow::Cow;
35
+ ///
36
+ /// let mut col: ColumnData<UIntCursor> = ColumnData::new();
37
+ /// col.splice(0, 0, [1u64, 2, 3]);
38
+ /// assert_eq!(col.get(1), Some(Some(Cow::Owned(2))));
39
+ /// assert_eq!(col.to_vec(), vec![Some(1), Some(2), Some(3)]);
40
+ /// ```
41
+ #[derive(Debug, Clone)]
42
+ pub struct ColumnData<C: ColumnCursor> {
43
+ pub len: usize,
44
+ pub slabs: SpanTree<Slab, C::SlabIndex>,
45
+ #[cfg(feature = "slow_path_assertions")]
46
+ pub debug: Vec<C::Export>,
47
+ counter: usize,
48
+ _phantom: PhantomData<C>,
49
+ }
50
+
51
+ impl<C: ColumnCursor> Default for ColumnData<C> {
52
+ fn default() -> Self {
53
+ Self::new()
54
+ }
55
+ }
56
+
57
+ impl<C: ColumnCursor> PartialEq for ColumnData<C> {
58
+ fn eq(&self, other: &Self) -> bool {
59
+ // we could use run iter execept sometimes runs are broken across slab boundaries
60
+ // maybe a top level run_iter that glues runs together?
61
+ self.iter().eq(other.iter())
62
+ }
63
+ }
64
+
65
+ impl<C: ColumnCursor> ColumnData<C> {
66
+ /// Total number of bytes used by all slabs (encoded, compressed size).
67
+ pub fn byte_len(&self) -> usize {
68
+ self.slabs.iter().map(|s| s.as_slice().len()).sum()
69
+ }
70
+
71
+ /// Returns the value at `index`, or `None` if the index is out of bounds.
72
+ ///
73
+ /// The inner `Option` is `None` for null entries and `Some(value)` otherwise.
74
+ /// This is O(log n + B) where B is the number of encoded runs in the target slab.
75
+ /// For multiple sequential reads prefer [`ColumnData::iter`] or [`ColumnData::iter_range`].
76
+ pub fn get(&self, index: usize) -> Option<Option<Cow<'_, C::Item>>> {
77
+ let range = index..(index + 1);
78
+ let mut iter = self.iter_range(range);
79
+ iter.next()
80
+ }
81
+
82
+ /// Returns the change in accumulator between `index1` and `index2`, together with
83
+ /// the item at `index2`.
84
+ ///
85
+ /// Panics if `index1 > index2`.
86
+ pub fn get_acc_delta(&self, index1: usize, index2: usize) -> (Acc, Option<Cow<'_, C::Item>>) {
87
+ assert!(index1 <= index2);
88
+ let acc1 = self.get_acc(index1);
89
+ let mut iter = self.iter_range(index2..(index2 + 1));
90
+ let acc2 = iter.calculate_acc();
91
+ let item = iter.next().flatten();
92
+ (acc2 - acc1, item)
93
+ }
94
+
95
+ /// Returns the cumulative [`Acc`] for all items *before* `index`
96
+ /// (i.e. the sum of `agg(item)` for items `0..index`).
97
+ pub fn get_acc(&self, index: usize) -> Acc {
98
+ let range = index..(index + 1);
99
+ let iter = self.iter_range(range);
100
+ iter.calculate_acc()
101
+ }
102
+
103
+ /// Returns the item at `index` together with the [`Acc`] value immediately before it,
104
+ /// or `None` if the index is out of bounds.
105
+ pub fn get_with_acc(
106
+ &self,
107
+ index: usize,
108
+ ) -> Option<ColGroupItem<'_, <C as ColumnCursor>::Item>> {
109
+ let range = index..(index + 1);
110
+ let mut iter = self.iter_range(range).with_acc();
111
+ iter.next()
112
+ }
113
+
114
+ /// Returns `true` if every item in the column is null (`None`) or, for
115
+ /// [`BooleanCursor`](crate::BooleanCursor), if every value is `false`.
116
+ ///
117
+ /// An empty column (`len() == 0`) is also considered empty.
118
+ pub fn is_empty(&self) -> bool {
119
+ let run = self.iter().next_run();
120
+ match run {
121
+ None => true,
122
+ Some(run) if run.count != self.len => false,
123
+ Some(run) => C::is_empty(run.value),
124
+ }
125
+ }
126
+
127
+ pub fn dump(&self) {
128
+ let data = self.to_vec();
129
+ log!(" :: {:?}", data);
130
+ }
131
+
132
+ /// Returns a new column with every item transformed by `f`.
133
+ ///
134
+ /// Equivalent to consuming `self` and re-encoding all items through `f`.
135
+ /// For an in-place version see [`ColumnData::remap`].
136
+ // TODO: could be much faster if done a run at a time (delta runs are tricky)
137
+ pub fn and_remap<F>(self, f: F) -> Self
138
+ where
139
+ F: Fn(Option<Cow<'_, C::Item>>) -> Option<Cow<'_, C::Item>>,
140
+ {
141
+ // TODO this could be much faster
142
+ // if we did it a run at a time instead of an item at a time
143
+ // but delta runs are special and don't remap easily
144
+ let mut encoder = Encoder::new(false);
145
+ for item in self.iter() {
146
+ encoder.append_item(f(item));
147
+ }
148
+ //std::mem::swap(self, &mut col);
149
+ encoder.into_column_data()
150
+ }
151
+
152
+ /// Replaces the column with a re-encoded version where every item has been
153
+ /// transformed by `f`. For a consuming version see [`ColumnData::and_remap`].
154
+ // TODO: could be much faster if done a run at a time (delta runs are tricky)
155
+ pub fn remap<F>(&mut self, f: F)
156
+ where
157
+ F: Fn(Option<Cow<'_, C::Item>>) -> Option<Cow<'_, C::Item>>,
158
+ {
159
+ // TODO this could be much faster
160
+ // if we did it a run at a time instead of an item at a time
161
+ // but delta runs are special and don't remap easily
162
+ let mut encoder = Encoder::new(false);
163
+ for item in self.iter() {
164
+ encoder.append_item(f(item));
165
+ }
166
+ *self = encoder.into_column_data();
167
+ }
168
+
169
+ /// Like [`save_to`](ColumnData::save_to) but writes nothing if [`is_empty`](ColumnData::is_empty)
170
+ /// returns `true`, returning an empty range at the current end of `out`.
171
+ pub fn save_to_unless_empty(&self, out: &mut Vec<u8>) -> Range<usize> {
172
+ if self.is_empty() {
173
+ out.len()..out.len()
174
+ } else {
175
+ self.save_to(out)
176
+ }
177
+ }
178
+
179
+ /// Serializes the column by appending encoded bytes to `out`.
180
+ ///
181
+ /// Returns the byte range written (`out[range]` is the serialized column data).
182
+ /// The output is compatible with [`ColumnData::load`]. If the column is empty (zero items),
183
+ /// nothing is written and an empty range is returned.
184
+ pub fn save_to(&self, out: &mut Vec<u8>) -> Range<usize> {
185
+ let start = out.len();
186
+ #[allow(clippy::len_zero)]
187
+ if self.len() == 0 {
188
+ // is_empty() considers all false to be empty
189
+ return start..start;
190
+ }
191
+ if self.slabs.len() == 1 {
192
+ let slab = self.slabs.get(0).unwrap();
193
+ if slab.is_empty() {
194
+ let mut encoder: Encoder<C> = Encoder::with_capacity(2, true);
195
+ encoder.flush();
196
+ encoder.writer.write(out);
197
+ } else {
198
+ out.extend(slab.as_slice())
199
+ }
200
+ } else {
201
+ let mut encoder: Encoder<C> = Encoder::with_capacity(self.slabs.len() * 7, true);
202
+ for s in &self.slabs {
203
+ encoder.copy_slab(s);
204
+ }
205
+ encoder.flush();
206
+ encoder.writer.write(out);
207
+ }
208
+ let end = out.len();
209
+ start..end
210
+ }
211
+
212
+ pub fn raw_reader(&self, advance: usize) -> RawReader<'_, C::SlabIndex> {
213
+ let cursor = self
214
+ .slabs
215
+ .get_where_or_last(|acc, next| advance < acc.pos() + next.pos());
216
+ let current = Some((cursor.element, advance - cursor.weight.pos()));
217
+ let slabs = slab::SpanTreeIter::new(&self.slabs, cursor);
218
+ let pos = advance;
219
+ RawReader {
220
+ pos,
221
+ slabs,
222
+ current,
223
+ }
224
+ }
225
+ }
226
+
227
+ /// An iterator over items in a [`ColumnData`], with rich navigation capabilities.
228
+ ///
229
+ /// Produced by [`ColumnData::iter`] and [`ColumnData::iter_range`].
230
+ ///
231
+ /// Beyond standard `Iterator` usage, `ColumnDataIter` supports:
232
+ /// - [`advance_by`](ColumnDataIter::advance_by) / [`advance_to`](ColumnDataIter::advance_to)
233
+ /// — fast O(log n) forward jump.
234
+ /// - [`seek_to_value`](ColumnDataIter::seek_to_value) — binary search for a sorted value.
235
+ /// - [`advance_acc_by`](ColumnDataIter::advance_acc_by) — advance by accumulator amount.
236
+ /// - [`next_run`](ColumnDataIter::next_run) — access the raw RLE runs.
237
+ /// - [`shift_next`](ColumnDataIter::shift_next) — move the window and return the next item.
238
+ /// - [`suspend`](ColumnDataIter::suspend) / [`ColumnDataIterState::try_resume`] — serialize
239
+ /// and restore position across async boundaries or between calls.
240
+ /// - [`with_acc`](ColumnDataIter::with_acc) — wrap in a [`ColGroupIter`] that emits
241
+ /// `(acc, pos, item)` tuples.
242
+ /// - [`as_acc`](ColumnDataIter::as_acc) — wrap in a [`ColAccIter`] that emits only `Acc`.
243
+ #[derive(Debug)]
244
+ pub struct ColumnDataIter<'a, C: ColumnCursor> {
245
+ counter: usize,
246
+ pos: usize,
247
+ max: usize,
248
+ slabs: slab::SpanTreeIter<'a, Slab, C::SlabIndex>,
249
+ slab: RunIter<'a, C>,
250
+ run: Option<Run<'a, C::Item>>,
251
+ }
252
+
253
+ impl<C: ColumnCursor> Default for ColumnDataIter<'_, C> {
254
+ fn default() -> Self {
255
+ Self {
256
+ counter: 0,
257
+ pos: 0,
258
+ max: 0,
259
+ slabs: slab::SpanTreeIter::default(),
260
+ slab: RunIter::default(),
261
+ run: None,
262
+ }
263
+ }
264
+ }
265
+
266
+ impl<C: ColumnCursor> Clone for ColumnDataIter<'_, C> {
267
+ fn clone(&self) -> Self {
268
+ Self {
269
+ counter: self.counter,
270
+ pos: self.pos,
271
+ max: self.max,
272
+ slabs: self.slabs.clone(),
273
+ slab: self.slab,
274
+ run: self.run.clone(),
275
+ }
276
+ }
277
+ }
278
+
279
+ impl<'a, C: ColumnCursor> ColumnDataIter<'a, C> {
280
+ pub(crate) fn new(
281
+ slabs: &'a SlabTree<C::SlabIndex>,
282
+ pos: usize,
283
+ max: usize,
284
+ counter: usize,
285
+ ) -> Self {
286
+ let cursor = slabs.get_where_or_last(|acc, next| pos < acc.pos() + next.pos());
287
+ let mut slab = cursor.element.run_iter::<C>();
288
+ let slabs = slab::SpanTreeIter::new(slabs, cursor);
289
+ let iter_pos = slabs.weight().pos() - slab.pos_left();
290
+ let advance = pos - iter_pos;
291
+ let run = slab.sub_advance(advance);
292
+ ColumnDataIter {
293
+ counter,
294
+ pos,
295
+ max,
296
+ slabs,
297
+ slab,
298
+ run,
299
+ }
300
+ }
301
+
302
+ pub(crate) fn try_resume(
303
+ slab_tree: &'a SlabTree<C::SlabIndex>,
304
+ state: &ColumnDataIterState<C>,
305
+ counter: usize,
306
+ ) -> Result<Self, PackError> {
307
+ if counter != state.counter {
308
+ return Err(PackError::InvalidResume);
309
+ }
310
+ if slab_tree.len() != state.num_slabs {
311
+ return Err(PackError::InvalidResume);
312
+ }
313
+ let counter = state.counter;
314
+ let pos = state.pos;
315
+ let max = state.max;
316
+ let slabs = slab_tree.resume(state.slabs_state.clone());
317
+ let s = slabs.current().unwrap();
318
+ let slab = RunIter::resume(s.as_slice(), state.run_state);
319
+ let run = slab.current().map(|r| Run {
320
+ count: state.run.unwrap(),
321
+ value: r.value,
322
+ });
323
+ Ok(ColumnDataIter {
324
+ counter,
325
+ pos,
326
+ max,
327
+ slabs,
328
+ slab,
329
+ run,
330
+ })
331
+ }
332
+
333
+ pub(crate) fn new_at_index(
334
+ slabs: &'a SlabTree<C::SlabIndex>,
335
+ index: usize,
336
+ max: usize,
337
+ counter: usize,
338
+ ) -> Self {
339
+ let cursor = slabs.get_cursor(index).unwrap();
340
+ let mut slab = cursor.element.run_iter::<C>();
341
+ let slabs = slab::SpanTreeIter::new(slabs, cursor);
342
+ let pos = slabs.weight().pos() - slab.pos_left();
343
+ let run = slab.sub_advance(0);
344
+ assert!(pos < max);
345
+ ColumnDataIter {
346
+ counter,
347
+ pos,
348
+ max,
349
+ slabs,
350
+ slab,
351
+ run,
352
+ }
353
+ }
354
+
355
+ pub(crate) fn new_at_acc(
356
+ slabs: &'a SlabTree<C::SlabIndex>,
357
+ acc: Acc,
358
+ max: usize,
359
+ counter: usize,
360
+ ) -> Self {
361
+ let cursor = slabs.get_where_or_last(|a, next| acc < a.acc() + next.acc());
362
+ let mut slab = cursor.element.run_iter();
363
+ let pos = cursor.weight.pos();
364
+ let slabs = slab::SpanTreeIter::new(slabs, cursor);
365
+ let run = slab.sub_advance(0);
366
+ ColumnDataIter {
367
+ counter,
368
+ pos,
369
+ max,
370
+ slabs,
371
+ slab,
372
+ run,
373
+ }
374
+ }
375
+
376
+ /// Returns the current position (index of the next item to be yielded).
377
+ pub fn pos(&self) -> usize {
378
+ debug_assert_eq!(
379
+ self.slabs.weight().pos() - self.slab.pos_left() - self.run_count(),
380
+ self.pos
381
+ );
382
+ std::cmp::min(self.pos, self.max)
383
+ }
384
+
385
+ fn check_pos(&self) {
386
+ debug_assert_eq!(
387
+ self.slabs.weight().pos() - self.slab.pos_left() - self.run_count(),
388
+ self.pos
389
+ );
390
+ }
391
+
392
+ /// Returns the number of items remaining in the current [`Run`].
393
+ pub fn run_count(&self) -> usize {
394
+ self.run.as_ref().map(|e| e.count).unwrap_or_default()
395
+ }
396
+
397
+ fn run_acc(&self) -> Acc {
398
+ self.run.as_ref().map(|e| e.acc()).unwrap_or_default()
399
+ }
400
+
401
+ fn pop_element(&mut self) -> Option<Option<Cow<'a, C::Item>>> {
402
+ self.slab.cursor.pop(self.run.as_mut()?)
403
+ }
404
+
405
+ /// Returns the next RLE [`Run`], advancing `pos` by `run.count`.
406
+ ///
407
+ /// More efficient than calling `next()` repeatedly when you only need run-level access.
408
+ /// Returns `None` when the iterator is exhausted.
409
+ pub fn next_run(&mut self) -> Option<Run<'a, C::Item>> {
410
+ if self.pos >= self.max {
411
+ return None;
412
+ }
413
+ let mut run = self.run.take().or_else(|| self.pop_run())?;
414
+ let count = run.count;
415
+ if self.pos + run.count > self.max {
416
+ let remainder = self.max - self.pos;
417
+ let overflow = run.count - remainder;
418
+ run.count = remainder;
419
+ self.run = Some(Run {
420
+ value: run.value.clone(),
421
+ count: overflow,
422
+ });
423
+ self.pos += remainder;
424
+ } else {
425
+ self.pos += count;
426
+ }
427
+ self.check_pos();
428
+ if run.count == 0 {
429
+ self.next_run()
430
+ } else {
431
+ Some(run)
432
+ }
433
+ }
434
+
435
+ fn pop_run(&mut self) -> Option<Run<'a, C::Item>> {
436
+ self.slab.next().or_else(|| {
437
+ self.slab = self.slabs.next()?.run_iter();
438
+ self.slab.next()
439
+ })
440
+ }
441
+
442
+ /// Advances the iterator by `amount` items in O(log n). A no-op if `amount` is 0.
443
+ pub fn advance_by(&mut self, amount: usize) {
444
+ if amount > 0 {
445
+ self.nth(amount - 1);
446
+ }
447
+ self.check_pos();
448
+ }
449
+
450
+ /// Advances the iterator to position `target` in O(log n).
451
+ ///
452
+ /// Panics if `target < self.pos()`.
453
+ pub fn advance_to(&mut self, target: usize) {
454
+ assert!(target >= self.pos());
455
+ if target > self.pos() {
456
+ self.advance_by(target - self.pos());
457
+ }
458
+ //assert_eq!(target, self.pos()); // max can stop this
459
+ }
460
+
461
+ fn slab_index(&self) -> usize {
462
+ self.slabs.index() - 1
463
+ }
464
+
465
+ // Binary search through the span tree nodes to find the slab likely containing `target`.
466
+ // Only valid when data is sorted within the range. Reads only the first element of each
467
+ // node; never reads the first node because we may not be including its first element.
468
+ fn binary_search_for<B>(&self, target: Option<B>, max: usize) -> Option<usize>
469
+ where
470
+ B: Borrow<C::Item> + Debug + Copy,
471
+ C::Item: Ord,
472
+ {
473
+ let original_start = self.slab_index();
474
+ let mut start = original_start;
475
+
476
+ let next_slab_value = self.slabs.peek()?.first_value::<C>();
477
+ match _cmp(next_slab_value.clone(), &target) {
478
+ Ordering::Greater => {
479
+ return None;
480
+ }
481
+ Ordering::Less => {
482
+ // not in current slab
483
+ //start += 1;
484
+ }
485
+ Ordering::Equal => (), // could still be in current slab
486
+ }
487
+
488
+ let slabs = self.slabs.span_tree()?;
489
+ let mut end = slabs
490
+ .get_where_or_last(|a, next| max < a.pos() + next.pos())
491
+ .index;
492
+ let mut mid = (start + end).div_ceil(2);
493
+ while start < mid && mid < end {
494
+ let value = slabs.get(mid)?.first_value::<C>();
495
+ if _cmp(value, &target) == Ordering::Less {
496
+ start = mid;
497
+ } else {
498
+ end = mid;
499
+ }
500
+ mid = (start + end).div_ceil(2);
501
+ }
502
+ if start != original_start {
503
+ assert!(start <= end);
504
+ Some(start)
505
+ } else {
506
+ None
507
+ }
508
+ }
509
+
510
+ /// Returns the contiguous index range where `value` appears within `range`, positioning
511
+ /// the iterator at the start of that range.
512
+ ///
513
+ /// **Requires** that values within `range` are sorted; gives undefined results otherwise.
514
+ /// Uses B-tree binary search followed by a linear slab scan.
515
+ /// Returns an empty range at the found position if `value` is absent.
516
+ ///
517
+ /// After returning, the iterator is positioned at the first index where `value` appears
518
+ /// (or where it would appear if absent), ready for further reads.
519
+ pub fn seek_to_value<B, R>(&mut self, value: Option<B>, range: R) -> Range<usize>
520
+ where
521
+ B: Borrow<C::Item> + Copy + Debug,
522
+ C::Item: Ord,
523
+ R: RangeBounds<usize>,
524
+ {
525
+ let (min, max) = normalize_range(range);
526
+ let max = std::cmp::min(max, self.max);
527
+
528
+ // FIXME - wasteful if we're gonna re-set
529
+ if min > self.pos() {
530
+ self.advance_to(min);
531
+ }
532
+
533
+ if let Some(index) = self.binary_search_for(value, max) {
534
+ self.reset_iter_to_slab_index(index);
535
+ }
536
+ let mut end = self.pos();
537
+ let mut first_run = self.run.take();
538
+ let mut found = None;
539
+ while let Some(mut run) = first_run.take().or_else(|| self.pop_run()) {
540
+ if run.count == 0 {
541
+ continue;
542
+ }
543
+ let c = run.count;
544
+ match _cmp(value, &run.value) {
545
+ Ordering::Equal if found.is_none() => {
546
+ let mut copy = self.clone();
547
+ copy.run = Some(run.clone());
548
+ found = Some(copy);
549
+ }
550
+ Ordering::Greater => {}
551
+ Ordering::Equal => {}
552
+ Ordering::Less => {
553
+ self.run = Some(run);
554
+ break;
555
+ }
556
+ }
557
+ self.pos += c;
558
+ end += c;
559
+ if self.pos >= max {
560
+ let delta = self.pos - max;
561
+ self.pos -= delta;
562
+ end -= delta;
563
+ run.count = delta;
564
+ self.run = Some(run);
565
+ break;
566
+ }
567
+ }
568
+ if let Some(f) = found {
569
+ // go back
570
+ *self = f;
571
+ }
572
+ let start = std::cmp::min(self.pos, max);
573
+ let end = std::cmp::min(end, max);
574
+ start..end
575
+ }
576
+
577
+ /// Returns the exclusive upper bound of the iteration range (as set by `iter_range` or `set_max`).
578
+ pub fn end_pos(&self) -> usize {
579
+ self.max
580
+ }
581
+
582
+ /// Overrides the upper bound of the iteration range.
583
+ pub fn set_max(&mut self, max: usize) {
584
+ self.max = max
585
+ }
586
+
587
+ /// Collects all remaining items into a `Vec`. Primarily useful for testing.
588
+ pub fn to_vec(self) -> Vec<C::Export> {
589
+ let mut result = vec![];
590
+ C::export_splice(&mut result, 0..0, self);
591
+ result
592
+ }
593
+
594
+ /// Wraps this iterator in a [`ColGroupIter`] that emits `(acc, pos, item)` tuples.
595
+ pub fn with_acc(self) -> ColGroupIter<'a, C> {
596
+ ColGroupIter { iter: self }
597
+ }
598
+
599
+ /// Wraps this iterator in a [`ColAccIter`] that emits only the [`Acc`] value for each item.
600
+ pub fn as_acc(self) -> ColAccIter<'a, C> {
601
+ ColAccIter { iter: self }
602
+ }
603
+
604
+ /// Returns the [`Acc`] value immediately before the current iterator position.
605
+ pub fn calculate_acc(&self) -> Acc {
606
+ self.slabs.weight().acc() - self.slab.acc_left() - self.run_acc()
607
+ }
608
+
609
+ fn reset_iter_to_pos(&mut self, pos: usize) -> Option<()> {
610
+ let tree = self.slabs.span_tree()?;
611
+ let pos = std::cmp::min(pos, self.max);
612
+ let new_iter = Self::new(tree, pos, self.max, self.counter);
613
+ let _ = std::mem::replace(self, new_iter);
614
+ Some(())
615
+ }
616
+
617
+ fn reset_iter_to_slab_index(&mut self, index: usize) -> Option<()> {
618
+ let tree = self.slabs.span_tree()?;
619
+ let new_iter = Self::new_at_index(tree, index, self.max, self.counter);
620
+ let _ = std::mem::replace(self, new_iter);
621
+ Some(())
622
+ }
623
+
624
+ fn reset_iter_to_acc(&mut self, acc: Acc) -> Acc {
625
+ if let Some(tree) = self.slabs.span_tree() {
626
+ let _ = std::mem::replace(self, Self::new_at_acc(tree, acc, self.max, self.counter));
627
+ let new_acc = self.calculate_acc();
628
+ acc - new_acc
629
+ } else {
630
+ Acc::default()
631
+ }
632
+ }
633
+
634
+ /// Moves the iterator window to `range` and returns the item at `range.start`.
635
+ ///
636
+ /// The iterator must already be at or before `range.start`. After this call, the
637
+ /// iterator will yield items from `range.start` up to (exclusive) `range.end`.
638
+ /// Subsequent calls to `shift_next` can extend the window further forward.
639
+ ///
640
+ /// Panics if `range.start < self.pos`.
641
+ pub fn shift_next(&mut self, range: Range<usize>) -> Option<<Self as Iterator>::Item> {
642
+ assert!(range.start >= self.pos);
643
+ self.max = range.end;
644
+ self.nth(range.start - self.pos)
645
+ }
646
+
647
+ fn total_acc(&self) -> Acc {
648
+ self.slabs
649
+ .total_weight()
650
+ .map(|w| w.acc())
651
+ .unwrap_or_default()
652
+ }
653
+
654
+ /// Advances the iterator until the cumulative [`Acc`] has grown by at least `n`.
655
+ ///
656
+ /// Returns the number of items consumed. If the total accumulator of the remaining
657
+ /// items is less than `n`, the iterator is exhausted and the actual advance is returned.
658
+ ///
659
+ /// This is O(log n) using the slab-level accumulator index.
660
+ pub fn advance_acc_by<A: Into<Acc>>(&mut self, n: A) -> usize {
661
+ let mut n = n.into();
662
+ let start_pos = self.pos();
663
+ let start = self.calculate_acc();
664
+ let target: Acc = self.calculate_acc() + n;
665
+
666
+ if start + n > self.total_acc() {
667
+ self.nth(self.max - self.pos);
668
+ } else {
669
+ if self.slabs.weight().acc() <= target {
670
+ n = self.reset_iter_to_acc(target);
671
+ }
672
+
673
+ if let Some(r) = self.run.as_mut() {
674
+ if r.acc() > n {
675
+ let advance = n / r.agg();
676
+ self.pos += advance;
677
+ r.count -= advance;
678
+ return self.pos() - start_pos;
679
+ }
680
+ self.pos += r.count;
681
+ n -= r.acc();
682
+ r.count = 0;
683
+ }
684
+ let (advance, run) = self.slab.sub_advance_acc(n);
685
+ self.run = run;
686
+ self.pos += advance;
687
+ self.check_pos();
688
+ }
689
+ self.pos() - start_pos
690
+ }
691
+
692
+ /// Captures the current iterator position as a [`ColumnDataIterState`] that can be
693
+ /// stored and later restored via [`ColumnDataIterState::try_resume`].
694
+ ///
695
+ /// Resumption will fail if the underlying `ColumnData` is mutated between suspend and resume.
696
+ pub fn suspend(&self) -> ColumnDataIterState<C> {
697
+ ColumnDataIterState {
698
+ counter: self.counter,
699
+ pos: self.pos,
700
+ max: self.max,
701
+ run_state: self.slab.suspend(),
702
+ slabs_state: self.slabs.suspend(),
703
+ num_slabs: self.slabs.span_tree().map_or(0, |t| t.len()),
704
+ run: self.run.as_ref().map(|r| r.count),
705
+ }
706
+ }
707
+ }
708
+
709
+ /// Serializable snapshot of a [`ColumnDataIter`] position.
710
+ ///
711
+ /// Created by [`ColumnDataIter::suspend`] and restored by [`try_resume`](ColumnDataIterState::try_resume).
712
+ /// Resumption returns [`PackError::InvalidResume`] if the source `ColumnData` was mutated
713
+ /// after the snapshot was taken.
714
+ pub struct ColumnDataIterState<C: ColumnCursor> {
715
+ counter: usize,
716
+ pos: usize,
717
+ max: usize,
718
+ run_state: RunIterState<C>,
719
+ slabs_state: SpanTreeIterState<C::SlabIndex>,
720
+ num_slabs: usize,
721
+ run: Option<usize>,
722
+ }
723
+
724
+ impl<C: ColumnCursor> ColumnDataIterState<C> {
725
+ /// Attempts to restore the iterator position in `column`.
726
+ ///
727
+ /// Returns [`PackError::InvalidResume`] if `column` was mutated since [`ColumnDataIter::suspend`].
728
+ pub fn try_resume<'a>(
729
+ &self,
730
+ column: &'a ColumnData<C>,
731
+ ) -> Result<ColumnDataIter<'a, C>, PackError> {
732
+ ColumnDataIter::try_resume(&column.slabs, self, column.counter)
733
+ }
734
+ }
735
+
736
+ /// An iterator adapter over [`ColumnDataIter`] that emits the [`Acc`] value after each item.
737
+ ///
738
+ /// Each `next()` call yields the cumulative accumulator *after* consuming the current item.
739
+ /// Created by [`ColumnDataIter::as_acc`].
740
+ #[derive(Debug, Default, Clone)]
741
+ pub struct ColAccIter<'a, C: ColumnCursor> {
742
+ iter: ColumnDataIter<'a, C>,
743
+ }
744
+
745
+ impl<C: ColumnCursor> ColAccIter<'_, C> {
746
+ pub fn shift_next(&mut self, range: Range<usize>) -> Option<<Self as Iterator>::Item> {
747
+ let _ = self.iter.shift_next(range);
748
+ let acc = self.acc();
749
+ Some(acc)
750
+ }
751
+
752
+ fn acc(&self) -> Acc {
753
+ self.iter.slabs.weight().acc() - self.iter.slab.acc_left() - self.iter.run_acc()
754
+ }
755
+ }
756
+
757
+ impl<C: ColumnCursor> Iterator for ColAccIter<'_, C> {
758
+ type Item = Acc;
759
+
760
+ fn next(&mut self) -> Option<Self::Item> {
761
+ let _ = self.iter.next()?;
762
+ let acc = self.acc();
763
+ Some(acc)
764
+ }
765
+
766
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
767
+ let _ = self.iter.nth(n)?;
768
+ let acc = self.acc();
769
+ Some(acc)
770
+ }
771
+ }
772
+
773
+ /// An iterator adapter over [`ColumnDataIter`] that emits [`ColGroupItem`] values.
774
+ ///
775
+ /// Each `next()` yields a `ColGroupItem { acc, pos, item }` where `acc` is the accumulator
776
+ /// *before* the item and `pos` is the item's index.
777
+ ///
778
+ /// **Important:** `nth(n)` advances by accumulator amount `n` rather than by item count `n`.
779
+ /// This is intentional for Automerge's internal use but deviates from the `Iterator` contract.
780
+ /// TODO: consider splitting this into two distinct types.
781
+ ///
782
+ /// Created by [`ColumnDataIter::with_acc`].
783
+ #[derive(Debug, Clone)]
784
+ pub struct ColGroupIter<'a, C: ColumnCursor> {
785
+ iter: ColumnDataIter<'a, C>,
786
+ }
787
+
788
+ impl<'a, C: ColumnCursor> ColGroupIter<'a, C> {
789
+ pub fn advance_by(&mut self, amount: usize) {
790
+ self.iter.advance_by(amount)
791
+ }
792
+
793
+ pub fn shift_acc(&mut self, n: usize) -> Option<ColGroupItem<'a, C::Item>> {
794
+ self.iter.advance_acc_by(n);
795
+ self.next()
796
+ }
797
+
798
+ pub fn run_count(&self) -> usize {
799
+ self.iter.run_count()
800
+ }
801
+
802
+ pub fn unwrap(self) -> ColumnDataIter<'a, C> {
803
+ self.iter
804
+ }
805
+
806
+ pub fn acc(&self) -> Acc {
807
+ self.iter.slabs.weight().acc() - self.iter.slab.acc_left() - self.iter.run_acc()
808
+ }
809
+ }
810
+
811
+ /// A single item from a [`ColGroupIter`], bundling the item with its position and
812
+ /// the pre-item accumulator.
813
+ ///
814
+ /// - `acc`: [`Acc`] value immediately *before* this item (sum of all prior `agg` values).
815
+ /// - `pos`: zero-based index of this item in the column.
816
+ /// - `item`: the value (`None` for null entries).
817
+ #[derive(Debug, PartialEq, Clone)]
818
+ pub struct ColGroupItem<'a, P: Packable + ?Sized> {
819
+ pub acc: Acc,
820
+ pub pos: usize,
821
+ pub item: Option<Cow<'a, P>>,
822
+ }
823
+
824
+ impl<P: Packable + ?Sized> ColGroupItem<'_, P> {
825
+ /// Returns the accumulator value *after* this item (`self.acc + agg(self.item)`).
826
+ pub fn next_acc(&self) -> Acc {
827
+ self.acc + P::maybe_agg(&self.item)
828
+ }
829
+ }
830
+
831
+ impl<'a, C: ColumnCursor> Iterator for ColGroupIter<'a, C> {
832
+ type Item = ColGroupItem<'a, C::Item>;
833
+
834
+ fn next(&mut self) -> Option<Self::Item> {
835
+ let acc = self.iter.slabs.weight().acc() - self.iter.slab.acc_left() - self.iter.run_acc();
836
+ let pos = self.iter.pos;
837
+ let item = self.iter.next()?;
838
+ Some(ColGroupItem { item, pos, acc })
839
+ }
840
+
841
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
842
+ if n > 0 {
843
+ self.iter.nth(n - 1);
844
+ }
845
+ self.next()
846
+ }
847
+ }
848
+
849
+ impl<'a, C: ColumnCursor> Iterator for ColumnDataIter<'a, C> {
850
+ type Item = Option<Cow<'a, C::Item>>;
851
+
852
+ fn next(&mut self) -> Option<Self::Item> {
853
+ if self.pos >= self.max {
854
+ return None;
855
+ }
856
+ let result = self.pop_element().or_else(|| {
857
+ self.run = self.pop_run();
858
+ self.slab.cursor.pop(self.run.as_mut()?)
859
+ })?;
860
+ self.pos += 1;
861
+ Some(result)
862
+ }
863
+
864
+ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
865
+ if self.pos >= self.max {
866
+ return None;
867
+ }
868
+ if n == 0 {
869
+ return self.next();
870
+ }
871
+ let mut overflow = false;
872
+ if self.pos + n + 1 > self.max {
873
+ n = self.max - self.pos - 1;
874
+ overflow = true;
875
+ }
876
+
877
+ let target = self.pos() + n + 1;
878
+ let result = if self.slabs.weight().pos() < target {
879
+ self.reset_iter_to_pos(target - 1)?;
880
+ self.next()
881
+ } else if self.run_count() > n {
882
+ self.pos += n + 1;
883
+ let result = self.slab.cursor.pop_n(self.run.as_mut()?, n + 1);
884
+ //if self.pos > self.max {
885
+ //if overflow {
886
+ // None
887
+ //} else {
888
+ result
889
+ //}
890
+ } else {
891
+ self.pos += self.run_count();
892
+ let n = n - self.run_count();
893
+ if n > 0 {
894
+ self.pos += n;
895
+ self.run = self.slab.sub_advance(n);
896
+ } else {
897
+ self.run = None;
898
+ }
899
+ self.next()
900
+ };
901
+ if !overflow {
902
+ result
903
+ } else {
904
+ None
905
+ }
906
+ }
907
+ }
908
+
909
+ impl<C: ColumnCursor> ColumnData<C> {
910
+ /// Iterates over the raw [`Run`]s in the column.
911
+ ///
912
+ /// Each `Run` has a `count` and an optional `value`. This gives lower-level access to the
913
+ /// RLE structure than `iter()` — useful for re-encoding or bulk inspection.
914
+ pub fn run_iter(&self) -> impl Iterator<Item = Run<'_, C::Item>> {
915
+ self.slabs.iter().flat_map(|s| s.run_iter::<C>())
916
+ }
917
+
918
+ /// Decodes all items into a `Vec`. Primarily useful for testing and debugging.
919
+ pub fn to_vec(&self) -> Vec<C::Export> {
920
+ let mut result = vec![];
921
+ C::export_splice(&mut result, 0..0, self.iter());
922
+ result
923
+ }
924
+
925
+ /// Returns a forward iterator over all items in the column.
926
+ ///
927
+ /// The iterator decodes one slab at a time, carrying state across items within each slab
928
+ /// for amortized O(1) per-item cost after an O(log n) initial seek.
929
+ /// For a sub-range use [`iter_range`](ColumnData::iter_range).
930
+ pub fn iter(&self) -> ColumnDataIter<'_, C> {
931
+ ColumnDataIter::new(&self.slabs, 0, self.len, self.counter)
932
+ }
933
+
934
+ /// Returns the contiguous index range where `value` appears within `range`.
935
+ ///
936
+ /// Requires that the values in `range` are sorted. Uses B-tree binary search over slabs
937
+ /// followed by a linear scan within the target slab.
938
+ /// Returns an empty range at the found position if `value` is not present.
939
+ ///
940
+ /// For repeated lookups on the same iterator use [`ColumnDataIter::seek_to_value`].
941
+ pub fn scope_to_value<B, R>(&self, value: Option<B>, range: R) -> Range<usize>
942
+ where
943
+ B: Borrow<C::Item> + Copy + Debug,
944
+ R: RangeBounds<usize>,
945
+ C::Item: Ord,
946
+ {
947
+ //let (start, end) = normalize_range(range);
948
+ //let mut iter = self.iter_range(start..end);
949
+ self.iter().seek_to_value(value, range)
950
+ }
951
+
952
+ /// Returns an iterator over items in `range`, clamped to the column's length.
953
+ pub fn iter_range(&self, range: Range<usize>) -> ColumnDataIter<'_, C> {
954
+ let start = std::cmp::min(self.len, range.start);
955
+ let end = std::cmp::min(self.len, range.end);
956
+ ColumnDataIter::new(&self.slabs, start, end, self.counter)
957
+ }
958
+
959
+ #[cfg(feature = "slow_path_assertions")]
960
+ fn init_debug(mut self) -> Self {
961
+ let mut debug = vec![];
962
+ C::export_splice(&mut debug, 0..0, self.iter());
963
+ self.debug = debug;
964
+ self
965
+ }
966
+
967
+ pub(crate) fn init(len: usize, slabs: SlabTree<C::SlabIndex>) -> Self {
968
+ debug_assert_eq!(len, slabs.iter().map(|s| s.len()).sum::<usize>());
969
+ let col = ColumnData {
970
+ counter: 0,
971
+ len,
972
+ slabs,
973
+ _phantom: PhantomData,
974
+ #[cfg(feature = "slow_path_assertions")]
975
+ debug: vec![],
976
+ };
977
+ #[cfg(feature = "slow_path_assertions")]
978
+ let col = col.init_debug();
979
+ col
980
+ }
981
+
982
+ /// Creates a new, empty column.
983
+ pub fn new() -> Self {
984
+ ColumnData {
985
+ len: 0,
986
+ counter: 0,
987
+ slabs: SlabTree::new2(Slab::default()),
988
+ _phantom: PhantomData,
989
+ #[cfg(feature = "slow_path_assertions")]
990
+ debug: vec![],
991
+ }
992
+ }
993
+
994
+ /// Serializes the column to a new `Vec<u8>`. See also [`save_to`](ColumnData::save_to).
995
+ pub fn save(&self) -> Vec<u8> {
996
+ let mut data = vec![];
997
+ self.save_to(&mut data);
998
+ data
999
+ }
1000
+
1001
+ /// Appends a single value to the end of the column.
1002
+ ///
1003
+ /// Returns the [`Acc`] value of the appended item. For bulk appends at the end,
1004
+ /// [`extend`](ColumnData::extend) is more efficient.
1005
+ pub fn push<'b, M>(&mut self, value: M) -> Acc
1006
+ where
1007
+ M: MaybePackable<'b, C::Item> + Clone,
1008
+ C::Item: 'b,
1009
+ {
1010
+ let index = self.len();
1011
+ self.splice(index, 0, [value])
1012
+ }
1013
+
1014
+ /// Appends multiple values to the end of the column.
1015
+ ///
1016
+ /// Returns the total [`Acc`] contributed by the appended values.
1017
+ pub fn extend<'b, M, I>(&mut self, values: I) -> Acc
1018
+ where
1019
+ M: MaybePackable<'b, C::Item>,
1020
+ I: IntoIterator<Item = M>,
1021
+ C::Item: 'b,
1022
+ {
1023
+ let index = self.len();
1024
+ self.splice(index, 0, values)
1025
+ }
1026
+
1027
+ /// Removes `del` items starting at `index` and inserts `values` in their place.
1028
+ ///
1029
+ /// This is the primary mutation method. It finds the slab containing `index` in O(log n),
1030
+ /// re-encodes the affected slab with the deletion/insertion applied, then replaces it in
1031
+ /// the B-tree. Unaffected slabs are not touched.
1032
+ ///
1033
+ /// Returns the accumulated [`Acc`] of the inserted values.
1034
+ ///
1035
+ /// Panics if `index > self.len()`.
1036
+ pub fn splice<'b, M, I>(&mut self, index: usize, del: usize, values: I) -> Acc
1037
+ where
1038
+ M: MaybePackable<'b, C::Item>,
1039
+ I: IntoIterator<Item = M>,
1040
+ C::Item: 'b,
1041
+ {
1042
+ assert!(index <= self.len);
1043
+ assert!(!self.slabs.is_empty());
1044
+ let values = values.into_iter();
1045
+
1046
+ let mut values = values.peekable();
1047
+ if values.peek().is_none() && del == 0 {
1048
+ return Acc::new(); // really none
1049
+ }
1050
+
1051
+ let cursor = self
1052
+ .slabs
1053
+ .get_where_or_last(|acc, next| index < acc.pos() + next.pos());
1054
+
1055
+ let mut acc = cursor.weight.acc();
1056
+
1057
+ debug_assert_eq!(
1058
+ self.iter()
1059
+ .map(|i| i.as_deref().map(<C::Item>::agg).unwrap_or_default())
1060
+ .sum::<Acc>(),
1061
+ self.acc()
1062
+ );
1063
+
1064
+ let subindex = index - cursor.weight.pos();
1065
+
1066
+ let mut result = C::splice(
1067
+ cursor.element,
1068
+ subindex,
1069
+ del,
1070
+ values,
1071
+ #[cfg(feature = "slow_path_assertions")]
1072
+ (&mut self.debug, index..(index + del)),
1073
+ );
1074
+
1075
+ acc += result.group;
1076
+ C::compute_min_max(&mut result.slabs); // this should be handled by slabwriter.finish
1077
+ self.len = self.len + result.add - result.del;
1078
+ let post_slab_index = cursor.index + result.slabs.len();
1079
+ self.slabs
1080
+ .splice(cursor.index..(cursor.index + 1), result.slabs);
1081
+ self.counter += 1;
1082
+
1083
+ while result.overflow > 0 {
1084
+ if let Some(post_slab) = self.slabs.get(post_slab_index) {
1085
+ if post_slab.len() <= result.overflow {
1086
+ result.overflow -= post_slab.len();
1087
+ self.len -= post_slab.len();
1088
+ self.slabs.remove(post_slab_index);
1089
+ } else {
1090
+ let mut r = C::splice::<_, M>(
1091
+ post_slab,
1092
+ 0,
1093
+ result.overflow,
1094
+ [].into_iter(),
1095
+ #[cfg(feature = "slow_path_assertions")]
1096
+ (&mut self.debug, 0..0),
1097
+ );
1098
+ self.len -= r.del;
1099
+ C::compute_min_max(&mut r.slabs);
1100
+ self.slabs
1101
+ .splice(post_slab_index..(post_slab_index + 1), r.slabs);
1102
+ break;
1103
+ }
1104
+ }
1105
+ }
1106
+ if self.slabs.is_empty() {
1107
+ assert!(self.len == 0);
1108
+ self.slabs.push(Slab::default()); // need a blank empty slab
1109
+ }
1110
+
1111
+ debug_assert_eq!(
1112
+ self.iter()
1113
+ .map(|i| i.as_deref().map(<C::Item>::agg).unwrap_or_default())
1114
+ .sum::<Acc>(),
1115
+ self.acc()
1116
+ );
1117
+
1118
+ #[cfg(feature = "slow_path_assertions")]
1119
+ if self.debug != self.to_vec() {
1120
+ let col = self.to_vec();
1121
+ assert_eq!(self.debug.len(), col.len());
1122
+ for (i, dbg) in col.iter().enumerate() {
1123
+ if dbg != &col[i] {
1124
+ panic!("index={} {:?} vs {:?}", i, dbg, col[i]);
1125
+ }
1126
+ }
1127
+ panic!()
1128
+ }
1129
+ acc
1130
+ }
1131
+
1132
+ /// If the column is currently empty, fills it with `len` null values and returns `true`.
1133
+ /// If the column already has items, returns `false` without modifying it.
1134
+ pub fn fill_if_empty(&mut self, len: usize) -> bool {
1135
+ if self.len == 0 && len > 0 {
1136
+ *self = Self::init_empty(len);
1137
+ true
1138
+ } else {
1139
+ false
1140
+ }
1141
+ }
1142
+
1143
+ /// Creates a column of `len` null values.
1144
+ pub fn init_empty(len: usize) -> Self {
1145
+ let new_slab = C::init_empty(len);
1146
+ let mut slabs = SlabTree::default();
1147
+ slabs.push(new_slab);
1148
+ assert!(!slabs.is_empty());
1149
+ ColumnData::init(len, slabs)
1150
+ }
1151
+
1152
+ /// Deserializes `data`, or returns a column of `len` nulls if `data` is empty.
1153
+ ///
1154
+ /// Returns [`PackError::InvalidLength`] if the decoded column has a different length
1155
+ /// than `len`.
1156
+ pub fn load_unless_empty(data: &[u8], len: usize) -> Result<Self, PackError> {
1157
+ if data.is_empty() {
1158
+ Ok(ColumnData::init_empty(len))
1159
+ } else {
1160
+ let c = ColumnData::load(data)?;
1161
+ if c.len() == len {
1162
+ Ok(c)
1163
+ } else {
1164
+ Err(PackError::InvalidLength(c.len(), len))
1165
+ }
1166
+ }
1167
+ }
1168
+
1169
+ /// Like [`load_unless_empty`](ColumnData::load_unless_empty) but also validates each value
1170
+ /// with `test`. If `test` returns `Some(msg)`, decoding fails with
1171
+ /// [`PackError::InvalidValue`].
1172
+ pub fn load_with_unless_empty<F>(data: &[u8], len: usize, test: &F) -> Result<Self, PackError>
1173
+ where
1174
+ F: Fn(Option<&C::Item>) -> Option<String>,
1175
+ {
1176
+ if data.is_empty() {
1177
+ Ok(ColumnData::init_empty(len))
1178
+ } else {
1179
+ let c = ColumnData::load_with(data, test)?;
1180
+ if c.len() == len {
1181
+ Ok(c)
1182
+ } else {
1183
+ Err(PackError::InvalidLength(c.len(), len))
1184
+ }
1185
+ }
1186
+ }
1187
+
1188
+ /// Deserializes a column from bytes produced by [`save`](ColumnData::save) /
1189
+ /// [`save_to`](ColumnData::save_to).
1190
+ ///
1191
+ /// Returns a [`PackError`] if the bytes are malformed or use the wrong encoding.
1192
+ pub fn load(data: &[u8]) -> Result<Self, PackError> {
1193
+ Self::load_with(data, &|_| None)
1194
+ }
1195
+
1196
+ /// Like [`load`](ColumnData::load) but validates each decoded value with `test`.
1197
+ /// If `test` returns `Some(msg)`, decoding fails with [`PackError::InvalidValue`].
1198
+ pub fn load_with<F>(data: &[u8], test: &F) -> Result<Self, PackError>
1199
+ where
1200
+ F: Fn(Option<&C::Item>) -> Option<String>,
1201
+ {
1202
+ let col = C::load_with(data, test)?;
1203
+ debug_assert_eq!(
1204
+ col.iter()
1205
+ .map(|i| i.as_deref().map(<C::Item>::agg).unwrap_or_default())
1206
+ .sum::<Acc>(),
1207
+ col.acc()
1208
+ );
1209
+ Ok(col)
1210
+ }
1211
+
1212
+ /// Returns the number of items in the column (including nulls).
1213
+ pub fn len(&self) -> usize {
1214
+ self.len
1215
+ }
1216
+
1217
+ /// Returns the total accumulated [`Acc`] for the entire column
1218
+ /// (sum of `agg(item)` for every non-null item).
1219
+ pub fn acc(&self) -> Acc {
1220
+ self.slabs.weight().map(|w| w.acc()).unwrap_or_default()
1221
+ }
1222
+ }
1223
+
1224
+ impl<C: ColumnCursor> ColumnData<C>
1225
+ where
1226
+ C::SlabIndex: HasMinMax,
1227
+ {
1228
+ /// Returns an iterator over the indices of items whose value falls within `range`.
1229
+ ///
1230
+ /// Uses slab-level min/max metadata to skip slabs that cannot contain matching values,
1231
+ /// making this efficient for sparse matches. Requires that the cursor type supports
1232
+ /// min/max tracking ([`HasMinMax`]).
1233
+ pub fn find_by_range(&self, range: Range<usize>) -> impl Iterator<Item = usize> + '_ {
1234
+ let start = range.start;
1235
+ let end = range.end;
1236
+ self.slabs
1237
+ .iter_where(move |_, s| s.intersects(start..end))
1238
+ .flat_map(move |cursor| {
1239
+ let pos = cursor.weight.pos();
1240
+ cursor
1241
+ .element
1242
+ .run_iter::<C>()
1243
+ .containing_range(pos, start..end)
1244
+ })
1245
+ }
1246
+
1247
+ /// Returns an iterator over the indices of items whose [`Agg`] value equals `agg`.
1248
+ ///
1249
+ /// Uses slab-level min/max metadata to skip non-matching slabs. Requires that the cursor
1250
+ /// type supports min/max tracking ([`HasMinMax`]).
1251
+ pub fn find_by_value<A: Into<Agg>>(&self, agg: A) -> impl Iterator<Item = usize> + '_ {
1252
+ let agg = agg.into();
1253
+
1254
+ self.slabs
1255
+ .iter_where(move |_, s| agg.is_some() && agg >= s.min() && agg <= s.max())
1256
+ .flat_map(move |cursor| {
1257
+ let pos = cursor.weight.pos();
1258
+ cursor.element.run_iter::<C>().containing_agg(pos, agg)
1259
+ })
1260
+ }
1261
+ }
1262
+
1263
+ pub(crate) fn normalize_range<R: RangeBounds<usize>>(range: R) -> (usize, usize) {
1264
+ let start = match range.start_bound() {
1265
+ Bound::Unbounded => usize::MIN,
1266
+ Bound::Included(n) => *n,
1267
+ Bound::Excluded(n) => *n - 1,
1268
+ };
1269
+
1270
+ let end = match range.end_bound() {
1271
+ Bound::Unbounded => usize::MAX,
1272
+ Bound::Included(n) => *n + 1,
1273
+ Bound::Excluded(n) => *n,
1274
+ };
1275
+ (start, end)
1276
+ }
1277
+
1278
+ impl<'a, C, M> From<Vec<M>> for ColumnData<C>
1279
+ where
1280
+ C: ColumnCursor,
1281
+ M: MaybePackable<'a, C::Item>,
1282
+ C::Item: 'a,
1283
+ {
1284
+ fn from(i: Vec<M>) -> Self {
1285
+ i.into_iter().collect()
1286
+ }
1287
+ }
1288
+
1289
+ impl<'a, C, M> FromIterator<M> for ColumnData<C>
1290
+ where
1291
+ C: ColumnCursor,
1292
+ M: MaybePackable<'a, C::Item>,
1293
+ C::Item: 'a,
1294
+ {
1295
+ fn from_iter<I: IntoIterator<Item = M>>(iter: I) -> Self {
1296
+ let mut encoder = Encoder::new(false);
1297
+ for item in iter {
1298
+ encoder.append_item(item.maybe_packable());
1299
+ }
1300
+ encoder.into_column_data()
1301
+ }
1302
+ }
1303
+
1304
+ fn _cmp<A, B, C>(a: Option<A>, b: &Option<B>) -> Ordering
1305
+ where
1306
+ A: Borrow<C>,
1307
+ B: Borrow<C>,
1308
+ C: Ord + ?Sized,
1309
+ {
1310
+ match (a, b) {
1311
+ (Some(a), Some(b)) => a.borrow().cmp(b.borrow()),
1312
+ (None, None) => Ordering::Equal,
1313
+ (None, Some(_)) => Ordering::Less,
1314
+ (Some(_), None) => Ordering::Greater,
1315
+ }
1316
+ }
1317
+
1318
+ #[cfg(test)]
1319
+ pub(crate) mod tests {
1320
+ use super::super::boolean::BooleanCursor;
1321
+ use super::super::delta::{DeltaCursor, DeltaCursorInternal};
1322
+ use super::super::rle::{ByteCursor, IntCursor, RleCursor, StrCursor, UIntCursor};
1323
+ use super::super::test::ColExport;
1324
+ use super::*;
1325
+ use rand::prelude::*;
1326
+ use rand::rngs::SmallRng;
1327
+ use std::cmp::{max, min};
1328
+
1329
+ const FUZZ_SIZE: u32 = 1_000;
1330
+
1331
+ fn test_splice<'a, C: ColumnCursor, E>(
1332
+ vec: &'a mut Vec<E>,
1333
+ col: &'a mut ColumnData<C>,
1334
+ index: usize,
1335
+ values: Vec<E>,
1336
+ ) where
1337
+ E: MaybePackable<'a, C::Item> + std::fmt::Debug + std::cmp::PartialEq<C::Export> + Clone,
1338
+ {
1339
+ test_splice_del(vec, col, index, 0, values);
1340
+ }
1341
+
1342
+ fn test_splice_del<'a, C: ColumnCursor, E>(
1343
+ vec: &'a mut Vec<E>,
1344
+ col: &'a mut ColumnData<C>,
1345
+ index: usize,
1346
+ del: usize,
1347
+ values: Vec<E>,
1348
+ ) where
1349
+ E: MaybePackable<'a, C::Item> + std::fmt::Debug + std::cmp::PartialEq<C::Export> + Clone,
1350
+ {
1351
+ vec.splice(index..index + del, values.clone());
1352
+ col.splice(index, del, values);
1353
+ for slab in &col.slabs {
1354
+ let (_, c) = C::seek(slab.len(), slab);
1355
+ assert_eq!(c.min(), slab.min());
1356
+ assert_eq!(c.max(), slab.max());
1357
+ }
1358
+ assert_eq!(vec, &col.to_vec());
1359
+ }
1360
+
1361
+ fn test_advance_by<'a, C: ColumnCursor>(
1362
+ rng: &mut SmallRng,
1363
+ data: &'a [C::Export],
1364
+ col: &'a mut ColumnData<C>,
1365
+ ) {
1366
+ let mut advanced_by = 0;
1367
+ let mut iter = col.iter();
1368
+ while advanced_by < data.len() - 1 {
1369
+ let advance_by = rng.random_range(1..(data.len() - advanced_by));
1370
+ iter.advance_by(advance_by);
1371
+ let expected = data[advance_by + advanced_by..].to_vec();
1372
+ let actual = iter.clone().to_vec();
1373
+ assert_eq!(expected, actual);
1374
+ advanced_by += advance_by;
1375
+ }
1376
+ }
1377
+
1378
+ #[test]
1379
+ fn column_data_breaking_literal_runs_in_int_column() {
1380
+ let numbers = vec![1, 2, 3];
1381
+ let mut start = ColumnData::<UIntCursor>::new();
1382
+ start.splice(0, 0, numbers);
1383
+ assert_eq!(
1384
+ start.test_dump(),
1385
+ vec![vec![ColExport::LitRun(vec![1, 2, 3])]]
1386
+ );
1387
+ let mut col = start.clone();
1388
+ col.splice(2, 0, vec![3, 3, 3]);
1389
+ assert_eq!(
1390
+ col.test_dump(),
1391
+ vec![vec![ColExport::LitRun(vec![1, 2]), ColExport::Run(4, 3)]]
1392
+ );
1393
+ let mut col = start.clone();
1394
+ col.splice(3, 0, vec![3, 3, 3]);
1395
+ assert_eq!(
1396
+ col.test_dump(),
1397
+ vec![vec![ColExport::LitRun(vec![1, 2]), ColExport::Run(4, 3)]]
1398
+ );
1399
+ let mut col = start.clone();
1400
+ col.splice(1, 0, vec![2, 2]);
1401
+ assert_eq!(
1402
+ col.test_dump(),
1403
+ vec![vec![
1404
+ ColExport::LitRun(vec![1]),
1405
+ ColExport::Run(3, 2),
1406
+ ColExport::LitRun(vec![3]),
1407
+ ]]
1408
+ );
1409
+ let mut col = start.clone();
1410
+ col.splice(2, 0, vec![2, 2]);
1411
+ assert_eq!(
1412
+ col.test_dump(),
1413
+ vec![vec![
1414
+ ColExport::LitRun(vec![1]),
1415
+ ColExport::Run(3, 2),
1416
+ ColExport::LitRun(vec![3]),
1417
+ ]]
1418
+ );
1419
+ let mut col = start.clone();
1420
+ col.splice(0, 0, vec![1, 1]);
1421
+ assert_eq!(
1422
+ col.test_dump(),
1423
+ vec![vec![ColExport::Run(3, 1), ColExport::LitRun(vec![2, 3]),]]
1424
+ );
1425
+ let mut col = start.clone();
1426
+ col.splice(1, 0, vec![1, 1]);
1427
+ assert_eq!(
1428
+ col.test_dump(),
1429
+ vec![vec![ColExport::Run(3, 1), ColExport::LitRun(vec![2, 3]),]]
1430
+ );
1431
+ }
1432
+
1433
+ #[test]
1434
+ fn column_data_breaking_runs_in_int_column() {
1435
+ let numbers = vec![2, 2, 2];
1436
+ let mut start = ColumnData::<UIntCursor>::new();
1437
+ start.splice(0, 0, numbers);
1438
+ assert_eq!(start.test_dump(), vec![vec![ColExport::Run(3, 2)]]);
1439
+ let mut col = start.clone();
1440
+ col.splice(1, 0, vec![3, 3, 3]);
1441
+ assert_eq!(
1442
+ col.test_dump(),
1443
+ vec![vec![
1444
+ ColExport::LitRun(vec![2]),
1445
+ ColExport::Run(3, 3),
1446
+ ColExport::Run(2, 2),
1447
+ ]]
1448
+ );
1449
+ let mut col = start.clone();
1450
+ col.splice(2, 0, vec![3, 3, 3]);
1451
+ assert_eq!(
1452
+ col.test_dump(),
1453
+ vec![vec![
1454
+ ColExport::Run(2, 2),
1455
+ ColExport::Run(3, 3),
1456
+ ColExport::LitRun(vec![2]),
1457
+ ]]
1458
+ );
1459
+ let mut col = start.clone();
1460
+ col.splice(0, 0, vec![3, 3, 3]);
1461
+ assert_eq!(
1462
+ col.test_dump(),
1463
+ vec![vec![ColExport::Run(3, 3), ColExport::Run(3, 2),]]
1464
+ );
1465
+ let mut col = start.clone();
1466
+ col.splice(3, 0, vec![3, 3, 3]);
1467
+ assert_eq!(
1468
+ col.test_dump(),
1469
+ vec![vec![ColExport::Run(3, 2), ColExport::Run(3, 3),]]
1470
+ );
1471
+ }
1472
+
1473
+ #[test]
1474
+ fn column_data_breaking_null_runs_in_int_column() {
1475
+ let numbers = vec![None, None, Some(2), Some(2), None, None, None];
1476
+ let mut start = ColumnData::<UIntCursor>::new();
1477
+ start.splice(0, 0, numbers);
1478
+ assert_eq!(
1479
+ start.test_dump(),
1480
+ vec![vec![
1481
+ ColExport::Null(2),
1482
+ ColExport::Run(2, 2),
1483
+ ColExport::Null(3)
1484
+ ]]
1485
+ );
1486
+ assert_eq!(
1487
+ start.to_vec(),
1488
+ vec![None, None, Some(2), Some(2), None, None, None]
1489
+ );
1490
+ let mut col = start.clone();
1491
+ col.splice(2, 0, vec![None, None, Some(2), Some(2)]);
1492
+ assert_eq!(
1493
+ col.test_dump(),
1494
+ vec![vec![
1495
+ ColExport::Null(4),
1496
+ ColExport::Run(4, 2),
1497
+ ColExport::Null(3)
1498
+ ]]
1499
+ );
1500
+ assert_eq!(col.len, 11);
1501
+ assert_eq!(col.slabs.iter().map(|s| s.len()).sum::<usize>(), 11);
1502
+ col.splice(8, 0, vec![Some(2), Some(2), None, None]);
1503
+ assert_eq!(
1504
+ col.test_dump(),
1505
+ vec![vec![
1506
+ ColExport::Null(4),
1507
+ ColExport::Run(6, 2),
1508
+ ColExport::Null(5)
1509
+ ]]
1510
+ );
1511
+ col.splice(4, 0, vec![None, Some(2), Some(3)]);
1512
+ assert_eq!(
1513
+ col.test_dump(),
1514
+ vec![vec![
1515
+ ColExport::Null(5),
1516
+ ColExport::LitRun(vec![2, 3]),
1517
+ ColExport::Run(6, 2),
1518
+ ColExport::Null(5)
1519
+ ]]
1520
+ );
1521
+ col.splice(2, 0, vec![4]);
1522
+ assert_eq!(
1523
+ col.test_dump(),
1524
+ vec![vec![
1525
+ ColExport::Null(2),
1526
+ ColExport::LitRun(vec![4]),
1527
+ ColExport::Null(3),
1528
+ ColExport::LitRun(vec![2, 3]),
1529
+ ColExport::Run(6, 2),
1530
+ ColExport::Null(5)
1531
+ ]]
1532
+ );
1533
+ col.splice(6, 0, vec![None, None, Some(2), Some(2)]);
1534
+ assert_eq!(
1535
+ col.test_dump(),
1536
+ vec![vec![
1537
+ ColExport::Null(2),
1538
+ ColExport::LitRun(vec![4]),
1539
+ ColExport::Null(5),
1540
+ ColExport::Run(3, 2),
1541
+ ColExport::LitRun(vec![3]),
1542
+ ColExport::Run(6, 2),
1543
+ ColExport::Null(5)
1544
+ ]]
1545
+ );
1546
+ col.splice(
1547
+ 12,
1548
+ 0,
1549
+ vec![Some(3), Some(3), None, Some(7), Some(8), Some(9), Some(2)],
1550
+ );
1551
+ assert_eq!(
1552
+ col.test_dump(),
1553
+ vec![vec![
1554
+ ColExport::Null(2),
1555
+ ColExport::LitRun(vec![4]),
1556
+ ColExport::Null(5),
1557
+ ColExport::Run(3, 2),
1558
+ ColExport::Run(3, 3),
1559
+ ColExport::Null(1),
1560
+ ColExport::LitRun(vec![7, 8, 9]),
1561
+ ColExport::Run(7, 2),
1562
+ ColExport::Null(5)
1563
+ ]]
1564
+ );
1565
+ col.splice(15, 0, vec![5, 6]);
1566
+ assert_eq!(
1567
+ col.test_dump(),
1568
+ vec![vec![
1569
+ ColExport::Null(2),
1570
+ ColExport::LitRun(vec![4]),
1571
+ ColExport::Null(5),
1572
+ ColExport::Run(3, 2),
1573
+ ColExport::Run(3, 3),
1574
+ ColExport::Null(1),
1575
+ ColExport::LitRun(vec![5, 6, 7, 8, 9]),
1576
+ ColExport::Run(7, 2),
1577
+ ColExport::Null(5)
1578
+ ]]
1579
+ );
1580
+ assert_eq!(col.len, col.iter().count());
1581
+ }
1582
+
1583
+ #[test]
1584
+ fn column_data_strings() {
1585
+ let strings = vec!["one", "two", "three"];
1586
+ let mut start = ColumnData::<StrCursor>::new();
1587
+ start.splice(0, 0, strings);
1588
+ assert_eq!(
1589
+ start.test_dump(),
1590
+ vec![vec![ColExport::litrun(vec!["one", "two", "three"])]]
1591
+ );
1592
+ let mut col = start.clone();
1593
+ col.splice(1, 0, vec![None, None, Some("two"), Some("two")]);
1594
+ assert_eq!(
1595
+ col.test_dump(),
1596
+ vec![vec![
1597
+ ColExport::litrun(vec!["one"]),
1598
+ ColExport::Null(2),
1599
+ ColExport::run(3, "two"),
1600
+ ColExport::litrun(vec!["three"]),
1601
+ ]]
1602
+ );
1603
+ col.splice(0, 0, vec![None, None, Some("three"), Some("one")]);
1604
+ assert_eq!(
1605
+ col.test_dump(),
1606
+ vec![vec![
1607
+ ColExport::Null(2),
1608
+ ColExport::litrun(vec!["three"]),
1609
+ ColExport::run(2, "one"),
1610
+ ColExport::Null(2),
1611
+ ColExport::run(3, "two"),
1612
+ ColExport::litrun(vec!["three"]),
1613
+ ]]
1614
+ );
1615
+ }
1616
+
1617
+ #[test]
1618
+ fn column_data_bytes() {
1619
+ let bytes = vec![vec![1, 1, 1], vec![2, 2, 2], vec![3, 3, 3]];
1620
+ let mut start = ColumnData::<ByteCursor>::new();
1621
+ start.splice(0, 0, bytes);
1622
+ assert_eq!(
1623
+ start.test_dump(),
1624
+ vec![vec![ColExport::litrun(vec![
1625
+ vec![1, 1, 1],
1626
+ vec![2, 2, 2],
1627
+ vec![3, 3, 3]
1628
+ ])]]
1629
+ );
1630
+ let mut col = start.clone();
1631
+ col.splice(
1632
+ 1,
1633
+ 0,
1634
+ vec![None, None, Some(vec![2, 2, 2]), Some(vec![2, 2, 2])],
1635
+ );
1636
+ assert_eq!(
1637
+ col.test_dump(),
1638
+ vec![vec![
1639
+ ColExport::litrun(vec![vec![1, 1, 1]]),
1640
+ ColExport::Null(2),
1641
+ ColExport::run(3, vec![2, 2, 2]),
1642
+ ColExport::litrun(vec![vec![3, 3, 3]]),
1643
+ ]]
1644
+ );
1645
+ col.splice(
1646
+ 0,
1647
+ 0,
1648
+ vec![None, None, Some(vec![3, 3, 3]), Some(vec![1, 1, 1])],
1649
+ );
1650
+ assert_eq!(
1651
+ col.test_dump(),
1652
+ vec![vec![
1653
+ ColExport::Null(2),
1654
+ ColExport::litrun(vec![vec![3, 3, 3]]),
1655
+ ColExport::run(2, vec![1, 1, 1]),
1656
+ ColExport::Null(2),
1657
+ ColExport::run(3, vec![2, 2, 2]),
1658
+ ColExport::litrun(vec![vec![3, 3, 3]]),
1659
+ ]]
1660
+ );
1661
+ }
1662
+
1663
+ #[test]
1664
+ fn column_data_delta() {
1665
+ let numbers = vec![1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 7, 8, 9];
1666
+ let mut start = ColumnData::<DeltaCursor>::new();
1667
+ start.splice(0, 0, numbers.clone());
1668
+ assert_eq!(
1669
+ start.test_dump(),
1670
+ vec![vec![
1671
+ ColExport::Run(6, 1),
1672
+ ColExport::Run(4, 0),
1673
+ ColExport::Run(3, 1),
1674
+ ]]
1675
+ );
1676
+ let numbers1 = numbers.iter().map(|i| Some(*i)).collect::<Vec<_>>();
1677
+ let numbers2 = start.to_vec();
1678
+ assert_eq!(numbers1, numbers2);
1679
+ let mut col = start.clone();
1680
+ col.splice(1, 0, vec![2]);
1681
+ assert_eq!(
1682
+ col.test_dump(),
1683
+ vec![vec![
1684
+ ColExport::Run(2, 1),
1685
+ ColExport::LitRun(vec![0]),
1686
+ ColExport::Run(4, 1),
1687
+ ColExport::Run(4, 0),
1688
+ ColExport::Run(3, 1),
1689
+ ]]
1690
+ );
1691
+ col.splice(0, 0, vec![0]);
1692
+ assert_eq!(
1693
+ col.test_dump(),
1694
+ vec![vec![
1695
+ ColExport::LitRun(vec![0]),
1696
+ ColExport::Run(2, 1),
1697
+ ColExport::LitRun(vec![0]),
1698
+ ColExport::Run(4, 1),
1699
+ ColExport::Run(4, 0),
1700
+ ColExport::Run(3, 1),
1701
+ ]]
1702
+ );
1703
+ }
1704
+
1705
+ /// v0 splice panics when del > 1 and the delete range spans a slab boundary.
1706
+ /// Build a multi-slab column (B=64) and delete 5 items near the boundary.
1707
+ #[test]
1708
+ fn splice_cross_slab_delete() {
1709
+ let mut col: ColumnData<UIntCursor> = (0..200).map(|i| i as u64).collect();
1710
+ // Position 62: last few items of first slab (64 items). del=5 crosses into the next slab.
1711
+ col.splice(62, 5, std::iter::empty::<u64>());
1712
+ assert_eq!(col.len(), 195);
1713
+ }
1714
+
1715
+ #[test]
1716
+ fn column_data_big_delete() {
1717
+ let mut col: ColumnData<IntCursor> = [
1718
+ 1, 2, 3, 4, 5, 6, 5, 5, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 2, 3, 4, 4, 4,
1719
+ ]
1720
+ .into_iter()
1721
+ .collect();
1722
+ let len = col.len();
1723
+ let v: Vec<i64> = vec![];
1724
+ log!("SPLICE 1");
1725
+ col.splice(0, 0, v.clone());
1726
+ log!("SPLICE 2");
1727
+ col.splice(0, len, v);
1728
+ }
1729
+
1730
+ // TODO - would be nice if you printed the seed on failure
1731
+ // so we could re-seed if we ever see one of these fail
1732
+ trait TestRand: Clone {
1733
+ fn index(len: usize, rng: &mut SmallRng) -> usize {
1734
+ match len {
1735
+ 0 => 0,
1736
+ _ => (rng.random::<u32>() as usize) % len,
1737
+ }
1738
+ }
1739
+ fn null() -> Self;
1740
+ fn rand(rng: &mut SmallRng) -> Self;
1741
+ fn maybe_rand(rng: &mut SmallRng) -> Self {
1742
+ match rng.random::<u64>() as i64 % 10 {
1743
+ 0 => Self::null(),
1744
+ _ => Self::rand(rng),
1745
+ }
1746
+ }
1747
+ fn plus(&self, index: usize) -> Self;
1748
+ fn rand_vec(rng: &mut SmallRng) -> Vec<Self>
1749
+ where
1750
+ Self: Sized,
1751
+ {
1752
+ let mut result = vec![];
1753
+ let len = rng.random::<u32>() % 40 + 1;
1754
+ for _ in 0..len {
1755
+ if rng.random::<i64>() % 3 == 0 {
1756
+ result.push(Self::null())
1757
+ } else {
1758
+ result.push(Self::rand(rng))
1759
+ }
1760
+ }
1761
+ result
1762
+ }
1763
+ }
1764
+
1765
+ impl TestRand for Option<i64> {
1766
+ fn null() -> Option<i64> {
1767
+ None
1768
+ }
1769
+
1770
+ fn rand(rng: &mut SmallRng) -> Option<i64> {
1771
+ Some((rng.random::<u64>() % 3) as i64)
1772
+ }
1773
+
1774
+ fn plus(&self, index: usize) -> Option<i64> {
1775
+ self.map(|i| i + index as i64)
1776
+ }
1777
+ }
1778
+
1779
+ impl TestRand for bool {
1780
+ fn null() -> bool {
1781
+ false
1782
+ }
1783
+ fn rand(rng: &mut SmallRng) -> bool {
1784
+ rng.random::<bool>()
1785
+ }
1786
+ fn plus(&self, _index: usize) -> bool {
1787
+ true
1788
+ }
1789
+ }
1790
+
1791
+ impl TestRand for Option<u64> {
1792
+ fn null() -> Option<u64> {
1793
+ None
1794
+ }
1795
+ fn rand(rng: &mut SmallRng) -> Option<u64> {
1796
+ Some(rng.random::<u64>() % 3)
1797
+ }
1798
+ fn plus(&self, index: usize) -> Option<u64> {
1799
+ self.map(|i| i + index as u64)
1800
+ }
1801
+ }
1802
+
1803
+ impl TestRand for Option<String> {
1804
+ fn null() -> Option<String> {
1805
+ None
1806
+ }
1807
+ fn rand(rng: &mut SmallRng) -> Option<String> {
1808
+ Some(format!("0x{:X}", rng.random::<u32>()).to_owned())
1809
+ }
1810
+ fn plus(&self, index: usize) -> Option<String> {
1811
+ self.as_ref().map(|s| format!("{}/{}", s, index).to_owned())
1812
+ }
1813
+ }
1814
+
1815
+ fn make_rng() -> SmallRng {
1816
+ let seed = rand::random::<u64>();
1817
+ //let seed = 16821371807298729682;
1818
+ //let seed = 14189760879853346850;
1819
+ log!("SEED: {}", seed);
1820
+ SmallRng::seed_from_u64(seed)
1821
+ }
1822
+
1823
+ /// Generate a random insert-only splice (del=0).
1824
+ fn generate_splice<T: TestRand>(len: usize, rng: &mut SmallRng) -> (usize, Vec<T>) {
1825
+ let index = T::index(len, rng);
1826
+ let patch = match rng.random::<u32>() % 4 {
1827
+ 0 => vec![T::null(), T::null(), T::null()],
1828
+ 1 => {
1829
+ let n = T::rand(rng);
1830
+ vec![n.clone(), n.clone(), n]
1831
+ }
1832
+ 2 => {
1833
+ let n = T::rand(rng);
1834
+ let step = (rng.random::<u32>() as usize) % 4;
1835
+ vec![n.clone(), n.plus(step), n.plus(step * 2)]
1836
+ }
1837
+ _ => T::rand_vec(rng),
1838
+ };
1839
+ (index, patch)
1840
+ }
1841
+
1842
+ /// Generate a random splice that may insert, delete, replace, or do a mix.
1843
+ /// Returns (index, del, values).
1844
+ fn generate_splice_del<T: TestRand>(len: usize, rng: &mut SmallRng) -> (usize, usize, Vec<T>) {
1845
+ if len == 0 {
1846
+ // Can only insert when empty.
1847
+ let (index, values) = generate_splice(len, rng);
1848
+ return (index, 0, values);
1849
+ }
1850
+ match rng.random::<u32>() % 5 {
1851
+ // Insert only (del=0).
1852
+ 0 => {
1853
+ let (index, values) = generate_splice(len, rng);
1854
+ (index, 0, values)
1855
+ }
1856
+ // Delete only (no new values).
1857
+ 1 => {
1858
+ let max_del = min(len, 10);
1859
+ let del = (rng.random::<u32>() as usize % max_del) + 1;
1860
+ let index = rng.random::<u32>() as usize % (len - del + 1);
1861
+ (index, del, vec![])
1862
+ }
1863
+ // Replace same count.
1864
+ 2 => {
1865
+ let max_del = min(len, 10);
1866
+ let del = (rng.random::<u32>() as usize % max_del) + 1;
1867
+ let index = rng.random::<u32>() as usize % (len - del + 1);
1868
+ let values = (0..del).map(|_| T::maybe_rand(rng)).collect();
1869
+ (index, del, values)
1870
+ }
1871
+ // Replace with fewer (shrink).
1872
+ 3 => {
1873
+ let max_del = min(len, 10);
1874
+ let del = (rng.random::<u32>() as usize % max_del) + 1;
1875
+ let index = rng.random::<u32>() as usize % (len - del + 1);
1876
+ let ins = rng.random::<u32>() as usize % del;
1877
+ let values = (0..ins).map(|_| T::maybe_rand(rng)).collect();
1878
+ (index, del, values)
1879
+ }
1880
+ // Replace with more (grow).
1881
+ _ => {
1882
+ let max_del = min(len, 5);
1883
+ let del = (rng.random::<u32>() as usize % max_del) + 1;
1884
+ let index = rng.random::<u32>() as usize % (len - del + 1);
1885
+ let ins = del + (rng.random::<u32>() as usize % 10) + 1;
1886
+ let values = (0..ins).map(|_| T::maybe_rand(rng)).collect();
1887
+ (index, del, values)
1888
+ }
1889
+ }
1890
+ }
1891
+
1892
+ #[test]
1893
+ fn column_data_fuzz_test_int() {
1894
+ let mut data: Vec<Option<u64>> = vec![];
1895
+ let mut col = ColumnData::<RleCursor<64, u64>>::new();
1896
+ let mut rng = make_rng();
1897
+ for _ in 0..FUZZ_SIZE {
1898
+ let (index, values) = generate_splice(data.len(), &mut rng);
1899
+ test_splice(&mut data, &mut col, index, values);
1900
+ }
1901
+ let export = ColumnData::<RleCursor<64, u64>>::load(&col.save()).unwrap();
1902
+ assert_eq!(col.to_vec(), export.to_vec());
1903
+
1904
+ // Phase 2: mixed insert/delete/replace.
1905
+ for _ in 0..FUZZ_SIZE {
1906
+ let (index, del, values) = generate_splice_del(data.len(), &mut rng);
1907
+ test_splice_del(&mut data, &mut col, index, del, values);
1908
+ }
1909
+ let export = ColumnData::<RleCursor<64, u64>>::load(&col.save()).unwrap();
1910
+ assert_eq!(col.to_vec(), export.to_vec());
1911
+ }
1912
+
1913
+ #[test]
1914
+ fn column_data_fuzz_test_suspend_resume() {
1915
+ let mut rng = make_rng();
1916
+ test_suspend_resume::<UIntCursor, Option<u64>>(&mut rng);
1917
+ test_suspend_resume::<IntCursor, Option<i64>>(&mut rng);
1918
+ test_suspend_resume::<DeltaCursor, Option<i64>>(&mut rng);
1919
+ test_suspend_resume::<StrCursor, Option<String>>(&mut rng);
1920
+ test_suspend_resume::<BooleanCursor, bool>(&mut rng);
1921
+ }
1922
+
1923
+ fn test_suspend_resume<'a, C: ColumnCursor, M: MaybePackable<'a, C::Item> + TestRand>(
1924
+ rng: &mut SmallRng,
1925
+ ) where
1926
+ C::Item: 'a,
1927
+ {
1928
+ const LEN: usize = 100;
1929
+ let col: ColumnData<C> = ((0..LEN).map(|_| M::maybe_rand(rng))).collect();
1930
+ log!("COL = {:?}", col.to_vec());
1931
+ for _ in 0..1000 {
1932
+ let index = M::index(LEN, rng);
1933
+ let mut iter1 = col.iter();
1934
+ iter1.nth(index);
1935
+ let cursor = iter1.suspend();
1936
+ let iter2 = cursor.try_resume(&col).unwrap();
1937
+ let v1: Vec<_> = iter1.collect();
1938
+ let v2: Vec<_> = iter2.collect();
1939
+ assert_eq!(v1, v2);
1940
+ }
1941
+ }
1942
+
1943
+ #[test]
1944
+ fn column_data_fuzz_test_suspend_resume_error() {
1945
+ let mut rng = make_rng();
1946
+
1947
+ const LEN: usize = 100;
1948
+ let mut col: ColumnData<UIntCursor> =
1949
+ ((0..LEN).map(|_| Option::<u64>::maybe_rand(&mut rng))).collect();
1950
+ for _ in 0..10 {
1951
+ let index1 = Option::<u64>::index(LEN, &mut rng);
1952
+ let index2 = Option::<u64>::index(LEN, &mut rng);
1953
+ let mut iter1 = col.iter();
1954
+ iter1.nth(index1);
1955
+ let cursor = iter1.suspend();
1956
+
1957
+ col.splice(index2, 0, vec![Option::<u64>::maybe_rand(&mut rng)]);
1958
+
1959
+ assert!(cursor.try_resume(&col).is_err());
1960
+ }
1961
+ }
1962
+
1963
+ #[test]
1964
+ fn column_data_fuzz_test_advance_by_int() {
1965
+ let mut rng = make_rng();
1966
+ for _ in 0..FUZZ_SIZE {
1967
+ let mut col = ColumnData::<UIntCursor>::new();
1968
+ let values = Option::<u64>::rand_vec(&mut rng);
1969
+ col.splice(0, 0, values.clone());
1970
+ test_advance_by(&mut rng, &values, &mut col);
1971
+ }
1972
+ }
1973
+
1974
+ #[test]
1975
+ fn column_data_str_fuzz_test() {
1976
+ let mut data: Vec<Option<String>> = vec![];
1977
+ let mut col = ColumnData::<RleCursor<64, str>>::new();
1978
+ let mut rng = make_rng();
1979
+ for _ in 0..FUZZ_SIZE {
1980
+ let (index, values) = generate_splice(data.len(), &mut rng);
1981
+ test_splice(&mut data, &mut col, index, values);
1982
+ }
1983
+ let copy: ColumnData<StrCursor> = ColumnData::load(&col.save()).unwrap();
1984
+ assert_eq!(col.to_vec(), copy.to_vec());
1985
+
1986
+ // Phase 2: mixed insert/delete/replace.
1987
+ for _ in 0..FUZZ_SIZE {
1988
+ let (index, del, values) = generate_splice_del(data.len(), &mut rng);
1989
+ test_splice_del(&mut data, &mut col, index, del, values);
1990
+ }
1991
+ let copy: ColumnData<StrCursor> = ColumnData::load(&col.save()).unwrap();
1992
+ assert_eq!(col.to_vec(), copy.to_vec());
1993
+ }
1994
+
1995
+ #[test]
1996
+ fn column_data_fuzz_test_advance_by_str() {
1997
+ let mut rng = make_rng();
1998
+ for _ in 0..FUZZ_SIZE {
1999
+ let mut col = ColumnData::<StrCursor>::new();
2000
+ let values = Option::<String>::rand_vec(&mut rng);
2001
+ col.splice(0, 0, values.clone());
2002
+ test_advance_by(&mut rng, &values, &mut col);
2003
+ }
2004
+ }
2005
+
2006
+ #[test]
2007
+ fn column_data_fuzz_test_delta() {
2008
+ let mut data: Vec<Option<i64>> = vec![];
2009
+ let mut col = ColumnData::<DeltaCursorInternal<8>>::new();
2010
+ let mut rng = make_rng();
2011
+ for _ in 0..FUZZ_SIZE {
2012
+ let (index, values) = generate_splice(data.len(), &mut rng);
2013
+ test_splice(&mut data, &mut col, index, values);
2014
+ }
2015
+ let copy: ColumnData<DeltaCursor> = ColumnData::load(&col.save()).unwrap();
2016
+ assert_eq!(col.to_vec(), copy.to_vec());
2017
+
2018
+ // Phase 2: mixed insert/delete/replace.
2019
+ for _ in 0..FUZZ_SIZE {
2020
+ let (index, del, values) = generate_splice_del(data.len(), &mut rng);
2021
+ test_splice_del(&mut data, &mut col, index, del, values);
2022
+ }
2023
+ let copy: ColumnData<DeltaCursor> = ColumnData::load(&col.save()).unwrap();
2024
+ assert_eq!(col.to_vec(), copy.to_vec());
2025
+ }
2026
+
2027
+ #[test]
2028
+ fn column_data_fuzz_test_advance_by_delta() {
2029
+ let mut rng = make_rng();
2030
+ for _ in 0..100 {
2031
+ let mut col = ColumnData::<DeltaCursor>::new();
2032
+ let values = Option::<i64>::rand_vec(&mut rng);
2033
+ col.splice(0, 0, values.clone());
2034
+ test_advance_by(&mut rng, &values, &mut col);
2035
+ }
2036
+ }
2037
+
2038
+ #[test]
2039
+ fn column_data_test_boolean() {
2040
+ let data: Vec<bool> = vec![true, true, true];
2041
+ let mut col = ColumnData::<BooleanCursor>::new();
2042
+ col.splice(0, 0, data.clone());
2043
+ assert_eq!(col.test_dump(), vec![vec![ColExport::Run(3, true)]]);
2044
+ col.splice(0, 0, vec![false, false, false]);
2045
+ assert_eq!(
2046
+ col.test_dump(),
2047
+ vec![vec![ColExport::Run(3, false), ColExport::Run(3, true)]]
2048
+ );
2049
+ col.splice(6, 0, vec![false, false, false]);
2050
+ assert_eq!(
2051
+ col.test_dump(),
2052
+ vec![vec![
2053
+ ColExport::Run(3, false),
2054
+ ColExport::Run(3, true),
2055
+ ColExport::Run(3, false),
2056
+ ]]
2057
+ );
2058
+ col.splice(9, 0, vec![true, true, true]);
2059
+ assert_eq!(
2060
+ col.test_dump(),
2061
+ vec![vec![
2062
+ ColExport::Run(3, false),
2063
+ ColExport::Run(3, true),
2064
+ ColExport::Run(3, false),
2065
+ ColExport::Run(3, true),
2066
+ ]]
2067
+ );
2068
+ col.splice(0, 0, vec![true, true, true]);
2069
+ assert_eq!(
2070
+ col.test_dump(),
2071
+ vec![vec![
2072
+ ColExport::Run(3, true),
2073
+ ColExport::Run(3, false),
2074
+ ColExport::Run(3, true),
2075
+ ColExport::Run(3, false),
2076
+ ColExport::Run(3, true),
2077
+ ]]
2078
+ );
2079
+ col.splice(1, 0, vec![false, false, false]);
2080
+ assert_eq!(
2081
+ col.test_dump(),
2082
+ vec![vec![
2083
+ ColExport::Run(1, true),
2084
+ ColExport::Run(3, false),
2085
+ ColExport::Run(2, true),
2086
+ ColExport::Run(3, false),
2087
+ ColExport::Run(3, true),
2088
+ ColExport::Run(3, false),
2089
+ ColExport::Run(3, true),
2090
+ ]]
2091
+ );
2092
+ }
2093
+
2094
+ #[test]
2095
+ fn column_data_fuzz_test_boolean() {
2096
+ let mut data: Vec<bool> = vec![];
2097
+ let mut col = ColumnData::<BooleanCursor>::new();
2098
+ let mut rng = make_rng();
2099
+ for _ in 0..FUZZ_SIZE {
2100
+ let (index, values) = generate_splice(data.len(), &mut rng);
2101
+ test_splice(&mut data, &mut col, index, values);
2102
+ }
2103
+ let export = ColumnData::<BooleanCursor>::load(&col.save()).unwrap();
2104
+ assert_eq!(col.to_vec(), export.to_vec());
2105
+
2106
+ // Phase 2: mixed insert/delete/replace.
2107
+ for _ in 0..FUZZ_SIZE {
2108
+ let (index, del, values) = generate_splice_del(data.len(), &mut rng);
2109
+ test_splice_del(&mut data, &mut col, index, del, values);
2110
+ }
2111
+ let export = ColumnData::<BooleanCursor>::load(&col.save()).unwrap();
2112
+ assert_eq!(col.to_vec(), export.to_vec());
2113
+ }
2114
+
2115
+ #[test]
2116
+ fn column_data_fuzz_test_advance_by_boolean() {
2117
+ let mut rng = make_rng();
2118
+ for _ in 0..FUZZ_SIZE {
2119
+ let mut col = ColumnData::<BooleanCursor>::new();
2120
+ let values = bool::rand_vec(&mut rng);
2121
+ col.splice(0, 0, values.clone());
2122
+ test_advance_by(&mut rng, &values, &mut col);
2123
+ }
2124
+ }
2125
+
2126
+ #[test]
2127
+ fn column_data_scope_to_value() {
2128
+ let data = vec![
2129
+ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 8, 9, 9,
2130
+ ];
2131
+ let mut col = ColumnData::<RleCursor<4, u64>>::new();
2132
+ col.splice(0, 0, data);
2133
+ let range = col.scope_to_value(Some(4), ..);
2134
+ assert_eq!(range, 7..15);
2135
+
2136
+ let range = col.scope_to_value(Some(4), ..11);
2137
+ assert_eq!(range, 7..11);
2138
+ let range = col.scope_to_value(Some(4), ..8);
2139
+ assert_eq!(range, 7..8);
2140
+ let range = col.scope_to_value(Some(4), 0..1);
2141
+ assert_eq!(range, 1..1);
2142
+ let range = col.scope_to_value(Some(4), 8..9);
2143
+ assert_eq!(range, 8..9);
2144
+ let range = col.scope_to_value(Some(4), 9..);
2145
+ assert_eq!(range, 9..15);
2146
+ let range = col.scope_to_value(Some(4), 14..16);
2147
+ assert_eq!(range, 14..15);
2148
+
2149
+ let range = col.scope_to_value(Some(2), ..);
2150
+ assert_eq!(range, 0..3);
2151
+ let range = col.scope_to_value(Some(7), ..);
2152
+ assert_eq!(range, 22..22);
2153
+ let range = col.scope_to_value(Some(8), ..);
2154
+ assert_eq!(range, 22..23);
2155
+ let range = col.scope_to_value(Some(9), ..);
2156
+ assert_eq!(range, 23..25);
2157
+ }
2158
+
2159
+ #[test]
2160
+ fn splice_on_boundary() {
2161
+ let data = vec![1, 2, 3, 4, 5, 6];
2162
+ let mut col = ColumnData::<RleCursor<4, u64>>::new();
2163
+ col.splice(0, 0, data);
2164
+ assert_eq!(
2165
+ col.test_dump(),
2166
+ vec![
2167
+ vec![ColExport::litrun(vec![1, 2, 3])],
2168
+ vec![ColExport::litrun(vec![4, 5, 6])],
2169
+ ]
2170
+ );
2171
+ col.splice(3, 1, vec![99]);
2172
+ assert_eq!(
2173
+ col.to_vec(),
2174
+ vec![Some(1), Some(2), Some(3), Some(99), Some(5), Some(6)]
2175
+ );
2176
+ }
2177
+
2178
+ #[test]
2179
+ fn iter_range() {
2180
+ let seed = rand::random::<u64>();
2181
+ let mut rng = SmallRng::seed_from_u64(seed);
2182
+ let mut data = vec![];
2183
+ for _ in 0..FUZZ_SIZE {
2184
+ let val = rng.random::<u64>() % 4;
2185
+ if val == 0 {
2186
+ data.push(None);
2187
+ } else {
2188
+ data.push(Some(val));
2189
+ }
2190
+ }
2191
+ let mut col = ColumnData::<RleCursor<8, u64>>::new();
2192
+ col.splice(0, 0, data.clone());
2193
+
2194
+ for _ in 0..FUZZ_SIZE {
2195
+ let a = rng.random::<u32>() % FUZZ_SIZE;
2196
+ let b = rng.random::<u32>() % FUZZ_SIZE;
2197
+ let min = std::cmp::min(a, b) as usize;
2198
+ let max = std::cmp::max(a, b) as usize;
2199
+
2200
+ assert_eq!(col.iter_range(min..max).to_vec(), data[min..max].to_vec());
2201
+ }
2202
+ }
2203
+
2204
+ #[test]
2205
+ fn iter_range_with_acc() {
2206
+ let seed = rand::random::<u64>();
2207
+ let mut rng = SmallRng::seed_from_u64(seed);
2208
+ let mut data = vec![];
2209
+ const MAX: usize = FUZZ_SIZE as usize;
2210
+ for _ in 0..MAX {
2211
+ let val = rng.random::<u64>() % 4;
2212
+ if val == 0 {
2213
+ data.push(None);
2214
+ } else {
2215
+ data.push(Some(val));
2216
+ }
2217
+ }
2218
+ let mut col = ColumnData::<RleCursor<8, u64>>::new();
2219
+ col.splice(0, 0, data.clone());
2220
+
2221
+ let vals_w_acc = col.iter().with_acc().collect::<Vec<_>>();
2222
+
2223
+ for n in 0..(MAX - 3) {
2224
+ let m = n + 3;
2225
+ let sub = col.iter_range(n..m).with_acc().collect::<Vec<_>>();
2226
+ assert_eq!(&vals_w_acc[n..m], sub.as_slice());
2227
+ }
2228
+
2229
+ let mut last_acc = Acc::new();
2230
+ let mut last_item_agg = Default::default();
2231
+ for n in 0..(col.acc().as_usize()) {
2232
+ let result = col.iter().with_acc().shift_acc(n).unwrap();
2233
+ let item = result.item;
2234
+ let acc = result.acc;
2235
+ assert!(acc <= Acc::from(n));
2236
+ assert!(acc == last_acc || acc == last_acc + last_item_agg);
2237
+ last_acc = acc;
2238
+ last_item_agg = item.map(|v| <u64 as Packable>::agg(&v)).unwrap_or_default();
2239
+ }
2240
+ }
2241
+
2242
+ #[test]
2243
+ fn find_values_by_agg() {
2244
+ let seed = rand::random::<u64>();
2245
+ let mut rng = SmallRng::seed_from_u64(seed);
2246
+ let mut data_i64 = vec![];
2247
+ let mut data_u64 = vec![];
2248
+ const MAX: usize = FUZZ_SIZE as usize;
2249
+ for _ in 0..MAX {
2250
+ let val = rng.random::<u32>();
2251
+ if val == 0 {
2252
+ data_i64.push(None);
2253
+ data_u64.push(None);
2254
+ } else {
2255
+ data_i64.push(Some(val as i64));
2256
+ data_u64.push(Some(val as u64));
2257
+ }
2258
+ }
2259
+
2260
+ let mut rle_col = ColumnData::<RleCursor<16, u64>>::new();
2261
+ rle_col.splice(0, 0, data_u64.clone());
2262
+
2263
+ for (i, val) in data_u64.iter().enumerate() {
2264
+ if let Some(val) = val {
2265
+ assert!(rle_col.find_by_value(*val).any(|j| j == i));
2266
+ }
2267
+ }
2268
+
2269
+ let mut delta_col = ColumnData::<DeltaCursorInternal<16>>::new();
2270
+ delta_col.splice(0, 0, data_i64.clone());
2271
+
2272
+ for (i, val) in data_i64.iter().enumerate() {
2273
+ if let Some(val) = val {
2274
+ assert!(delta_col.find_by_value(*val).any(|j| j == i));
2275
+ }
2276
+ }
2277
+ }
2278
+
2279
+ #[test]
2280
+ fn fuzz_find_by_values() {
2281
+ const N: u32 = 10_000;
2282
+ const STEP: u32 = 3;
2283
+ let mut rng = make_rng();
2284
+ let col: ColumnData<UIntCursor> = (0..N)
2285
+ .flat_map(|i| [i as u64 * 2 + 1; STEP as usize].into_iter())
2286
+ .collect();
2287
+ for _ in 0..FUZZ_SIZE {
2288
+ let roll = rng.random::<u32>() % N;
2289
+ let target1 = (roll * 2) as u64;
2290
+ let target2 = (roll * 2 + 1) as u64;
2291
+
2292
+ let mut a = (rng.random::<u32>() % (N * STEP)) as usize;
2293
+ let mut b = (rng.random::<u32>() % (N * STEP)) as usize;
2294
+ if a > b {
2295
+ std::mem::swap(&mut a, &mut b);
2296
+ }
2297
+
2298
+ assert!(b >= a);
2299
+
2300
+ let start = (roll * 3) as usize;
2301
+ let a_start = min(b, max(start, a));
2302
+ let a_end1 = max(a_start, min(start, b));
2303
+ let a_end2 = max(a_start, min(start + 3, b));
2304
+
2305
+ let answer1 = a_start..a_end1;
2306
+ let answer2 = a_start..a_end2;
2307
+
2308
+ let result1 = col.scope_to_value(Some(target1), a..b);
2309
+ let result2 = col.scope_to_value(Some(target2), a..b);
2310
+
2311
+ assert_eq!(answer1, result1);
2312
+ assert_eq!(answer2, result2);
2313
+ }
2314
+ }
2315
+
2316
+ #[test]
2317
+ fn shift_next() {
2318
+ let col: ColumnData<UIntCursor> = [
2319
+ 0, 0, 0, 1, 1, 1, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
2320
+ ]
2321
+ .iter()
2322
+ .collect();
2323
+ let mut iter = col.iter_range(1..4);
2324
+ assert_eq!(iter.next(), Some(Some(Cow::Owned(0))));
2325
+ assert_eq!(iter.next(), Some(Some(Cow::Owned(0))));
2326
+ assert_eq!(iter.next(), Some(Some(Cow::Owned(1))));
2327
+ assert_eq!(iter.next(), None);
2328
+
2329
+ let next = iter.shift_next(5..7);
2330
+
2331
+ assert_eq!(next, Some(Some(Cow::Owned(1))));
2332
+ assert_eq!(iter.next(), Some(Some(Cow::Owned(6))));
2333
+ assert_eq!(iter.next(), None);
2334
+
2335
+ let next = iter.shift_next(8..10);
2336
+
2337
+ assert_eq!(next, Some(Some(Cow::Owned(6))));
2338
+ assert_eq!(iter.next(), Some(Some(Cow::Owned(7))));
2339
+ assert_eq!(iter.next(), None);
2340
+ }
2341
+
2342
+ #[test]
2343
+ fn fuzz_find_by_range() {
2344
+ const N: usize = 8;
2345
+ const STEP: u32 = 4;
2346
+ let mut rng = make_rng();
2347
+ for _ in 0..FUZZ_SIZE {
2348
+ let data = (0..N)
2349
+ .map(|_| rng.random::<u64>() % STEP as u64 + 1)
2350
+ .collect::<Vec<_>>();
2351
+ let col1: ColumnData<UIntCursor> = data.clone().into_iter().collect();
2352
+ let col2: ColumnData<DeltaCursor> =
2353
+ data.clone().into_iter().map(|i| i as i64).collect();
2354
+
2355
+ let a = (rng.random::<u32>() % STEP + 1) as usize;
2356
+ let b = (rng.random::<u32>() % STEP + 1) as usize;
2357
+ let range = a.min(b)..a.max(b);
2358
+
2359
+ let result1 = col1.find_by_range(range.clone()).collect::<Vec<_>>();
2360
+ let result2 = col2.find_by_range(range.clone()).collect::<Vec<_>>();
2361
+ let answer = data
2362
+ .iter()
2363
+ .enumerate()
2364
+ .filter_map(|(i, v)| {
2365
+ if range.contains(&(*v as usize)) {
2366
+ Some(i)
2367
+ } else {
2368
+ None
2369
+ }
2370
+ })
2371
+ .collect::<Vec<_>>();
2372
+
2373
+ assert_eq!(result1, answer);
2374
+ assert_eq!(result2, answer);
2375
+ }
2376
+ }
2377
+
2378
+ #[test]
2379
+ fn iter_scope_to_value() {
2380
+ let col: ColumnData<UIntCursor> = [
2381
+ 0, 0, 0, 1, 1, 1, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
2382
+ ]
2383
+ .iter()
2384
+ .collect();
2385
+ let mut iter = col.iter();
2386
+ assert_eq!(iter.seek_to_value(Some(0), ..), 0..3);
2387
+ assert_eq!(iter.seek_to_value(Some(6), ..), 6..9);
2388
+ assert_eq!(iter.seek_to_value(Some(8), ..), 12..15);
2389
+
2390
+ let mut iter = col.iter();
2391
+ assert_eq!(iter.seek_to_value(Some(0), ..), 0..3);
2392
+ assert_eq!(iter.seek_to_value(Some(1), ..), 3..6);
2393
+ assert_eq!(iter.seek_to_value(Some(6), ..), 6..9);
2394
+ }
2395
+
2396
+ #[test]
2397
+ fn simple_advance_by_acc() {
2398
+ type C = ColumnData<RleCursor<8, u64>>;
2399
+
2400
+ let column = C::from(vec![0, 1, 1, 0, 1, 1, 0]);
2401
+
2402
+ assert_eq!(column.iter().advance_acc_by(0), 1);
2403
+ assert_eq!(column.iter().advance_acc_by(1), 2);
2404
+ assert_eq!(column.iter().advance_acc_by(2), 4);
2405
+ assert_eq!(column.iter().advance_acc_by(3), 5);
2406
+ assert_eq!(column.iter().advance_acc_by(4), 7);
2407
+ assert_eq!(column.iter().advance_acc_by(100), 7);
2408
+
2409
+ assert_eq!(column.iter_range(2..7).advance_acc_by(0), 0);
2410
+ assert_eq!(column.iter_range(2..7).advance_acc_by(1), 2);
2411
+ assert_eq!(column.iter_range(2..7).advance_acc_by(2), 3);
2412
+ assert_eq!(column.iter_range(2..7).advance_acc_by(3), 5);
2413
+ assert_eq!(column.iter_range(2..7).advance_acc_by(100), 5);
2414
+
2415
+ let column = C::from(vec![0, 0, 1, 1, 0, 0, 1, 1, 0]);
2416
+
2417
+ let mut iter = column.iter_range(1..5);
2418
+ assert_eq!(iter.advance_acc_by(0), 1);
2419
+ iter.next();
2420
+ assert_eq!(iter.advance_acc_by(0), 0);
2421
+
2422
+ let mut iter = column.iter_range(0..5);
2423
+ assert_eq!(iter.advance_acc_by(1), 3);
2424
+ iter.next();
2425
+ assert_eq!(iter.advance_acc_by(0), 1);
2426
+ assert_eq!(iter.pos(), 5);
2427
+
2428
+ let column = C::from(vec![0, 3, 3, 0, 3, 3, 0]);
2429
+
2430
+ assert_eq!(column.iter().advance_acc_by(0), 1);
2431
+ assert_eq!(column.iter().advance_acc_by(1), 1);
2432
+ assert_eq!(column.iter().advance_acc_by(2), 1);
2433
+ assert_eq!(column.iter().advance_acc_by(3), 2);
2434
+ assert_eq!(column.iter().advance_acc_by(4), 2);
2435
+ assert_eq!(column.iter().advance_acc_by(5), 2);
2436
+ assert_eq!(column.iter().advance_acc_by(6), 4);
2437
+ }
2438
+
2439
+ #[test]
2440
+ fn fuzz_advance_by_acc() {
2441
+ const SIZE: usize = 10000;
2442
+ let mut rng = make_rng();
2443
+ let mut data = vec![];
2444
+ let mut acc = vec![];
2445
+ let mut agg = 0;
2446
+ for _ in 0..SIZE {
2447
+ let val = rng.random::<u64>() % 4;
2448
+ agg += val;
2449
+ data.push(val);
2450
+ acc.push(agg);
2451
+ }
2452
+ let column: ColumnData<RleCursor<8, u64>> = data.iter().cloned().collect();
2453
+ for _ in 0..10 {
2454
+ let mut iter = column.iter();
2455
+ loop {
2456
+ let advance = rng.random::<u64>() % 8 + 1;
2457
+ let pos1 = iter.pos();
2458
+ iter.advance_acc_by(advance);
2459
+ if let Some(val) = iter.next() {
2460
+ let pos2 = iter.pos();
2461
+ let _acc = iter.calculate_acc();
2462
+ assert!(pos2 > pos1);
2463
+ assert!(Acc::from(acc[pos2 - 1]) >= _acc);
2464
+ if pos2 > 1 {
2465
+ assert!(Acc::from(acc[pos2 - 2]) <= _acc);
2466
+ }
2467
+ assert_eq!(data[pos2 - 1], val.as_deref().copied().unwrap_or_default());
2468
+ } else {
2469
+ break;
2470
+ }
2471
+ }
2472
+ }
2473
+ }
2474
+
2475
+ #[test]
2476
+ fn readme_test() {
2477
+ // columns are generally modified with a splice command
2478
+ let mut column1: ColumnData<IntCursor> = ColumnData::new();
2479
+ column1.splice(0, 0, [1, 2, 3, 4, 5, 6, 7]);
2480
+
2481
+ // the columns can be created with collect()
2482
+ // data written to columns is mediated by the MaybePackable trait.
2483
+ // this allows StrCursor to use &str, String, Option<&str> and Option<String>
2484
+ // or UIntCursor to use u64, or Option<u64> interchangably
2485
+ let column2: ColumnData<UIntCursor> = [1, 2, 3].into_iter().collect();
2486
+ // data read is always Option<Cow<'_, Cursor::Item>> or Option<Cursor::Item>
2487
+ assert_eq!(column2.to_vec(), vec![Some(1), Some(2), Some(3)]);
2488
+
2489
+ // save() writes the column data to a single Vec<u8> combinding the internal slabs
2490
+ // load() does the inverse and will throw an error if the data does not fit the
2491
+ // encoding standard
2492
+ let column3: ColumnData<IntCursor> = ColumnData::load(&column1.save()).unwrap();
2493
+ // TODO add a load_with() example
2494
+
2495
+ // the vec representation of the data is the same
2496
+ assert_eq!(column1.to_vec(), column3.to_vec());
2497
+ // and the saved data is the same - but the internal representation may differ
2498
+ assert_eq!(column1.save(), column3.save());
2499
+
2500
+ // Cursors can directly encode data into a buffer and skip the slab intermediary
2501
+ // By default encode writes nothing if all the data passed in is false or None
2502
+ // but you can force it to write the nulls if the third parameter is true
2503
+ let mut buffer = vec![];
2504
+ let _word_range = StrCursor::encode(&mut buffer, ["dog", "book", "bell"]);
2505
+ assert_eq!(_word_range, 0..15);
2506
+ let _bool_range = BooleanCursor::encode_unless_empty(&mut buffer, [false, false, false]);
2507
+ assert_eq!(_bool_range, 15..15);
2508
+
2509
+ // if you need to build the data incrementally you can get access to the underlying encoder
2510
+ let mut encoder: Encoder<'_, StrCursor> = Encoder::default();
2511
+ for word in ["dog", "book", "bell"] {
2512
+ encoder.append(word);
2513
+ }
2514
+ let _word_range2 = encoder.save_to(&mut buffer);
2515
+
2516
+ // accessing elements within a column
2517
+
2518
+ assert_eq!(column1.get(1), Some(Some(Cow::Owned(2))));
2519
+ assert_eq!(
2520
+ column1.iter().take(3).collect::<Vec<_>>(),
2521
+ vec![
2522
+ Some(Cow::Owned(1)),
2523
+ Some(Cow::Owned(2)),
2524
+ Some(Cow::Owned(3)),
2525
+ ]
2526
+ );
2527
+ assert_eq!(
2528
+ column1.iter_range(3..5).collect::<Vec<_>>(),
2529
+ vec![Some(Cow::Owned(4)), Some(Cow::Owned(5)),]
2530
+ );
2531
+
2532
+ // TODO
2533
+ // get_acc()
2534
+ // get_with_acc()
2535
+ // seek_to_value()
2536
+ // advance_acc_by()
2537
+ // iter().with_acc()
2538
+ // suspend()
2539
+ }
2540
+ }